一、通过@Autowired进行自动注入
Spring通过@Autowired注解实现Bean的依赖注入,来看一个例子:
1.对类属性进行注入
<bean id="car1" class="spring.ioc.demo1.Car" scope="singleton" p:brand="spring注入-红旗001" p:color="spring注入-紫色" p:maxSpeed="520" /> <!-- 通过注解来实例化 --> <bean id="useAutoWired" class="spring.ioc.autowired.UseAutoWired" />
package spring.ioc.autowired; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import spring.ioc.demo1.Car; public class UseAutoWired { @Autowired @Qualifier("car1") private Car car; public String toString(){ return car.toString(); } }
public static void main(String[] args) { ApplicationContext ctx = new ClassPathXmlApplicationContext("classpath:applicationContext.xml"); UseAutoWired useAutoWired = ctx.getBean("useAutoWired",UseAutoWired.class); System.out.println(useAutoWired); }
输出:the car is:spring注入-红旗001, color is:spring注入-紫色, maxspeed is:520
注意:@Autowired默认按类型匹配的方式在容器查找匹配的Bean,当有且仅有一个匹配的Bean时,Spring才将其注入到@Autowired标注的变量中。
如果容器中没有一个和标注变量类型匹配的Bean,会抛出NoSuchBeanDefinitionException的异常,如果希望不抛出异常:
使用@Autowired(request=false)来标注。
在上例中,如果容器中有一个以上匹配的carBean的时候,我们要使用@Qualifier指定注入Bean的名称。
如果不指定名称,会报错:expected single matching bean but found
2.对类方法进行注入
<!-- 通过注解对方法进行注入 --> <bean id="useAutoWiredMethod" class="spring.ioc.autowired.UseAutoWiredMethod" />
package spring.ioc.autowired; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import spring.ioc.demo1.Car; public class UseAutoWiredMethod { private Car car1; @Autowired @Qualifier("car1") public void getInfo(Car car1){ this.car1 = car1; } public String toString(){ return car1.toString(); } }
public static void main(String[] args) { ApplicationContext ctx = new ClassPathXmlApplicationContext("classpath:applicationContext.xml"); //用注解对方法进行注入 UseAutoWiredMethod useAutoWiredMethod = ctx.getBean("useAutoWiredMethod",UseAutoWiredMethod.class); System.out.println(useAutoWiredMethod); }
输出:the car is:spring注入-红旗001, color is:spring注入-紫色, maxspeed is:520
同时,Spring支持对方法参数标注@Qualifier以指定注入Bean的名称:
@Autowired //@Qualifier("car1") public void getInfo(@Qualifier("car1")Car car1){ this.car1 = car1; }
总结:
@Autowired默认按类型匹配注入Bean;
@Resource按名称匹配注入Bean;
@Inject和@Autowired一样按类型注入Bean的,只不过他没有required属性。
二、通过注解来看Bean的作用范围及生命过程方法
Spring为注解配置提供了一个@Scope的注解,可以通过它显示的指定Bean的作用范围;
package spring.ioc.autowired; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; @Component @Scope("prototype") //多态的Bean public class Student { }
package spring.ioc.autowired; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @Component public class Teacher { private Student student; public Teacher(){ System.out.println("执行构造函数..."); } public Student getStudent() { return student; } @Autowired public void setStudent(Student student) { this.student = student; } @PostConstruct //相当于在bean中配置init-method public void init1(){ System.out.println("执行init1方法"); } @PostConstruct public void init2(){ System.out.println("执行init1方法"); } @PreDestroy //相当于在bean中配置destroy-method public void destroy1(){ System.out.println("执行destroy1方法"); } @PreDestroy public void destroy2s(){ System.out.println("执行destroy2方法"); } }
public static void main(String[] args) { ApplicationContext ctx = new ClassPathXmlApplicationContext("classpath:applicationContext.xml"); //注解来观察bean的生命周期 ((ClassPathXmlApplicationContext)ctx).destroy(); }
输出:
执行构造函数...
执行init1方法
执行init1方法
执行destroy1方法
执行destroy2方法
Spring容器的时候会自动去实例化单例的Bean,调用destroy方法销毁看到bean的生命周期。
我们看到我们并没有在bean.xml里配置bean,因为我们使用了@Component注解,它相当于我们在bean.xml中已经定义好以下内容:
<!-- 通过注解观察bean生命周期 --> <bean id="student" class="spring.ioc.autowired.Student" /> <bean id="teacher" class="spring.ioc.autowired.Teacher" />