想要查看前面的笔记请翻阅我的CSDN博客,作者码字不易,喜欢的话点赞,加个关注吧,后期还有很多干货等着你!
1.相关注解
- @Autowired(spring):优先按照类型去找到对应的组件,如果找到多个相同类型组件,那么就使用属性名称作为id去查找,默认如果没有找到就就报错,需要添加required=false来去除必须找到;
- @Resource(java):JSR250规范,默认使用组件名称进行装配,效果与@Autowired相同,但不支持required=false、@Primary
- @Inject(java):JSR330规范,需要导入javax,效果与@Autowired相同,但不支持required=false
- @Qualifier:使用此注解可以明确指定需要装配的组件id
- @Primary:用此注解可以声明如果容器中有多个同类型的组件,指定首选装配的组件
2.其他位置使用@Autowired
- 参数:添加在参数上,当容器创建当前对象,注入完成赋值
- 方法:标注在方法上时,当容器创建当前对象,就会调用方法,完成赋值,@Bean标注的方法,创建对象时,那么@Autowired可以省略。方法参数从容器中获取
- 构造器:标注在构造器上时,当容器创建当前对象,完成赋值,如果只有一个有参数构造器,那么@Autowired可以省略。
3.Aware注入Spring底层组件&原理
1.有时候有时候我们的自定义组件想要使用Spring底层的一些组件,只需要我们的自定义组件,去实现xxxAware即可,在创建对象的时候,会调用规定的方法注入相关的方法,比如(ApplicationContextAware(ioc容器)、BeanFactoryAware(Bean创建工厂)、BeanNameAware(获取当前Bean的名字)、EmbeddedValueResolverAware(解析string的值,容器中的${},#{}就是使用这个组件去解析的))。
底层原理(个人理解):我们去看Aware这个接口的注释,Spring官方写的也比较明白,他就是使用了回调这个思想,当你的组件被创建成对象放入容器时,当到后置处理器去处理时,spring会获取你当前类实现的接口,当发现你实现了xxxAware接口时,就会将容器中原本创建好的底层组件,使用回调的方式,经过一系列if判断,调用你实现的方法,进行属性赋值完成注入你想要的底层组件。
那我们就看看spring是否是这样做的:我们拿ApplicationContextAware举例,它是使用ApplicationContextAwareProcessor进行处理的(在哪里调ApplicationContextAwareProcessor请跳转到第一章组件注册观看),ApplicationContextAwareProcessor又实现了BeanPostProcessor(后置处理器),在实现后置处理器的postProsessBeforeInitialization时,去判断是否有实现一些接口(使用bean instanceof xxxAware(instanceof判断一个引用类型变量所指向的对象是否是一个类(或接口、抽象类、父类)的实例,即它左边的对象是否是它右边的类的实例))如果实现了,先进行安全检查是否可以访问到对象的属性,如果检查通过,调用invokeAwareInterfaces方法,invokeAwareInterfaces方法里面是先判断是否是bean instanceof Aware,如果不是,直接结束,如果是,调用对象对应的SetxxxxxAware方法进行赋值。
@Profile环境注册
@Profile:使用此注解,只有这个环境的时候,Bean才会被注入,默认是default环境,没有标注环境标识的Bean,在任何环境下都是加载的。