美文网首页spring
【Spring源码】11.IOC之Bean初始化之依赖注入

【Spring源码】11.IOC之Bean初始化之依赖注入

作者: 天还下着毛毛雨 | 来源:发表于2022-01-27 17:01 被阅读0次
    image

    前言

    一个Bean的实例化大致有以下几步:

    1. Bean的创建
    2. 各种信息的收集
    3. 依赖注入
    4. Bean的初始化

    现在 第一步 bean的创建和 各种注解信息的收集已经完毕。

    接下来 就是 Bean 属性的依赖注入了。

    依赖注入环节同样是 由BeanPostProcessor类来完成的。

    1. AutowiredAnnotationBeanPostProcessor : 注入有@Autowired/@Value注解的属性。
    2. CommonAnnotationBeanPostProcessor :注入@Resource的属性。

    1. @Autowired/@Value注解的属性的依赖注入

    在 实例化bean和 收集信息之后, 这个代码就是 依赖注入。AbstractAutowireCapableBeanFactory.doCreateBean()

    image

    populateBean方法:

    取出所有的BeanPostProcessor,判断是否是 InstantiationAwareBeanPostProcessor, 遍历调用postProcessProperties来进行依赖注入。

    image

    每个BeanPostProceesor的关注点都不同, 在这里 AutowiredAnnotationBeanPostProcessor 是用来 注入@Autowired/@Value的属性的。

    看AutowiredAnnotationBeanPostProcessor.postProcessProperties()方法

    1.从之前InjectionMetadata 取出需要注入的属性和方法

    image

    这里直接从AutowiredAnnotationBeanPostProcessor的缓存injectionMetadataCache属性里拿。之前收集的时候已经做好缓存了。

    image

    2.调用每一个InjectedElement 进行依赖注入

    上一节讲过收集 的过程中, 需要 @Autowired和@Value进行依赖注入的属性和方法 已经放到了 InjectionMetadata对象的容器里了 : checkedElements。

    属性被封装成了AutowiredFieldElement对象,方法被封装成了AutowiredMethodElement对象,这两个类都继承了InjectedElement类。

    Set<InjectedElement> checkedElements
    

    这里直接 取出 符合的属性和方法,调用inject方法 ,同时传入bean实例 ,进行 依赖注入。

    image

    2.1 属性的依赖注入:AutowiredFieldElement.inject()

    2.1.1 先是从BeanFactory获取 需要的 值

    image image
    2.1.1.1 @Value

    如果是字符串类型的属性, 并且有@Value,那么就需要从配置文件里获取对应的值。

    image

    关于配置文件和配置文件 信息注入后续会有专门的篇章来讲。这里先一笔带过。

    2.1.1.2 @Autowired

    如果是@Autowired修饰的引用类型,那么就需要从BeanFactory 根据name 来获取bean, 赋值给这个属性。

    image
    2.1.1.2.1 resolvableDependencies

    一开始有个容器 :resolvableDependencies,

    image

    但是这个容器里的东西很少,只有内置的几个类的对象,后续 也不会再添加已经依赖注入好的值放里面。

    image

    这几个值 是在容器启动的核心方法,refresh()里的prepareBeanFactory(beanFactory); 就设置好的。

    image image image

    如果你的bean 需要依赖注入的是这几个类型,那么就会从这个 预设好的容器里找值赋给属性。

    1. BeanFactory
    2. ResourceLoader
    3. ApplicationEventPublisher
    4. ApplicationContext
    2.1.1.2.2 非内置类型,从BeanFactory获取

    除了以上几种类型,其他的去BeanFactory获取

    image image

    最后的就是 beanFactory.getBean(beanName)

    image

    2.1.2 反射赋给bean的属性

    获取到值之后,field.set(bean, value); 反射赋值就完成了bean 属性的依赖注入。

    image

    好了,@Autowired和@Value的属性 的依赖注入就成了,bean的该属性就有值了。

    2. @Resource注解的属性的依赖注入

    负责为@Resource注解属性 进行依赖注入的是 这个,CommonAnnotationBeanPostProcessor类, 负责收集@Resource注解属性 的也是他。

    代码回到这里 :

    image

    点进CommonAnnotationBeanPostProcessor类的postProcessProperties方法:逻辑和@Autowired/@Value属性的依赖注入是一样的

    2.1. 先从缓存里拿 收集好 的, 带有@Resource 注解的属性的 InjectionMetadata对象

    image image

    2.2 依赖注入

    调用 InjectionMetadata.inject() 进行依赖注入:

    image

    循环每一个封装有属性或者方法的InjectedElement对象,调用inject

    image

    最後肯定是先获取 到 值,在反射给属性赋值。

    image

    获取属性依赖的值

    getResourceToInject(target, requestingBeanName) 最终还是 从BeanFactory.getBean(beanName)拿值

    image image image

    相关文章

      网友评论

        本文标题:【Spring源码】11.IOC之Bean初始化之依赖注入

        本文链接:https://www.haomeiwen.com/subject/rcuahrtx.html