简介及源码
@Autowired注解的三种方式如下,第一种是直接在属性名上加注解,这样就可以不用在写set方法进行注入,这种方式与set方式作用一样;第二种是在set方法上加注解;第三种是在构造器上加注解
我们从@Autowired这个注解点进去看一下源码:
我们可以发现这个注解可以标注的位置有:构造器,参数,方法,属性;都是从容器中来获取参数组件的值。
@Target({ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Autowired {
/**
* Declares whether the annotated dependency is required.
* <p>Defaults to {@code true}.
*/
boolean required() default true;
}
标注在方法上
@Autowired注解标注在方法上:类似于xml配置中的set方法注入
用的最多的方式就是在@Bean注解标注的方法上标注,但是可省略。@Autowired注解作用在方法上
(1)该方法如果有参数,会使用autowired的方式在容器中查找是否有该参数
(2)会执行该方法
@Autowired作用在普通方法上,会在注入的时候调用一次该方法,如果方法中有实体参数,会对方法里面的参数进行装配,并调用一次该方法。这个可以用来在自动注入的时候做一些初始化操作
@Component
public class Boss {
private Car car;
public Car getCar() {
return car;
}
@Autowired //标注在方法上,Spring容器在创建当前对象的时候,就会调用当前方法完成赋值;
//方法使用的参数,自定义类型的值从IOC容器里面进行获取
public void setCar(Car car) {
this.car = car;
}
@Override
public String toString() {
return "Boss{" +
"car=" + car +
'}';
}
}
标注在构造器上
@Autowired注解标注在构造器上,默认加载IOC容器中的组件,容器启动的时候会调用无参构造器创建对象,再进行初始化赋值操作,构造器要用的组件,也都是从容器中来获取:
注意:如果组件只有一个有参的构造器,这个有参的构造器的 @Autowired注解可以省略,参数位置的组件还是可以自动从容器中获取
//默认加在IOC容器中的组件,容器启动的时候会调用无参构造器创建对象,再进行初始化赋值操作
@Component
public class Boss {
private Car car;
//构造器要用的组件,也都是从容器中来获取
@Autowired
public Boss(Car car) {
this.car = car;
System.out.println("Boss的有参构造器"+car);
}
public Car getCar() {
return car;
}
@Autowired //标注在方法上,Spring容器在创建当前对象的时候,就会调用当前方法完成赋值;
//方法使用的参数,自定义类型的值从IOC容器里面进行获取
public void setCar(Car car) {
this.car = car;
}
@Override
public String toString() {
return "Boss{" +
"car=" + car +
'}';
}
}
标注在方法上和构造器上,感觉都是会在调用方法时,会自动加载装配方法的参数,完成初始化操作。其中方法可以是结合@Bean标注的方法(此时可省略),也可以是普通方法,此时会创建bean后会主动调用该方法完成舒适化操作
标注在参数上
@Autowired注解标注在参数上:效果是一样的
//默认加在IOC容器中的组件,容器启动的时候会调用无参构造器创建对象,再进行初始化赋值操作
@Component
public class Boss {
private Car car;
//构造器要用的组件,也都是从容器中来获取
//我们也可以标注在参数上效果是一样的
public Boss(@Autowired Car car) {
this.car = car;
System.out.println("Boss的有参构造器"+car);
}
public Car getCar() {
return car;
}
@Autowired //标注在方法上,Spring容器在创建当前对象的时候,就会调用当前方法完成赋值;
//方法使用的参数,自定义类型的值从IOC容器里面进行获取
public void setCar(Car car) {
this.car = car;
}
@Override
public String toString() {
return "Boss{" +
"car=" + car +
'}';
}
}
直接标注在属性上
本人最常用。在创建对象时会自动注入装配
总结
/**
* 自动装配;
* Spring利用依赖注入(DI),完成对IOC容器中中各个组件的依赖关系赋值;
*
* 1)、@Autowired:自动注入:
* 1)、默认优先按照类型去容器中找对应的组件:applicationContext.getBean(BookDao.class);找到就赋值
* 2)、如果找到多个相同类型的组件,再将属性的名称作为组件的id去容器中查找
* applicationContext.getBean("bookDao")
* 3)、@Qualifier("bookDao"):使用@Qualifier指定需要装配的组件的id,而不是使用属性名
* 4)、自动装配默认一定要将属性赋值好,没有就会报错;
* 可以使用@Autowired(required=false);
* 5)、@Primary:让Spring进行自动装配的时候,默认使用首选的bean;
* 也可以继续使用@Qualifier指定需要装配的bean的名字
* BookService{
* @Autowired
* BookDao bookDao;
* }
*
* 2)、Spring还支持使用@Resource(JSR250)和@Inject(JSR330)[java规范的注解]
* @Resource:
* 可以和@Autowired一样实现自动装配功能;默认是按照组件名称进行装配的;
* 没有能支持@Primary功能没有支持@Autowired(reqiured=false);
* @Inject:
* 需要导入javax.inject的包,和Autowired的功能一样。没有required=false的功能;
* @Autowired:Spring定义的; @Resource、@Inject都是java规范
*
* AutowiredAnnotationBeanPostProcessor:解析完成自动装配功能; 属于是底层原理为后置处理器
*
* 3)、 @Autowired:构造器,参数,方法,属性;都是从容器中获取参数组件的值
* 1)、[标注在方法位置]:@Bean+方法参数;参数从容器中获取;默认不写@Autowired效果是一样的;都能自动装配
* 2)、[标在构造器上]:如果组件只有一个有参构造器,这个有参构造器的@Autowired可以省略,参数位置的组件还是可以自动从容器中获取
* 3)、放在参数位置:
* 4)、放在属性位置
*
* 4)、自定义组件想要使用Spring容器底层的一些组件(ApplicationContext,BeanFactory,xxx);
* 自定义组件实现xxxAware;在创建对象的时候,会调用接口规定的方法注入相关组件;Aware;
* 把Spring底层一些组件注入到自定义的Bean中;
* xxxAware:功能使用xxxProcessor;
* ApplicationContextAware==》ApplicationContextAwareProcessor;
*
* /
版权声明:本文为sinat_41847122原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。