• Spring依赖注入之@autowire注解详解


    目录

    @autowire用法

    @autowire注解底层逻辑

    逻辑处理类AutowiredAnnotationBeanPostProcessor

    postProcessMergedBeanDefinition获取注入点

    postProcessProperties针对注入点字段或者方法获取bean

    字段注入

    set方法注入


    @autowire用法

    • 属性上:先根据属性类型去找Bean,如果找到多个再根据属性名确定一个
    1. @Component
    2. public class A {
    3. @Autowired
    4. private B b;
    5. }
    • 构造方法上:先根据方法参数类型去找Bean,如果找到多个再根据参数名确定一个
    1. @Component
    2. public class A {
    3. private B b;
    4. @Autowired
    5. public A(B b) {
    6. this.b = b;
    7. }
    8. }
    • set方法上:先根据方法参数类型去找Bean,如果找到多个再根据参数名确定一个
    1. @Component
    2. public class A {
    3. private B b;
    4. public B getB() {
    5. return b;
    6. }
    7. @Autowired
    8. public void setB(B b) {
    9. this.b = b;
    10. }
    11. }

    @autowire注解底层逻辑

    它主要逻辑处理类AutowiredAnnotationBeanPostProcessor

    逻辑处理类AutowiredAnnotationBeanPostProcessor

    这个类实现了SmartInstantiationAwareBeanPostProcessor,MergedBeanDefinitionPostProcessor,

    重写了MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition和

    SmartInstantiationAwareBeanPostProcessor.postProcessProperties方法

    1. public class AutowiredAnnotationBeanPostProcessor implements SmartInstantiationAwareBeanPostProcessor,
    2. MergedBeanDefinitionPostProcessor, PriorityOrdered, BeanFactoryAware {

    这两个拓展点均参与了bean生命周期,postProcessMergedBeanDefinition在实例化后执行,postProcessProperties在属性注入时执行

    postProcessMergedBeanDefinition获取注入点

    主要的作用获取所有方法和字段中@autowire的注入点放到缓存injectionMetadataCache中;
    遍历当前类的所有的属性字段Field
    查看字段上是否存在@Autowired、@Value、@Inject中的其中任意一个,存在则认为该字段是一个注入点
    如果字段是static的,则不进行注入,获取@Autowired中的required属性的值,将字段信息构造成一个AutowiredFieldElement对象,作为一个注入点对象添加到currElements集合中。
    遍历当前类的所有方法Method,判断当前Method是否是桥接方法,如果是找到原方法,查看方法上是否存在@Autowired、@Value、@Inject中的其中任意一个,存在则认为该方法,是一个注入点
    如果方法是static的,则不进行注入,获取@Autowired中的required属性的值,将方法信息构造成一个AutowiredMethodElement对象,作为一个注入点对象添加到currElements集合中。
    遍历完当前类的字段和方法后,将遍历父类的,直到没有父类。最后将currElements集合封装成一个InjectionMetadata对象,作为当前Bean对于的注入点集合对象,并缓存。

    postProcessProperties针对注入点字段或者方法获取bean

    字段注入


    1遍历所有的AutowiredFieldElement对象
    2.将对应的字段封装为DependencyDescriptor对象

    3.调用BeanFactory的resolveDependency()方法,传入DependencyDescriptor对象,进行依赖查找,找到当前字段所匹配的Bean对象。
    4.将DependencyDescriptor对象和所找到的结果对象beanName封装成一个,ShortcutDependencyDescriptor对象作为缓存,比如如果当前Bean是原型Bean,那么下次再来创建该Bean时,就可以直接拿缓存的结果对象beanName去BeanFactory中去那bean对象了,不用再次进行查找了
    5.利用反射将结果对象赋值给字段。

    set方法注入


    1遍历所有的AutowiredMethodElement对象
    2.遍历将对应的方法的参数,将每个参数封装成MethodParameter对象
    3.将MethodParameter对象封装为DependencyDescriptor对象
    4.调用BeanFactory的resolveDependency()方法,传入DependencyDescriptor对象,
    进行依赖查找,找到当前方法参数所匹配的Bean对象。
    5.将DependencyDescriptor对象和所找到的结果对象beanName封装成一个ShortcutDependencyDescriptor对象作为缓存,比如如果当前Bean是原型Bean,那么下次再来创建该Bean时,就可以直接拿缓存的结果对象beanName去BeanFactory中去那bean对象了,不用再次进行查找了
    6.利用反射将找到的所有结果对象传给当前方法,并执行。

  • 相关阅读:
    Python3+Selenium框架搭建
    adobe国际认证证书有用吗?
    centos8同步时间安装时间校准服务
    struts2.x笔记
    传输层 四层负载均衡可以做什么?
    在docker上安装AWVS
    C语言学习-数组(4)
    [c语言]小课堂 day6
    神经网络到底是怎样一回事,神经网络是什么意思
    英国Alevel考试将被英国学士学位取代?
  • 原文地址:https://blog.csdn.net/changyinling520/article/details/134543240