目录
2.1、invokeAwareMethods - 激活 Aware 方法
2.3、 invokeInitMethods - 激活自定义的init方法
第八次调用后置处理器 postProcessAfterInitialization
概述
本文是笔者阅读Spring源码的记录文章,由于本人技术水平有限,在文章中难免出现错误,如有发现,感谢各位指正。在阅读过程中也创建了一些衍生文章,衍生文章的意义是因为自己在看源码的过程中,部分知识点并不了解或者对某些知识点产生了兴趣,所以为了更好的阅读源码,所以开设了衍生篇的文章来更好的对这些知识点进行进一步的学习。
这篇文章是 spring bean生命周期二---Spring Bean实例化( Instantiation)阶段 的文章的展开内容。Spring 在 AbstractAutowireCapableBeanFactory#doCreateBean
方法中,完成了bean的完整创建。而在上篇 spring bean生命周期三---Spring Bean populateBean 属性填充阶段 中,完成了Bean的属性注入,表面上看起来 Bean的创建过程已经结束了。实际上还有一些收尾工作没有完成。本文就是完成Bean创建的收尾工作:完成 Aware 接口的功能,调用后处理器的Bean的后置方法,以及指定的init 方法的激活。
本阶段主要包括:激活 Aware 方法、Spring Bean 初始化前阶段、Spring Bean 初始化阶段(Initialization)、Spring Bean 初始化后阶段、Spring Bean 初始化完成阶段。
一、initializeBean初始化阶段
相较于前几篇的内容,本文的内容显得简单了很多。具体代码如下:
下面的代码只要完成了 Spring Bean 初始化前阶段、Spring Bean 初始化阶段(Initialization)、Spring Bean 初始化后阶段
//初始容器创建的Bean实例对象,为其添加BeanPostProcessor后置处理器
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
//JDK的安全机制验证权限
if (System.getSecurityManager() != null) {
//实现PrivilegedAction接口的匿名内部类
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {
//为Bean实例对象包装相关属性,如名称,类加载器,所属容器等信息
//todo Spring Bean Aware 接口回调阶段
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
//todo 第七次调用后置处理器 BeanPostProcessor后置处理器的postProcessBeforeInitialization
//回调方法的调用,为Bean实例初始化前做一些处理
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
//todo 1、先处理了 InitializingBean#afterPropertiesSet()
// 2、调用Bean实例对象初始化的方法,这个初始化方法是在Spring Bean定义配置
//文件中通过init-method属性指定的
try {
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
//todo 第八次调用 BeanPostProcessor后置处理器的postProcessAfterInitialization
//回调方法的调用,为Bean实例初始化之后做一些处理
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
2.1、invokeAwareMethods - 激活 Aware 方法
这个方法很简单,完成了 Aware 接口的激活功能。可以简单的说 :
- 如果bean实现了
BeanNameAware
接口,则将 beanName设值进去 - 如果bean实现了
BeanClassLoaderAware
接口,则将 ClassLoader 设值进去 - 如果bean实现了
BeanFactoryAware
接口,则将 beanFactory 设值进去
private void invokeAwareMethods(final String beanName, final Object bean) {
if (bean instanceof Aware) {
if (bean instanceof BeanNameAware) {
((BeanNameAware) bean).setBeanName(beanName);
}
if (bean instanceof BeanClassLoaderAware) {
ClassLoader bcl = getBeanClassLoader();
if (bcl != null) {
((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
}
}
if (bean instanceof BeanFactoryAware) {
((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
}
}
}
这里简单解释一下 Aware的作用。从上面的代码可以看到,实现不同类型的 Aware 接口会接受到不同得到初始化数据。
举个例子: 如果bean实现了 BeanFactoryAware
接口,那么他就可以在bean内部获取到beanFacotory。
其实Aware
接口的作用 我在分析 AutowiredAnnotationBeanPostProcessor
后处理器的时候才突然想明白的。 AutowiredAnnotationBeanPostProcess