populateBean方法执行后,就开始执行initializeBean方法了。在这之前前面已经完成了Bean的属性设置、依赖注入,这里属于bean初始化过程的后置部分。给用户提供一个入口,实现其他特性。
方法源码如下所示:
// AbstractAutowireCapableBeanFactory
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
// JDK安全校验机制
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
// bean后置处理器的postProcessBeforeInitialization方法
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
// 初始化方法
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
// bean后置处理器的postProcessAfterInitialization方法
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
如上代码所示,这里主要核心有四个步骤:invokeAwareMethods、applyBeanPostProcessorsBeforeInitialization、invokeInitMethods以及applyBeanPostProcessorsAfterInitialization。
① invokeAwareMethods方法
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);
}
}
}
源码如上所示,其将会分别尝试触发:
- ((BeanNameAware) bean).setBeanName(beanName);-设置BeanName
- ((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);–设置Bean加载器
- ((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);–设置BeanFactory
② applyBeanPostProcessorsBeforeInitialization
applyBeanPostProcessorsBeforeInitialization
方法会循环遍历BeanPostProcessor
并调用其postProcessBeforeInitialization
方法。
如CommonAnnotationBeanPostProcessor
其继承自InitDestroyAnnotationBeanPostProcessor
实现了InstantiationAwareBeanPostProcessor
接口。那么在这里就会反射调用那些被标注了@PostConstruct
注解的方法,也可以看到其是在init-method方法执行前。
③ invokeInitMethods
protected void invokeInitMethods(String beanName, final Object bean, @Nullable RootBeanDefinition mbd)
throws Throwable {
// 是否为InitializingBean,也就是是否实现了InitializingBean接口
boolean isInitializingBean = (bean instanceof InitializingBean);
if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
if (logger.isTraceEnabled()) {
logger.trace("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
}
if (System.getSecurityManager() != null) {
try {
AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
((InitializingBean) bean).afterPropertiesSet();
return null;
}, getAccessControlContext());
}
catch (PrivilegedActionException pae) {
throw pae.getException();
}
}
else {
// 调用其afterPropertiesSet方法
((InitializingBean) bean).afterPropertiesSet();
}
}
if (mbd != null && bean.getClass() != NullBean.class) {
String initMethodName = mbd.getInitMethodName();
if (StringUtils.hasLength(initMethodName) &&
!(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
!mbd.isExternallyManagedInitMethod(initMethodName)) {
// 尝试反射调用initMethod 初始化方法
invokeCustomInitMethod(beanName, bean, mbd);
}
}
}
也就是说invokeInitMethods方法将会分别尝试触发:
- ((InitializingBean) bean).afterPropertiesSet();
- invokeCustomInitMethod(beanName, bean, mbd);
④ applyBeanPostProcessorsAfterInitialization
该方法会循环遍历BeanPostProcessor
并调用其postProcessAfterInitialization
方法。
同样以CommonAnnotationBeanPostProcessor为例,这里会触发其postProcessAfterInitialization调用,不过该处理器此时未做任何动作只是返回了bean。
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
总结
在调用Bean的初始化方法之前,会调用一系列的aware接口实现,把相关的BeanName、BeanClassLoader以及BeanFactory注入到Bean中区。
接着会看到对invokeInitMethods的调用,如果Bean实现了InitializingBean的接口,会调用其afterPropertiesSet方法。
最后还会判断Bean是否配置有initMethod,如果有那么通过invokeCustomInitMethod方法 来直接调用,最终完成Bean的初始化。
关于Bean的初始化/生命周期可以参考博文:
Spring中Bean的作用域与生命周期
Spring中bean的初始化和销毁几种实现方式详解
Spring中那些BeanPostProcessor在Bean实例化过程中的作用