最近在扫盲Spring相关的点,关于bean生命周期的问题其实是老生常谈了,网上的讲解文章也很多,有的写的很深入,觉得对于我这种菜鸡来讲不太友好,作为一个学习的过程,我这里总结了最基础的一版。
大体流程
- 加载定义
依据包扫描解析类得到BeanDefinition,因为spring都是先把一个个配置类解析成BeanDefinition(bean的定义)再交由bean工厂制作加工成一个个的实例bean
- 实例化 Instantiation
实例化前后会调用InstantiationAwareBeanPostProcessor的postProcessBeforeInstantiationpostProcessafterInstantiation方法 (扩展点)(这里要知道InstantiationAwareBeanPostProcessor是extends BeanPostProcessor)
实例化的代码在doCreateBean方法中
// 忽略了无关代码
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
// Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (instanceWrapper == null) {
// 实例化阶段!
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
// Initialize the bean instance.
Object exposedObject = bean;
try {
// 属性赋值阶段!
populateBean(beanName, mbd, instanceWrapper);
// 初始化阶段!
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
}
- 属性赋值 Populate
populateBean方法中实现了属性赋值包括依赖注入
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
// 这里(实例化之后,初始化之前)执行了InstantiationAwareBeanPostProcessor的postProcessAfterInstantiation方法
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
continueWithPropertyPopulation = false;
break;
}
}
}
}
// autowire在这实现了
if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME || mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) {
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
// Add property values based on autowire by name if applicable.
if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
// Add property values based on autowire by type if applicable.
if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}
// 这里执行了BeanPostProcessor的前置方法
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
if (filteredPds == null) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
return;
}
}
pvs = pvsToUse;
}
}
}
}
回调aware接口(扩展点)
- 初始化 Initialization
初始化前后会调用BeanPostProcessor的postProcessBeforeInitialization/postProcessafterInitialization方法 (扩展点)
- 销毁 Destruction
主要逻辑都在doCreate()方法中,逻辑很清晰,就是顺序调用以下三个方法。
createBeanInstance() -> 实例化
populateBean() -> 属性赋值
initializeBean() -> 初始化
重要的扩展点
第一大类:影响多个Bean的接口
- InstantiationAwareBeanPostProcessor 作用于实例化前后
- BeanPostProcessor 作用于初始化前后
第二大类:只调用一次的接口
1.Aware类型的接口
获取bean相关信息
BeanNameAware
BeanClassLoaderAware
BeanFactoryAware
获取容器相关信息
EnvironmentAware
EmbeddedValueResolverAware 这个知道的人可能不多,实现该接口能够获取Spring EL解析器,用户的自定义注解需要支持spel表达式的时候可以使用,非常方便。
ApplicationContextAware(ResourceLoaderAware\ApplicationEventPublisherAware\MessageSourceAware) 这几个接口可能让人有点懵,实际上这几个接口可以一起记,其返回值实质上都是当前的ApplicationContext对象,因为ApplicationContext是一个复合接口,如下:
2.生命周期接口
InitializingBean 初始化
DisposableBean 销毁