一、介绍
初始化bean的动作是在创建bean和给bean填充属性之后,目的是为了调用用户自定义的初始化方法。期间还涉及到Aware接口和BeanPostProcessor的处理,处理流程如下:
二、bean加载流程
- 获取用户传入name对应的beanName
- 尝试从缓存中获取bean实例
- 缓存中不存在,加载bean实例
3.1. 检查循环依赖
3.2 处理parentBeanFactory
3.3 处理依赖的bean(dependsOn)
3.4 三种bean实例的创建
3.4.1 单例bean的创建
3.4.1.1 获取单例bean,getSingleton()方法
3.4.1.2 准备创建bean,createBean()方法
3.4.1.3 创建bean,doCreateBean()方法
3.4.1.3.1 创建BeanWrapper
3.4.1.3.2 记录bean的Object-Factory
3.4.1.3.3 属性填充
3.4.1.3.3 初始化bean(本章解析)
3.4.2 原型bean的创建
3.4.3 根据scope策略创建bean - 从bean实例中获取真正的对象
- 转换对象类型
- 返回对象实例
三、主要方法
- org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean:初始化bean的整体流程
- org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#invokeAwareMethods:调用具体Aware接口的对应方法
- org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#invokeInitMethods:调用用户自定义的初始化方法
四、源码分析
1. 初始化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类型bean的对应方法
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
// 2. 初始化前,应用后处理器
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
// 3. 激活用户自定义的init方法
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. 初始化后,应用后处理器
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
从代码中可以看到,初始化bean不仅仅是调用用户自定义的初始化方法。而是经历了以下四个步骤:
- 如果bean是Aware类型,则调用具体Aware的对应方法
- 调用BeanPostProcessor的postProcessBeforeInitialization方法
- 调用bean的初始化方法
- 调用BeanPostProcessor的postProcessAfterInitialization方法
2. 给Aware类型的bean设置资源
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);
}
}
}
如果该bean实现了某种Aware接口,初始化的时候spring就会调用该接口的特定方法,来给bean传递某种类型的值。目前一共有三种Aware接口:BeanNameAware(获取bean名称)、BeanClassLoaderAware(获取类加载器)、BeanFactoryAware(获取bean工厂)。
3. 调用bean的初始化方法
protected void invokeInitMethods(String beanName, final Object bean, @Nullable RootBeanDefinition mbd)
throws Throwable {
// 1. 如果是InitializingBean类型的bean,调用bean的afterPropertiesSet方法
boolean isInitializingBean = (bean instanceof InitializingBean);
if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
if (logger.isDebugEnabled()) {
logger.debug("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 {
// 调用bean的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)) {
// 2. 调用用户自定义的初始化方法
invokeCustomInitMethod(beanName, bean, mbd);
}
}
}
如果bean实现了InitializingBean接口,则先调用afterPropertiesSet方法;然后调用用户自定义的初始化方法。指定初始化方法的方式如下
<bean id="personInit" class="com.kaka.spring.pojo.Person" init-method="testInitMethod" />