普通bean对象的初始化流程


普通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

上面的流程稍微复杂一点,化繁为简来看有几个总要的步骤:

  1. 调用入口方法:finishBeanFactoryInitialization()
  2. 循环依赖处理:AbstractBeanFactory.doGetBean()
  3. 提前初始化扩展点:resolveBeforeInstantiation()
  4. 执行初始化前置扩展点:applyBeanPostProcessorsBeforeInitialization()
  5. 执行初始化:invokeInitMethods()
  6. 执行初始化后置扩展点: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个实现类,分别是LocalContainerEntityManagerFactoryBeanDefaultPersistenceUnitManagerAspectJWeavingEnabler;

LoadTimeWeaverAware

在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对象添加到singletonObjectsregisteredSingletons,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对象的流程中;

对于循环引用的流程可以分为下面几个步骤:

  1. 先实例化A对象,并且将A对象的factory放入三级缓存中(目的在于延迟对实例化阶段生成的对象的代理,只有真正发生循环依赖的时候,才去提前生成代理对象,否则只会创建一个工厂并将其放入到三级缓存中,但是不会去通过这个工厂去真正创建对象)
  2. A对象进行填充属性
  3. 加载B对象,B对象进行实例化并放入三级缓存中
  4. B对象进行填充属性,获取到A对象的三级缓存然后添加到二级缓存中
  5. B对象完成初始化
  6. 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

参考资料

Spring AOP源码解读1 - 程序入口
Spring源码分析之Bean的加载


  TOC