spring IOC 容器有两种,分别是 BeanFactory 容器和 ApplicationContext 容器。java
BeanFactory以下:spring
/*第一步,利用ClassPathResource()API加载路径CLASSPATH下的可用的Bean的xml配置文件 而后利用框架提供的 XmlBeanFactory() API生成工厂Bean,XmlBeanFactory()负责建立和初始化全部对象 而后用getBean方法获得所须要Bean并转化类型为真正的对象 */ XmlBeanFactory factory = new XmlBeanFactory(new ClassPathResource("Beans.xml")); HelloWorld obj = (HelloWorld) factory.getBean("helloWorld"); obj.getMessage();
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> <bean id="helloWorld" class="com.tutorialspoint.HelloWorld"> <property name="message" value="Hello World!"/> </bean> </beans>
ApplicationContext接口的实现:数据库
FileSystemXmlApplicationContext:从xml文件中加载已经被定义的bean,须要提供的参数为完整的XML文件路径express
ClassPathXmlApplicationCOntext:从xml文件中加载已经被定义的bean,但从CLASSPATH加载xml文件框架
package com.tutorialspoint; import org.springframework.context.ApplicationContext; import org.springframework.context.support.FileSystemXmlApplicationContext; public class MainApp { public static void main(String[] args) { //第一步 ApplicationContext context = new FileSystemXmlApplicationContext("C:/Users/ZARA/workspace/HelloSpring/src/Beans.xml"); //第二步 HelloWorld obj = (HelloWorld) context.getBean("helloWorld"); obj.getMessage(); } }
singleton:是bean的默认做用域;看成用域为singleton时,IOC容器只会存在一个共享的bean实例,屡次getBean时,返回的都是同一个Bean函数
<bean id="..." class="..." scope="singleton"> <!-- collaborators and configuration for this bean go here --> </bean>
prototype:表示一个bean的定义对应多个对象实例,每次getbean时都会返回一个新的bean实例;ui
<!-- id是bean的id,用于识别bean; class是bean所对应的类--> <bean id="textEditor" class="com.tutorialspoint.TextEditor"> <!--constructor-arg表示基于构造函数注入 ,ref表示注入的值是引用而非通常的数值--> <constructor-arg ref="spellChecker"/> </bean>
<bean id="foo" class="x.y.Foo"> <!-- 当构造函数存在多个参数时,按顺序定义便可按顺序传参--> <constructor-arg ref="bar"/> <constructor-arg ref="baz"/> </bean>
<bean id="textEditor" class="com.tutorialspoint.TextEditor"> <property name="spellChecker" ref="spellChecker"/> <!-- property表示基于设值函数注入,设值函数的名字必定要是 setSpellChecker()--> <property name="name" value="John Doe"/> <!-- name是属性的名字,value是属性的值--> </bean>
@required:用在set方法上,一旦用了这个注解,bean在初始化时就必须对这个值进行依赖注入;不然报错this
public class Zoo { private Dog dog ; public Dog getDog() { return dog; } @required //若是xml文件中没有对Dog属性进行注入,则会报错 public void setDog(Dog dog) { this.dog = dog; } }
@Autowired:能够不写依赖注入的配置,让容器本身寻找依赖并注入spa
public class Zoo { @Autowired private Dog dog ; public Dog getDog() { return dog; } public void setDog(Dog dog) { this.dog = dog; } }
在xml配置中添加下列语句,告诉spring要用注解的方式进行配置prototype
<context:annotation-config/>
import org.springframework.beans.factory.annotation.Autowired; public class Product {
private int id; //在属性前加上Autowired注解,实现注入; //这时Category属性就能够不要set函数了,在xml中的Product的bean也不能再配置Category属性了;但product的bean仍是须要的; //若是在xml中的product的bean中也配置了Category属性,则会按照xml优先的原则寻找属性对应的set函数或者构造函数,若是找不到则报错 @Autowired private Category category; public int getId() { return id; } public void setId(int id) { this.id = id; } //也能够在设值函数前加上Autowired注解,实现注入; //这种状况下同上,能够不用在xml文件中配置category属性,但product的bean仍是须要声明的 @Autowired public void setCategory(Category category) { this.category = category; } }
此时的xml:仅仅去掉了对属性是引用的Category属性的配置,其它的并无省略;(省略的是下方注释的那一行)
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> <context:annotation-config/> <bean name="c" class="com.how2java.pojo.Category"> <property name="name" value="category 1" /> </bean> <bean name="p" class="com.how2java.pojo.Product"> <property name="name" value="product1" /> <!-- <property name="category" ref="c" /> --> </bean> </beans>
先将xml中的什么都去掉,只新增一行<context:component-scan base-package="com.how2java.pojo"/>,这时告诉spring,bean在哪一个java包下
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> <context:component-scan base-package="com.how2java.pojo"/> </beans>
而后在java文件中作以下改动
package com.how2java.pojo; import javax.annotation.Resource; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; //@component代表Product类是bean,这至关于在xml中声明一个bean @Component("p") public class Product { //属性的初始化如今放在属性声明中进行 private int id = 10; private String name="product 1"; //同上,对Category属性进行自动注入 @Autowired private Category category; }
链接点(joinpoint):一个类或者一段程序拥有的具备边界性质的特定点,叫作链接点。
切点(pointcut):是某些特定的链接点;若是用数据库的概念来比喻链接点和切点的关系,链接点至关于客观存在的记录数据,而切点至关于查询条件;
加强(advice):加强是织入到链接点上的一段程序代码(就是一个方法);
目标对象:要被织入代码的类
切面:切面 = 加强 + 切点
服务类:
import org.aspectj.lang.ProceedingJoinPoint; //加强所在的类 public class LoggerAspect { //加强,即要织入的方法 public void log(JoinPoint joinPoint) throws Throwable { System.out.println("start log"); return object; } }
xml配置:
<!-- 声明业务类对象--> <bean name="s" class="com.how2java.service.ProductService"> </bean> <!-- 声明服务类对象--> <bean id="loggerAspect" class="com.how2java.aspect.LoggerAspect"/> <aop:config> <!-- id是切入点的名字,定义了一个切点 --> <!-- expression 表示知足这个expression 的方法在被调用以后,就会执行切面操做,至关于触发了切面;--> <!--第一个*表示返回值返回任意类型,第二个*表示任意方法,(..)表示方法的参数是任意数量和类型 --> <aop:pointcut id="loggerCutpoint" expression="execution(* com.how2java.service.ProductService.*(..)) "/> <!-- 定义了一个切面,切面 = 加强 + 切点--> <!-- id是切面的名字, ref是加强所在的类--> <aop:aspect id="logAspect" ref="loggerAspect"> <!-- pointcut-ref 表示本切面和哪一个切点相关联; method表明加强--> <!-- aop:after 表示要在什么时候调用加强;before在方法调用前,after在方法调用后,after-returning在方法执行成功后--> <!-- after-throwing在方法抛出异常后调用;around在方法调用前和调用后执行--> <aop:after pointcut-ref="loggerCutpoint" method="log"/> </aop:aspect> </aop:config>
业务类以下:
package com.how2java.service; import org.springframework.stereotype.Component; //用component来声明这是一个bean @Component("s") public class ProductService { public void doSomeService(){ System.out.println("doSomeService"); } }
服务类以下:
package com.how2java.aspect; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.springframework.stereotype.Component; //Aspect注解表示这是一个切面,component注解声明了一个bean @Aspect @Component public class LoggerAspect { //around注解表示对目标类中的某些方法进行切面操做 @Around(value="execution(*com.how2java.service.ProductService.*(..))") public Object log(ProceedingJoinPoint joinPoint) throws Throwable { System.out.println("start log:" + joinPoint.getSignature().getName()); Object object = joinPoint.proceed(); System.out.println("end log:" + joinPoint.getSignature().getName()); return object; } }
xml配置以下:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> <!-- 下面两行是告诉spring应该扫描哪些包--> <context:component-scan base-package="com.how2java.aspect"/> <context:component-scan base-package="com.how2java.service"/> <aop:aspectj-autoproxy/> </beans>