【spring源码-7】bean的实例化(4)后置处理引题

上一篇【spring源码-6】bean的实例化(3)注解收集、依赖注入(DI)

引题

上篇回顾:

image.png

注解收集

  1. CommonAnnotationBeanPostProcessor 收集 @PostConstruct、@PreDestroy、@Resource 注解。
  2. AutowiredAnnotationBeanPostProcessor 收集 @Autowired、@Value 注解。
通过 BeanPostProcessor 完成收集过程。
复制代码

依赖注入(DI)
对含有 @Autowired、@Value、@Resource 注解的属性和方法,通过反射完成注入。

  1. 注入属性,如果是引用类型,会触发 getBean() 实例化需要注入的对象(实例化逻辑就是之前说到的)。
  2. 注入方法时,如果方法形参是引用类型,也会触发 getBean() 操作。

556 行:完成了bean的实例化。
539 行:完成了依赖注入。此时bean已经完成了实例化。
实例化完成之后还有一些后置工作:

initializeBean()

一、Aware 接口的调用

主要逻辑:

Snipaste_2021-11-13_12-49-39.png

如果当前 bean 实现了 Aware 接口,就调用对应的方法:

  1. 实现了 BeanNameAware 接口,调用 setBeanName(beanName);
  2. 实现了 BeanClassLoaderAware 接口,调用 setBeanClassLoader(bcl);
  3. 实现了 BeanFactoryAware 接口,调用 setBeanFactory(AbstractAutowireCapableBeanFactory.this);

应用示例:

1. BeanNameAware 接口

image.png

2. BeanClassLoaderAware 接口

image.png

3. BeanFactoryAware 接口

image.png

二、applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName)

image.png
1786 行:调用到本类方法。如下图:

image.png

BeanProcessor 接口的应用:
循环所有的 BeanProcessor,并调用 postProcessAfterInitialization();完成不同的功能实现。

1. InitDestroyAnnotationBeanPostProcessor 类

完成对类中带有 @PostConstruct 注解的方法的调用。

Snipaste_2021-11-13_13-43-30.png
155 行:获取到类中带有 @PostConstruct 注解的方法,(注解收集的时候已经完成了对 类中带有 @PostConstruct 注解的方法 的收集)。
157 行:调用到如下图:

image.png
333 行:调用 Element 对象的invoke();当前是方法,调用到如下图:

image.png
388 行:将方法设置成可访问的。
389 行:反射调用。

2. ApplicationContextAwareProcessor

完成诸多 Aware 接口的调用。

image.png
81 - 85 行:如果当前bean不是这些Aware类型的,不进行操作,直接返回bean。
106 行:反之就调用对应的方法。

三、invokeInitMethods(beanName, wrappedBean, mbd)

支持 InitializingBean 接口、xml bean标签中 init-method 属性

image.png

主逻辑

定义类信息:
image.png
xmlbean标签
image.png

image.png

  1. 支持 InitializingBean 接口

1836 行:判断当前bean有没有实现 InitializingBean 接口。
1853 行:如果实现了就调用 afterPropertiesSet();注意该方法没有形参。

  1. 支持 xml bean标签中 init-method 属性。

1858 行:获取到BD对象中 InitethodName 属性值。
1859 - 1862 行:如果bean标签中设置了 init-method 属性,并且这个方法名称不是 afterPropertiesSet,就调用这个方法。还是反射调用,调用方法如下:

image.png

应用示例:

image.png
image.png

applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName)

逻辑与上面
二、applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName) 类似。
image.png


总结

spring在完成对 bean 实例化之后,进行了一系列后置操作:

  1. 完成诸多 Aware 接口的调用(功能很多...)。
  2. 完成 类的初始化方法的调用。调用顺序为:@PostConstruct 注解 > InitializingBean 接口 > init-method 属性。

注:本文通过源码 + 行说明的方式进行描述,若不好理解可留言。本文仅为个人学习记录,有错误的地方,请大佬们指正。

下一篇【spring源码-8】bean的实例化(5)FactoryBean接口