上一篇【spring源码-6】bean的实例化(3)注解收集、依赖注入(DI)
引题
上篇回顾:
注解收集
- CommonAnnotationBeanPostProcessor 收集 @PostConstruct、@PreDestroy、@Resource 注解。
- AutowiredAnnotationBeanPostProcessor 收集 @Autowired、@Value 注解。
通过 BeanPostProcessor 完成收集过程。 复制代码
依赖注入(DI)
对含有 @Autowired、@Value、@Resource 注解的属性和方法,通过反射完成注入。
- 注入属性,如果是引用类型,会触发 getBean() 实例化需要注入的对象(实例化逻辑就是之前说到的)。
- 注入方法时,如果方法形参是引用类型,也会触发 getBean() 操作。
556 行:完成了bean的实例化。
539 行:完成了依赖注入。此时bean已经完成了实例化。
实例化完成之后还有一些后置工作:
initializeBean()
一、Aware 接口的调用
主要逻辑:
如果当前 bean 实现了 Aware 接口,就调用对应的方法:
- 实现了 BeanNameAware 接口,调用 setBeanName(beanName);
- 实现了 BeanClassLoaderAware 接口,调用 setBeanClassLoader(bcl);
- 实现了 BeanFactoryAware 接口,调用 setBeanFactory(AbstractAutowireCapableBeanFactory.this);
应用示例:
1. BeanNameAware 接口
2. BeanClassLoaderAware 接口
3. BeanFactoryAware 接口
二、applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName)
1786 行:调用到本类方法。如下图:
BeanProcessor 接口的应用:
循环所有的 BeanProcessor,并调用 postProcessAfterInitialization();完成不同的功能实现。
1. InitDestroyAnnotationBeanPostProcessor 类
完成对类中带有 @PostConstruct 注解的方法的调用。
155 行:获取到类中带有 @PostConstruct 注解的方法,(注解收集的时候已经完成了对 类中带有 @PostConstruct 注解的方法 的收集)。
157 行:调用到如下图:
333 行:调用 Element 对象的invoke();当前是方法,调用到如下图:
388 行:将方法设置成可访问的。
389 行:反射调用。
2. ApplicationContextAwareProcessor
完成诸多 Aware 接口的调用。
81 - 85 行:如果当前bean不是这些Aware类型的,不进行操作,直接返回bean。
106 行:反之就调用对应的方法。
三、invokeInitMethods(beanName, wrappedBean, mbd)
支持 InitializingBean 接口、xml bean标签中 init-method 属性
主逻辑
定义类信息:
xmlbean标签:
- 支持 InitializingBean 接口
1836 行:判断当前bean有没有实现 InitializingBean 接口。
1853 行:如果实现了就调用 afterPropertiesSet();注意该方法没有形参。
- 支持 xml bean标签中 init-method 属性。
1858 行:获取到BD对象中 InitethodName 属性值。
1859 - 1862 行:如果bean标签中设置了 init-method 属性,并且这个方法名称不是 afterPropertiesSet,就调用这个方法。还是反射调用,调用方法如下:
应用示例:
applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName)
逻辑与上面
二、applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName) 类似。
总结
spring在完成对 bean 实例化之后,进行了一系列后置操作:
- 完成诸多 Aware 接口的调用(功能很多...)。
- 完成 类的初始化方法的调用。调用顺序为:@PostConstruct 注解 > InitializingBean 接口 > init-method 属性。
注:本文通过源码 + 行说明的方式进行描述,若不好理解可留言。本文仅为个人学习记录,有错误的地方,请大佬们指正。
近期评论