12、Spring initializeBean源码分析
12、Spring initializeBean源码分析
一,initializeBean 方法概述
Spring 中的 initializeBean()方法是 doCreateBean 方法三部曲的最后一步,完成 initializeBean()则整个 bean 的创建过程才算完成,我们来看一下 bean 的创建过程 doCreateBean()方法中三部曲:实例化(createBeanInstance),填充属性(populateBean),初始化(initializeBean)。
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
implements AutowireCapableBeanFactory {
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
// 省略部分代码....
// 第一步:实例化bean
instanceWrapper = createBeanInstance(beanName, mbd, args);
// 为避免后期循环依赖,提前曝露ObjectFactory到第三级缓存中。
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
// 第二步:填充属性
populateBean(beanName, mbd, instanceWrapper);
// 第三步:执行初始化逻辑
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
}
本文主要分析是 initializeBean 初始化,关于前面两步 “实例化” 和 “填充属性” 两步,请参考:
Spring 实例化(createBeanInstance)源码解析
initializeBean 初始化主要分为如下几个步骤:
1、 执行 aware 接口 invokeAwareMethods;
2、 执行 BeanPostProcessor 的 postProcessBeforeInitialization()方法;
3、 执行初始化方法 invokeInitMethods;
4、 执行 BeanPostProcessor 的 postProcessAfterInitialization()方法;
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
// Aware接口处理器,调用BeanNameAware、BeanClassLoaderAware、beanFactoryAware
invokeAwareMethods(beanName, bean);
// 调用BeanPostProcessor的postProcessBeforeInitialization方法。
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
// 调用初始化方法,先调用bean的InitializingBean接口方法,后调用bean的自定义初始化方法
invokeInitMethods(beanName, wrappedBean, mbd);
// 调用BeanPostProcessor的applyBeanPostProcessorsAfterInitialization方法。
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
//返回包装后的Bean
return wrappedBean;
}
我们从上面可以看到,在 beanPostProcessor 接口的 postProcessBeforeInitialization()方法和 postProcessAfterInitialization()方法都可以对最终的 bean 做修改或替换。
如果我们配置的有 Aop 代理的话,会在执行 AbstractAutoProxyCreator 类的 postProcessAfterInitialization()方法时创建此 bean 代理对象,并且把此代理对象放入 bean 容器中。
二,执行 aware 接口 invokeAwareMethods
这个方法就是判断一下当前 bean 是否实现了 BeanNameAware,BeanClassLoaderAware,BeanFactoryAware 接口,如果实现了,就回调相应的方法。比较简单,没啥好说的,直接看源码就行了:
private void invokeAwareMethods(String beanName, Object bean) {
//如果 bean 是 Aware 实例
if (bean instanceof Aware) {
//如果bean是BeanNameAware实例
if (bean instanceof BeanNameAware) {
//调用 bean 的setBeanName方法
((BeanNameAware) bean).setBeanName(beanName);
}
//如果bean是 BeanClassLoaderAware 实例
if (bean instanceof BeanClassLoaderAware) {
//获取此工厂的类加载器以加载Bean类(即使无法使用系统ClassLoader,也只能为null)
ClassLoader bcl = getBeanClassLoader();
if (bcl != null) {
//调用 bean 的 setBeanClassLoader 方法
((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
}
}
//如果bean是 BeanFactoryAware 实例
if (bean instanceof BeanFactoryAware) {
// //调用 bean 的 setBeanFactory 方法
((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
}
}
}
三,执行 BeanPostProcessor 的 postProcessBeforeInitialization()方法
postProcessBeforeInitialization()方法会在执行 init 方法之前调用,遍历 beanPostProcessors 集合调用 postProcessBeforeInitialization()方法。
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
throws BeansException {
//初始化返回结果为existingBean
Object result = existingBean;
//遍历 该工厂创建的bean的BeanPostProcessors列表
for (BeanPostProcessor processor : getBeanPostProcessors()) {
// postProcessBeforeInitialization:在任何Bean初始化回调之前(如初始化Bean的afterPropertiesSet或自定义的init方法)
// 将此BeanPostProcessor 应用到给定的新Bean实例。Bean已经填充了属性值。返回的Bean实例可能时原始Bean的包装器。
// 默认实现按原样返回给定的 Bean
Object current = processor.postProcessBeforeInitialization(result, beanName);
// 如果 current为null
if (current == null) {
//直接返回result,中断其后续的BeanPostProcessor处理
return result;
}
//让result引用processor的返回结果,使其经过所有BeanPostProcess对象的后置处理的层层包装
result = current;
}
//返回经过所有BeanPostProcess对象的后置处理的层层包装后的result
return result;
}
1,ApplicationContextAwareProcessor 调用 Aware 接口方法
主要完成,判断当前 bean 是否实现 EnvironmentAware,EmbeddedValueResolverAware,ResourceLoaderAware,ApplicationEventPublisherAware,MessageSourceAware,ApplicationContextAware 接口,如果实现则对其方法进行调用。
class ApplicationContextAwareProcessor implements BeanPostProcessor {
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if (!(bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware ||
bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware ||
bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)){
return bean;
}
AccessControlContext acc = null;
if (System.getSecurityManager() != null) {
acc = this.applicationContext.getBeanFactory().getAccessControlContext();
}
if (acc != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
// 检测bean上是否实现了某个aware接口,有的话进行相关的调用
invokeAwareInterfaces(bean);
return null;
}, acc);
}
else {
invokeAwareInterfaces(bean);
}
return bean;
}
}
2,ConfigurationClassPostProcessor 调用 ImportAware 接口方法
如果 bean 实现了 ImportAware 接口,就会设置 bean 的注解信息:
public Object postProcessBeforeInitialization(Object bean, String beanName) {
if (bean instanceof ImportAware) {
ImportRegistry ir = this.beanFactory.getBean(IMPORT_REGISTRY_BEAN_NAME, ImportRegistry.class);
AnnotationMetadata importingClass = ir.getImportingClassFor(ClassUtils.getUserClass(bean).getName());
if (importingClass != null) {
((ImportAware) bean).setImportMetadata(importingClass);
}
}
return bean;
}
3,InitDestroyAnnotationBeanPostProcessor 调用被注解修饰的生命周期方法
在 doCreateBean 中,createBeanInstance 实例化完成之后,populateBean 填充属性执行之前,会执行 applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName)方法:
protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof MergedBeanDefinitionPostProcessor) {
MergedBeanDefinitionPostProcessor bdp = (MergedBeanDefinitionPostProcessor) bp;
bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName);
}
}
}
目的是允许 beanPostProcessor 去修改合并的 beanDefinition,其中会执行 InitDestroyAnnotationBeanPostProcessor 类的 postProcessMergedBeanDefinition()方法:
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
// 调用方法获取生命周期元数据并保存
LifecycleMetadata metadata = findLifecycleMetadata(beanType);
// 验证相关方法
metadata.checkConfigMembers(beanDefinition);
}
会获取当前 bean 中包含的被@PostContruct 和@PreDestroy 注解标注的方法存储在 lifecycleMetadataCache 的 map 中。
所以在 InitDestroyAnnotationBeanPostProcessor 类的 postProcessBeforeInitialization()方法中会通过反射去调用上面缓存在 lifecycleMetadataCache 中的被@PostContruct 注解修饰的方法:
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
LifecycleMetadata metadata = findLifecycleMetadata(bean.getClass());
try {
metadata.invokeInitMethods(bean, beanName);
}
catch (InvocationTargetException ex) {
throw new BeanCreationException(beanName, "Invocation of init method failed", ex.getTargetException());
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "Failed to invoke init method", ex);
}
return bean;
}
四,执行初始化方法 invokeInitMethods
如果 bean 实现了 InitializingBean 接口,则先执行 InitializingBean 接口的 afterPropertiesSet 方法。
然后执行 xml 或注解设置的 init-method 方法。
protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBeanDefinition mbd)
throws Throwable {
// 省略部分代码...
// 调用bean的afterPropertiesSet方法
((InitializingBean) bean).afterPropertiesSet();
// 在bean上调用指定的自定义init方法
invokeCustomInitMethod(beanName, bean, mbd);
}
五,执行 BeanPostProcessor 的 postProcessAfterInitialization()方法
遍历 beanPostProcessors 集合,执行 BeanPostProcessor 的后置处理器:
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
//初始化结果对象为result,默认引用existingBean
Object result = existingBean;
//遍历该工厂创建的bean的BeanPostProcessors列表
for (BeanPostProcessor processor : getBeanPostProcessors()) {
//回调BeanPostProcessor#postProcessAfterInitialization来对现有的bean实例进行包装
Object current = processor.postProcessAfterInitialization(result, beanName);
//一般processor对不感兴趣的bean会回调直接返回result,使其能继续回调后续的BeanPostProcessor;
// 但有些processor会返回null来中断其后续的BeanPostProcessor
// 如果current为null
if (current == null) {
//直接返回result,中断其后续的BeanPostProcessor处理
return result;
}
//让result引用processor的返回结果,使其经过所有BeanPostProcess对象的后置处理的层层包装
result = current;
}
//返回经过所有BeanPostProcess对象的后置处理的层层包装后的result
return result;
}
1,AbstractAutoProxyCreator 生成 aop 代理对象
如果使用了 aop 代理,那么此处会生成代理对象,替换原生 bean 对象。
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
if (bean != null) {
// 根据给定bean的name和class构建出一个key
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (this.earlyProxyReferences.remove(cacheKey) != bean) {
// 如果它需要被代理,则需要封装指定的bean
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
首先查看是否在 earlyProxyReferences 缓存中存在,如果有就说明处理过了,不存在就考虑是否需要被代理,如需要则创建代理对象(对原生 bean 封装)。
2,ApplicationListenerDetector 检测 bean 是否实现了 ApplicationListener 接口
如果 bean 是单例的并且实现了 ApplicationListener 接口,则加入到多播器中 applicationEventMulticaster。
public Object postProcessAfterInitialization(Object bean, String beanName) {
if (bean instanceof ApplicationListener) {
// 判断当前bean是否是单例,如果是的话,直接添加到容器的监听器集合中
Boolean flag = this.singletonNames.get(beanName);
if (Boolean.TRUE.equals(flag)) {
// 添加到容器的监听器集合中
this.applicationContext.addApplicationListener((ApplicationListener<?>) bean);
}
// 如果不是单例的,并且又是一个嵌套的bean,那么打印日志,提示内嵌的bean只有在单例的情况下才能作为事件监听器
}
return bean;
}
六,总结
生命周期执行顺序:
1、 @PostConstruct 注解修饰的方法;
2、 InitializingBean 接口的 afterPropertiesSet()方法;
3、 init-method 指定的方法;
4、 @PreDestroy 注解修饰的方法;
5、 DisposableBean 接口的 destroy()方法;
6、 destory-method 指定的方法;