主要流程
到这里,bean生命周期已经完成了两件大事:
- 调用 createBeanInstance() 方法:完成 bean 的实例化工作
- 调用 populateBean() 方法:完成 bean 的属性填充注入工作
接下来是第三件大事:
初始化 Bean,主要工作:调用工厂回调、init方法执行、后置处理器的执行。
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
// 安全机制特权处理
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
} else {
// 对特殊的 bean 处理:Aware、 BeanClassLoaderaware、 BeanFactoryAware
invokeAwareMethods(beanName, bean);
}
// 执行前置处理器
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
// 执行自定义init方法
try {
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()) {
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
流程1 - invokeAwareMethods�
实现 Aware 接口用于让 bean 能拥有某些额外的扩展能力。
- 如果 bean 实现了 BeanNameAware 接口,则将 beanName 设置进去
- 如果 bean 实现了 BeanClassLoaderAware 接口,则将 ClassLoader 设置进去
- 如果 bean 实现了 BeanFactoryAware 接口,则将 beanFactory 设置进去
也就是说实现了上面的接口,就能得到相关的资源。代码如下所示:
private void invokeAwareMethods(String beanName, 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);
}
}
}
流程2 - applyBeanPostProcessorsBeforeInitialization
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor.postProcessBeforeInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
postProcessBeforeInitialization() 方法是 BeanPostProcessor 接口提供的方法。
它是在 bean 初始化之前调用的,这时的 bean 已完成了实例化和属性填充注入工作。
🔥 流程3 - invokeInitMethods�
执行自定义init方法。自定义方法的方式:
- bean 在 xml 文件中配置 init-method ;
- 标签或使用注解 @Bean(initMethod=” “) ;
实现 InitializingBean 接口,并且在 afterPropertiesSet() 方法中实现自己初始化的业务逻辑。
protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBeanDefinition mbd)
throws Throwable {
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();
}
}
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);
}
}
}
流程4 - applyBeanPostProcessorsAfterInitialization�
postProcessAfterInitialization() 方法是 BeanPostProcessor 接口提供的方法,可以看到它是在 bean 初始化之后调用的,这时的 bean 已完成了实例化,属性填充注入,初始化的工作;可以认为是一个完整的 bean 已在 spring 容器中。
如果使用了 spring aop 功能,那么代理对象的产生就在这个 applyBeanPostProcessorsAfterInitialization() 方法中。Spring 初始化 bean 的方式小结
- xml 配置文件中指定 init-method 标签
- 使用 @PostConstruct 注解
- 实现 InitializingBean 接口
- 使用 @Bean(initMethod=” “) 注解指定