• 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.利用反射将找到的所有结果对象传给当前方法,并执行。

  • 相关阅读:
    [附源码]计算机毕业设计校园代取快递系统Springboot程序
    论语第二篇-为政
    一文掌握Lambda表达式(下)
    设计思维|如何构建价值导向的设计思维?
    HTTP 响应头 X-Frame-Options
    数据结构与算法特训365天—深度优先搜索
    Java实现图书管理系统
    Mysql Liunx下安装指南
    结巴(jieba)分词 java 实现
    参与修谱工作,要具备哪些能力?光会修谱可不行
  • 原文地址:https://blog.csdn.net/changyinling520/article/details/134543240