1. 注册 BPP 的 BD

image.png
image.png

2. 创建 BPP Bean

在 refresh () 的 6. registerBeanPostProcessors () ,将所有 BeanPostProcessor 注册到容器中。注意:只是注册但并未执行

image.png

image.png

3. 预解析

image.png
%%
▶1. 🏡⭐️◼️Autowired 注解完成自动装配功能所需要的方法和执行时机是什么 ?🔜MSTM📝 Autowired 自动装配功能是依靠 AutowiredAnnotationBeanPostProcessor 来完成的,这个 BPP 分别实现了 MergedBeanDefinitionPostProcessor 的 postProcessBeanDefinitionRegistry 方法和 InstantiationAwareBeanPostProcessor 的 postProcessProperties 方法,分别完成注解的预解析和装配动作。◼️⭐️-point-20230223-1834%%

在 refresh () 的 11. finishBeanFactoryInitialization(),在实例化之后属性赋值之前,在 MergedBeanDefinitionPostProcessor 的子实现接口 AutowiredAnnotationBeanPostProcessorpostProcessMergedBeanDefinition 方法中,解析@ Autowired@Value 转换 InjectionMetadata 并缓存在 injectionMetadataCache

image.png
image.png

findAutowiringMetadata -> buildAutowiringMetadata ->
findAutowiredAnnotation-> ==List<InjectionMetadata.InjectedElement>==.add(new AutowiredFieldElement(field, required)) ❕%%
0627-🏡⭐️◼️预解析动作 ?🔜MSTM📝 最终封装的是带有 Autowired 注解的属性的 field 和它的 required 属性,封装为 injectionMetadata 放到缓存中备用◼️⭐️-point-202302100627%%

[[pages/002-schdule/001-Arch/001-Subject/013-DemoCode/lianpengju/spring-beans/src/main/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.java]]

4. 自动装配

在 refresh () 的 11. finishBeanFactoryInitialization() 中,applyPropertyValues 真正赋值之前,在 InstantiationAwareBeanPostProcessor 的子实现接口 AutowiredAnnotationBeanPostProcessor 的 (postProcessPropertyValues) postProcessProperties 方法中完成 bean 中@Autowired,@Inject,@Value 注解的解析并注入:

但我们发现被废弃的方法 postProcessPropertyValues 并没有被执行,这个方法是完全没有被使用了吗?其实不是的,当 postProcessProperties 方法的返回值为 null 时,被废弃的方法 postProcessPropertyValues 就会被执行。

postProcessProperties->findAutowiringMetadata->metadata.inject(bean, beanName, pvs)->beanFactory.resolveDependency

  1. 获取依赖的 value 值的工作最终还是委托给 beanFactory.resolveDependency() 去完成的
  2. 这个接口方法由 AutowireCapableBeanFactory 提供,它提供了从 bean 工厂里获取依赖值的能力
  3. resolveDependency 方法根据 descriptor 的依赖类型解析出与 descriptor 所包装的对象匹配的候选 Bean 对象
    %%
    ▶2. 🏡⭐️◼️为什么 Autowired 默认是按类型匹配的 ?🔜MSTM📝 因为在获取属性时使用的方法是 resolveDependency,这个方法是按类型从容器中获取对象的方法◼️⭐️-point-20230223-1830%%

    image.png

image.png

image.png

beanFactory.resolveDependency 根据 descriptor 的依赖类型解析出与 descriptor 所包装的对象匹配的候选 Bean 对象 ^ac1rnt

当容器扫描到@Autowied、@Resource 或@Inject 时,就会在 IOC 容器自动查找需要的 bean,并装配给该对象的属性。在使用@Autowired 时,首先在容器中查询对应类型的 bean
如果查询结果刚好为一个,就将该 bean 装配给@Autowired 指定的数据;
如果查询的结果不止一个,那么@Autowired 会根据名称来查找
如果上述查找的结果为空,那么会抛出异常。解决方法时,使用 required=false。
%%
▶6.🏡⭐️◼️Autowired 默认按类型查找并装配,如果多余 1 个,那么会按名字,如果没有就报错◼️⭐️-point-20230223-1951%%

1、Spring-基础

image.png

5. 实战经验

6. 参考与感谢