Bean 生命周期
之前的文章《Spring IOC 中循环依赖,两幅图搞定》中介绍了 bean 的创建过程:
1. 创建 createBean
2. populateBean
3. initializeBean
第一步,通过反射拿到构造方法创建 bean; 第二步,填充 bean 的属性,如果发现被依赖的属性不存在则会首先创建被依赖属性,然后填充,里面涉及的循环依赖的问题已经讲过;第三步初始化是我们今天来聊的话题。先看代码:
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {
// 1. 调用 Aware 方法
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
// 2. 初始化前:调用 BeanPostProcessor 方法
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
// 3. 初始化
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
if (mbd == null || !mbd.isSynthetic()) {
// 4. 初始化后:调用 BeanPostProcessor 方法
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
invokeAwareMethods
初始化 bean 的第一步是调用 Aware 接口的方法, 如果 bean 实现了 Aware 接口就执行对应的方法:
private void invokeAwareMethods(final String beanName, final Object bean) {
// bean 是否实现 Aware 接口
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 接口可以用来从容器自动获取一些常见的基础依赖,比如设置 beanName、context、classLoader 等, 常见的 Aware 接口:
BeanPostProcessor
这里的接口是 BeanPostProcessor,字面意思 Bean 的后置处理器,也就是 beanFactory 的钩子,允许在 bean 创建后以及初始化前后来修改 bean:
尤其注意的是在如果使用了AOP ,会在 applyBeanPostProcessorsAfterInitialization 方法中由
InfrastructureAdvisorAutoProxyCreator 生成增强对象:
invokeInitMethods
执行初始化方法,如果实现了 InitializingBean 接口,则执行 afterPropertiesSet 方法,如果有 init 方法则执行 init 方法:
protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBeanDefinition mbd)
throws Throwable {
// 是否实现了 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 {
((InitializingBean) bean).afterPropertiesSet();
}
}
// 找 initMethod 并执行,可以通过 @Bean(initMethod = "") 或者 bean 标签 init-method 指定
if (mbd != null && bean.getClass() != NullBean.class) {
String initMethodName = mbd.getInitMethodName();
if (StringUtils.hasLength(initMethodName) &&
!(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
!mbd.isExternallyManagedInitMethod(initMethodName)) {
invokeCustomInitMethod(beanName, bean, mbd);
}
}
}
总结
bean 初始化过程中通过 spring 接口做了很多操作, Aware 接口、BeanPostProcessor 接口、BeanInitializing 接口等,每个接口的作用和常见的子接口需要大家掌握。
如果觉得还不错的话,关注、分享、在看, 原创不易,且看且珍惜~