普通bean对象的初始化流程
在上文中分析ApplicationContext的refresh过程,在这过程中对于业务bean对象添加到Spirng容器的过程,在这个流程的最后一步骤就是初始化业务bean对象,下面这个业务bean对象的初始化流程进行分析;
整体执行流程
AbstractApplicationContext:refresh() -> finishBeanFactoryInitialization()
-> DefaultListableBeanFactory.preInstantiateSingletons()
-> DefaultSingletonBeanRegistry:preInstantiateSingletons() -> getBean(beanName)
-> AbstractBeanFactory.doGetBean() -> getSingleton(beanName)|createBean(beanName, mbd, args) ->
-> AbstractAutowireCapableBeanFactory:createBean() ->resolveBeforeInstantiation(beanName, mbdToUse) -> doCreateBean() -> initializeBean() -> applyBeanPostProcessorsBeforeInitialization()|invokeInitMethods()|applyBeanPostProcessorsAfterInitialization()
invokeInitMethods(): ->invokeCustomInitMethod()->BeanUtils.findMethod()|ClassUtils.getMethodIfAvailable()->ClassUtils.getInterfaceMethodIfPossible->methodToInvoke.invoke
上面的流程稍微复杂一点,化繁为简来看有几个总要的步骤:
- 调用入口方法:finishBeanFactoryInitialization()
- 循环依赖处理:AbstractBeanFactory.doGetBean()
- 提前初始化扩展点:resolveBeforeInstantiation()
- 执行初始化前置扩展点:applyBeanPostProcessorsBeforeInitialization()
- 执行初始化:invokeInitMethods()
- 执行初始化后置扩展点:applyBeanPostProcessorsAfterInitialization()
调用入口方法
调用初始化业务bean的方法是在finishBeanFactoryInitialization进行处理的,
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
//省略...
//1. 提前加载LoadTimeWeaverAware实例,用于在class加载的过程中实现AOP的功能
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {
getBean(weaverAwareName);
}
//2. 停止使用临时类加载器进行类型匹配
beanFactory.setTempClassLoader(null);
//3. 允许缓存所有 Bean 定义元数据,而不期望进一步更改
beanFactory.freezeConfiguration();
//4. 调用beanFactory实例化bean对象.
beanFactory.preInstantiateSingletons();
}
前面省略的主要是在做一些前置转换和设置默认处理的特殊操作.
下面的第一个步骤比较有意思是在类进行加载的过程中实现AOP的功能,可以看到LoadTimeWeaverAware类有3个实现类,分别是LocalContainerEntityManagerFactoryBean、DefaultPersistenceUnitManager、AspectJWeavingEnabler;
在LoadTimeWeaverAware接口中只定义了一个方法
public interface LoadTimeWeaverAware extends Aware {
//设置加载时间
void setLoadTimeWeaver(LoadTimeWeaver loadTimeWeaver);
}
下面对这三个实现类进行分析:
- AspectJWeavingEnabler
AspectJWeavingEnabler这个类是属于weaving织入模块下的一个配置类,主要是负责注册AspectJ的后处理器ClassPreProcessorAgentAdapter,这个类中的关键代码如下:
@Override
public void setLoadTimeWeaver(LoadTimeWeaver loadTimeWeaver) {
this.loadTimeWeaver = loadTimeWeaver;
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
enableAspectJWeaving(this.loadTimeWeaver, this.beanClassLoader);
}
public static void enableAspectJWeaving(
@Nullable LoadTimeWeaver weaverToUse, @Nullable ClassLoader beanClassLoader) {
if (weaverToUse == null) {
if (InstrumentationLoadTimeWeaver.isInstrumentationAvailable()) {
weaverToUse = new InstrumentationLoadTimeWeaver(beanClassLoader);
}
else {
throw new IllegalStateException("No LoadTimeWeaver available");
}
}
weaverToUse.addTransformer(
new AspectJClassBypassingClassFileTransformer(new ClassPreProcessorAgentAdapter()));
}
AspectJWeavingEnabler实现LoadTimeWeaverAware主要目的是为了将LoadTimeWeaver对象作为实参传递进来,然后添加AspectJClassBypassingClassFileTransformer,这个类实现了ClassFileTransformer从而完成在类的加载期间进行增强的功能;
循环依赖处理
在org.springframework.beans.factory.support.AbstractBeanFactory#getSingleton方法中实现检查循环依赖,具体实现方法如下
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(beanName, "Bean name must not be null");
synchronized (this.singletonObjects) {
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
//将beanName添加到singletonsCurrentlyInCreation(目前正在创建的bean对象集合中)
beforeSingletonCreation(beanName);
boolean newSingleton = false;
try {
singletonObject = singletonFactory.getObject();
newSingleton = true;
}
//省略...
//如果是新创建的对象
if (newSingleton) {
addSingleton(beanName, singletonObject);
}
}
return singletonObject;
}
}
protected void addSingleton(String beanName, Object singletonObject) {
synchronized (this.singletonObjects) {
//单例对象的缓存:key-bean对象名称
this.singletonObjects.put(beanName, singletonObject);
//单例工厂的缓存:key-ObjectFactory的 Bean名称
this.singletonFactories.remove(beanName);
//早期单例对象的缓存
this.earlySingletonObjects.remove(beanName);
//已注册的bean单例名称set集合
this.registeredSingletons.add(beanName);
}
}
在这个方法中大部分方法进行了省略,只保留最关键的几行代码
singletonObject = singletonFactory.getObject();这里调用singletonFactory生成bean对象;
然后将bean对象添加到singletonObjects和registeredSingletons,singletonObjects就是常说的一级缓存,在getSingleton(String beanName)中会使用到,下面继续分析doCreateBean(String beanName)方法,doCreateBean方法是在getSingleton方法中显示调用的
- DefaultSingletonBeanRegistry.java
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
// 快速缓存单例以便能够解析循环引用
// 即使由 BeanFactoryAware 等生命周期接口触发.
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isTraceEnabled()) {
logger.trace("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
}
protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(singletonFactory, "Singleton factory must not be null");
synchronized (this.singletonObjects) {
if (!this.singletonObjects.containsKey(beanName)) {
//向三级缓存添加对象
this.singletonFactories.put(beanName, singletonFactory);
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.add(beanName);
}
}
}
在这一步中Spring提前将singletonFactory放到三级缓存中,下面继续分析属性对象的初始化过程
//设置bean对象的属性
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
// 如果适用,按名称添加bean对象
if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
//自动装载bean对象
autowireByName(beanName, mbd, bw, newPvs);
}
// 如果适用,按类型添加bean对象
if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
//自动装载bean对象
autowireByType(beanName, mbd, bw, newPvs);
}
}
protected void autowireByName(
String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
for (String propertyName : propertyNames) {
if (containsBean(propertyName)) {
//获取bean对象
Object bean = getBean(propertyName);
pvs.add(propertyName, bean);
registerDependentBean(propertyName, beanName);
if (logger.isTraceEnabled()) {
logger.trace("Added autowiring by name from bean name '" + beanName +
"' via property '" + propertyName + "' to bean named '" + propertyName + "'");
}
}
}
}
可以看到在这里对bean对象依赖的属性对象进行获取getBean,也就同样走到了获取bean对象的流程中;
对于循环引用的流程可以分为下面几个步骤:
- 先实例化A对象,并且将A对象的factory放入三级缓存中(目的在于延迟对实例化阶段生成的对象的代理,只有真正发生循环依赖的时候,才去提前生成代理对象,否则只会创建一个工厂并将其放入到三级缓存中,但是不会去通过这个工厂去真正创建对象)
- A对象进行填充属性
- 加载B对象,B对象进行实例化并放入三级缓存中
- B对象进行填充属性,获取到A对象的三级缓存然后添加到二级缓存中
- B对象完成初始化
- A对象完成初始化然后添加到一级缓存中
- @DependsOn
@DependsOn和depends-on标签可以指定bean的初始化的先后顺序,也是在doGetBean方法中进行处理的
// 判断是否通过标签<depends-on>或@DependsOn显示引入需要在提前进行初始化的对象
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
for (String dep : dependsOn) {
if (isDependent(beanName, dep)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
//注册需要提前进行初始化的bean
registerDependentBean(dep, beanName);
try {
getBean(dep);
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
}
}
}
提前初始化扩展点
- resolveBeforeInstantiation()
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
//调用resolveBeforeInstantiation
try {
// 让 BeanPostProcessor 有机会返回代理而不是目标 Bean 实例
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
} catch (Throwable ex) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
"BeanPostProcessor before instantiation of bean failed", ex);
}
}
@Nullable
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
Object bean = null;
if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
// Make sure bean class is actually resolved at this point.
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
//确定目标类型
Class<?> targetType = determineTargetType(beanName, mbd);
if (targetType != null) {
//在实例化之前应用 Bean 后处理器
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
if (bean != null) {
//初始化后应用 Bean 后处理器
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
}
mbd.beforeInstantiationResolved = (bean != null);
}
return bean;
}
@Nullable
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
Object result = bp.postProcessBeforeInstantiation(beanClass, beanName);
if (result != null) {
return result;
}
}
return null;
}
在这一步骤中可以看到applyBeanPostProcessorsBeforeInstantiation方法尝试执行所有InstantiationAwareBeanPostProcessor的postProcessBeforeInstantiation方法,用于提前方法bean对象,然后在执行applyBeanPostProcessorsAfterInitialization后置处理器;
执行初始化前置扩展点
- applyBeanPostProcessorsBeforeInitialization
@Override
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor.postProcessBeforeInitialization(result, beanName);//ref.1
if (current == null) {
return result;
}
result = current;
}
return result;
}
public List<BeanPostProcessor> getBeanPostProcessors() {
return this.beanPostProcessors;
}
其中this.beanPostProcessors是通过refresh() -> registerBeanPostProcessors(beanFactory) -> registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors) -> ((AbstractBeanFactory) beanFactory).addBeanPostProcessors(postProcessors) ->this.beanPostProcessors.addAll(beanPostProcessors)来进行设置的;
可以看到在ref处执行了postProcessBeforeInitialization方法,spring提供这个扩展点是为了在对象在初始化的前提供属性注入的方法;
执行初始化
- invokeInitMethods
protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBeanDefinition mbd)
throws Throwable {
//执行InitializingBean方法
boolean isInitializingBean = (bean instanceof InitializingBean); //ref.1
if (isInitializingBean && (mbd == null || !mbd.hasAnyExternallyManagedInitMethod("afterPropertiesSet"))) {
if (logger.isTraceEnabled()) {
logger.trace("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
}
((InitializingBean) bean).afterPropertiesSet();
}
if (mbd != null && bean.getClass() != NullBean.class) {
//获取init-method
String[] initMethodNames = mbd.getInitMethodNames(); //ref.2
if (initMethodNames != null) {
for (String initMethodName : initMethodNames) {
if (StringUtils.hasLength(initMethodName) &&
!(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
!mbd.hasAnyExternallyManagedInitMethod(initMethodName)) {
invokeCustomInitMethod(beanName, bean, mbd, initMethodName);
}
}
}
}
}
在ref.1处是执行执行InitializingBean.afterPropertiesSet(),这个方法主要是用来在执行检查属性是否填充完成的;
在ref.2处是执行init-method方法的;
执行初始化后置扩展点
- applyBeanPostProcessorsAfterInitialization
@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor.postProcessAfterInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
这个方法与applyBeanPostProcessorsBeforeInitialization方法的执行逻辑类似;
总结
普通Bean对象的生命周期可以划分为以下几个阶段:实例化 -> 属性填充 -> 初始化 -> 使用 -> 销毁,这几个流程中涉及到的扩展点如下所示;
-
实例化
InstantiationAwareBeanPostProcessor.以下方法
postProcessBeforeInstantiation:实例化bean之前,相当于new这个bean之前
postProcessAfterInstantiation:实例化bean之后,相当于new这个bean之后
postProcessPropertyValues:bean已经实例化完成,在属性注入时阶段触发,@Autowired,@Resource等注解原理基于此方法实现
postProcessBeforeInitialization:初始化bean之前,相当于把bean注入spring上下文之前
postProcessAfterInitialization:初始化bean之后,相当于把bean注入spring上下文之后 -
属性填充
BeanFactoryAware.setBeanFactory方法可在注入属性之前,也就是Setter之前拿到Bean对象;
- 初始化
@PostConstruct
InitializingBean