前言
一个Bean的实例化大致有以下几步:
- Bean的创建
- 各种信息的收集
- 依赖注入
- Bean的初始化
现在 第一步 bean的创建和 各种注解信息的收集已经完毕。
接下来 就是 Bean 属性的依赖注入了。
依赖注入环节同样是 由BeanPostProcessor类来完成的。
- AutowiredAnnotationBeanPostProcessor : 注入有@Autowired/@Value注解的属性。
- CommonAnnotationBeanPostProcessor :注入@Resource的属性。
1. @Autowired/@Value注解的属性的依赖注入
在 实例化bean和 收集信息之后, 这个代码就是 依赖注入。AbstractAutowireCapableBeanFactory.doCreateBean()
imagepopulateBean方法:
取出所有的BeanPostProcessor,判断是否是 InstantiationAwareBeanPostProcessor, 遍历调用postProcessProperties来进行依赖注入。
image每个BeanPostProceesor的关注点都不同, 在这里 AutowiredAnnotationBeanPostProcessor 是用来 注入@Autowired/@Value的属性的。
看AutowiredAnnotationBeanPostProcessor.postProcessProperties()方法
1.从之前InjectionMetadata 取出需要注入的属性和方法
image这里直接从AutowiredAnnotationBeanPostProcessor的缓存injectionMetadataCache属性里拿。之前收集的时候已经做好缓存了。
image2.调用每一个InjectedElement 进行依赖注入
上一节讲过收集 的过程中, 需要 @Autowired和@Value进行依赖注入的属性和方法 已经放到了 InjectionMetadata对象的容器里了 : checkedElements。
属性被封装成了AutowiredFieldElement对象,方法被封装成了AutowiredMethodElement对象,这两个类都继承了InjectedElement类。
Set<InjectedElement> checkedElements
这里直接 取出 符合的属性和方法,调用inject方法 ,同时传入bean实例 ,进行 依赖注入。
image2.1 属性的依赖注入:AutowiredFieldElement.inject()
2.1.1 先是从BeanFactory获取 需要的 值
image image2.1.1.1 @Value
如果是字符串类型的属性, 并且有@Value,那么就需要从配置文件里获取对应的值。
image关于配置文件和配置文件 信息注入后续会有专门的篇章来讲。这里先一笔带过。
2.1.1.2 @Autowired
如果是@Autowired修饰的引用类型,那么就需要从BeanFactory 根据name 来获取bean, 赋值给这个属性。
image2.1.1.2.1 resolvableDependencies
一开始有个容器 :resolvableDependencies,
image但是这个容器里的东西很少,只有内置的几个类的对象,后续 也不会再添加已经依赖注入好的值放里面。
image这几个值 是在容器启动的核心方法,refresh()里的prepareBeanFactory(beanFactory); 就设置好的。
image image image如果你的bean 需要依赖注入的是这几个类型,那么就会从这个 预设好的容器里找值赋给属性。
- BeanFactory
- ResourceLoader
- ApplicationEventPublisher
- ApplicationContext
2.1.1.2.2 非内置类型,从BeanFactory获取
除了以上几种类型,其他的去BeanFactory获取
image image最后的就是 beanFactory.getBean(beanName)
image2.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 image2.2 依赖注入
调用 InjectionMetadata.inject() 进行依赖注入:
image循环每一个封装有属性或者方法的InjectedElement对象,调用inject
image最後肯定是先获取 到 值,在反射给属性赋值。
image获取属性依赖的值
getResourceToInject(target, requestingBeanName) 最终还是 从BeanFactory.getBean(beanName)拿值
image image image
网友评论