Spring IoC容器的初始化,主要分为三段
-
启动容器,扫描指定包路径下的Bean,封装BeanDefinition
启动容器的三种方式:ClassPathXmlApplicationContext、AnnotationConfigApplicationContext、FileSystemXmlApplicationContext; 分别会走不同的扫描方式,最终完成BeanDefinition的封装。
装配BeanFactory
根据SpringBean的生命周期中定义的创建流程,创建Bean对象。无论以哪一种方式启动容器,最终都会交由AbstractApplicationContext类执行refresh方法进行Bean对象的创建
循环依赖
在Spring容器的初始化过程中,绕不开2个及以上Bean对象的相互依赖问题,Spring称之为循环依赖(circular references)
三级缓存
Spring对于循环依赖问题,提供了使用三级缓存的解决策略。分别为
- singletonFactories:三级缓存,存放的是ObjectFactory,注意此处存放的不是bean对象,而是生成bean对象的factory对象。
- earlySingletonObjects:二级缓存,存放的是由三级缓存中ObjectFactory对象执行getObject方法生成的代理对象,完成Spring通过动态代理的方式,对bean中的方法实现增强。此时该代理对象尚未开始属性注入。
- singletonObjects:一级缓存,即最终Spring容器中的单例池,存放最终完成所有属性注入的完整bean对象。
值得注意的是:Spring在初始化Bean的过程中,并不能预先确认该Bean是否存在循环依赖的情况。因此所有Bean对象(无论有无循环依赖),在被实例化之后,属性注入之前,都会被放入三级缓存singletonFactories中,走相同的初始化流程。
为什么要使用三级缓存
看了一些关于三级缓存的博客,大部分都有描述这个问题。简单回答:需要遵守设计的“单一原则”,各级缓存各司其职。
这又衍生出另一个问题:第三级缓存的存在,到底在设计上有何优雅或者必要之处?
实际上这个三级缓存中的ObjectFactory会在Bean对象第一次属性依赖(注意不一定是循环依赖的情况)注入时,就执行它的getObject方法,获取增强后的代理对象,放入二级缓存中;此后,在每一次循环依赖属性注入时,都会从二级缓存中取得代理对象进行注入。也就是说,如果根本就没有三级缓存,直接执行掉ObjectFactory.getObject方法里的操作,获取代理对象后放入二级缓存中。理论上也是可以的,这样似乎三级缓存就没必要了?不用怀疑ObjectFactory.getObject里的操作的执行时机问题,里面只是一些纯粹的增强。
下图是源码追踪Spring解决循环依赖问题的时序图,也是Spring Bean初始化与属性注入的大致流程:
以下源码分析的过程,对不关注的代码进行了删减
通过ClassPathXmlApplicationContext启动容器:
public ClassPathXmlApplicationContext(
String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
throws BeansException {
super(parent);
// sy 扫描配置文件,封装BeanDefinition对象 -- 所有的启动方式在构造函数中,都会先走配置扫描,做BeanDefinition封装。
// 之后统一走AbstractApplicationContext:refresh();进行容器初始化
// ClassPathXmlApplicationContext:setConfigLocations(configLocations);
// FileSystemXmlApplicationContext:setConfigLocations(configLocations);
// AnnotationConfigApplicationContext(Class>... componentClasses):register(componentClasses);
// AnnotationConfigApplicationContext(String... basePackages):scan(basePackages);
// -- AbstractApplicationContext:refresh();
setConfigLocations(configLocations);
if (refresh) {
// sy 初始化IoC容器
refresh();
}
}
ClassPathXmlApplicationContext的构造函数最终走AbstractApplicationContext.refresh方法,完成BeanFactory与Bean的建立
AbstractApplicationContext#refresh
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
// sy 获取BeanFactory
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
// sy 预装配BeanFactory
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
// sy 模板方法
postProcessBeanFactory(beanFactory);
// Invoke factory processors registered as beans in the context.
// sy 设置工程中实现的BeanFactoryPostProcessors并执行postProcessBeanFactory方法
// 最终通过DefaultListableBeanFactory.doGetBeanNamesForType遍历beanDefinitionNames获取BeanFactoryPostProcessors。
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
// sy 注册BeanPostProcessors
// 调用时机:Bean实例化 -> Bean对象属性注入 -> BeanNameAware.setBeanName -> BeanFactoryAware.setBeanFactory -> ApplicationContextAware.setApplicationContext
// -> **** BeanPostProcessor.postProcessBeforeInitialization ****
// -> InitializingBean.afterPropertiesSet -> 调用xml定制的init-method方法或者Bean中用@PostConstruct注解的方法
// -> **** BeanPostProcessor.postProcessAfterInitialization ****
// -> Singleton:放入单例池中,由Spring容器管理; Prototype:交给调用者,由JVM管理
registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
// sy 国际化
initMessageSource();
// Initialize event multicaster for this context.
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
onRefresh();
// Check for listener beans and register them.
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
// sy 最终完成IoC注入的调用
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
finishRefresh();
}
catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
// Destroy already created singletons to avoid dangling resources.
destroyBeans();
// Reset 'active' flag.
cancelRefresh(ex);
// Propagate exception to caller.
throw ex;
}
finally {
// Reset common introspection caches in Spring's core, since we
// might not ever need metadata for singleton beans anymore...
resetCommonCaches();
}
}
}
执行AbstractApplicationContext#finishBeanFactoryInitialization
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// 初始化Bean
beanFactory.preInstantiateSingletons();
}
执行DefaultListableBeanFactory#preInstantiateSingletons
public void preInstantiateSingletons() throws BeansException {
if (logger.isTraceEnabled()) {
logger.trace("Pre-instantiating singletons in " + this);
}
// Iterate over a copy to allow for init methods which in turn register new bean definitions.
// While this may not be part of the regular factory bootstrap, it does otherwise work fine.
List beanNames = new ArrayList<>(this.beanDefinitionNames);
// Trigger initialization of all non-lazy singleton beans...
// sy 通过遍历封装完毕的BeanDefinition,逐一创建Spring Bean
for (String beanName : beanNames) {
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
if (isFactoryBean(beanName)) {
// sy 处理FactoryBean
// 从容器中获取FactoryBean时,使用"&"+beanName的原因
Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
if (bean instanceof FactoryBean) {
final FactoryBean> factory = (FactoryBean>) bean;
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged((PrivilegedAction)
((SmartFactoryBean>) factory)::isEagerInit,
getAccessControlContext());
}
else {
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean>) factory).isEagerInit());
}
if (isEagerInit) {
// sy 初始化bean
getBean(beanName);
}
}
}
else {
// sy 初始化bean
getBean(beanName);
}
}
}
// Trigger post-initialization callback for all applicable beans...
for (String beanName : beanNames) {
// 逐一从一级缓存、二级缓存、三级缓存中获取实例化对象
Object singletonInstance = getSingleton(beanName);
// 对单例bean对象的后置增强
if (singletonInstance instanceof SmartInitializingSingleton) {
final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction
执行AbstractBeanFactory#getBean -> 调用内部AbstractBeanFactory#doGetBean方法
protected T doGetBean(final String name, @Nullable final Class requiredType,
@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
final String beanName = transformedBeanName(name);
Object bean;
// Eagerly check singleton cache for manually registered singletons.
// sy 依次从一级缓存、二级缓存、三级缓存中获取bean对象
Object sharedInstance = getSingleton(beanName);
// sy 如果已获得bean且其无参构造
if (sharedInstance != null && args == null) {
if (logger.isTraceEnabled()) {
if (isSingletonCurrentlyInCreation(beanName)) {
logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +
"' that is not fully initialized yet - a consequence of a circular reference");
}
else {
logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
}
}
// sy 处理factoryBean的情况
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
else {
// Fail if we're already creating this bean instance:
// We're assumably within a circular reference.
// sy 如果当前的bean的scope为prototype,则抛出异常,prototype类型的bean不应该在初始化阶段生成
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
// Check if bean definition exists in this factory.
// sy 根据得到的BeanFactory做getBean递归
BeanFactory parentBeanFactory = getParentBeanFactory();
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// Not found -> check parent.
String nameToLookup = originalBeanName(name);
if (parentBeanFactory instanceof AbstractBeanFactory) {
return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
nameToLookup, requiredType, args, typeCheckOnly);
}
}
try {
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);
// Guarantee initialization of beans that the current bean depends on.
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
for (String dep : dependsOn) {
registerDependentBean(dep, beanName);
try {
// sy 递归创建依赖对象
getBean(dep);
}
}
}
// Create bean instance.
if (mbd.isSingleton()) {
// sy 看命名应该能明白,该方法最终返回了一个singleton的bean对象,即存放在singletonObjects(一级缓存单例池中的对象)
sharedInstance = getSingleton(beanName, () -> {
try {
// sy 最终创建bean代理对象的地方
return createBean(beanName, mbd, args);
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
}
}
return (T) bean;
}
如果能使用DefaultListableBeanFactory#preInstantiateSingletons.getSingleton方法从缓存中得到bean,则之前已走过实例化流程。该方法很关键:
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
Object singletonObject = this.singletonObjects.get(beanName);
// sy 如果对象不在单例池singletonObjects(一级缓存)中
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
synchronized (this.singletonObjects) {
singletonObject = this.earlySingletonObjects.get(beanName);
// sy 如果对象不在二级缓存earlySingletonObjects中
if (singletonObject == null && allowEarlyReference) {
// sy 从三级缓存singletonFactories中获取中获取ObjectFactory
// 注意三级缓存singletonFactories中存放的是ObjectFactory,并不是bean对象,即此时没有生成bean的代理对象
ObjectFactory> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
// sy 通过匿名内部类实现ObjectFactory接口的getObject,创建Bean对象
// addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
singletonObject = singletonFactory.getObject();
// sy 将生成的Bean对象放入二级缓存中
this.earlySingletonObjects.put(beanName, singletonObject);
// sy 从一级缓存中移除使用beanName标记的ObjectFactory
this.singletonFactories.remove(beanName);
}
}
}
}
return singletonObject;
}
如果从缓存中获取不到bean,说明该Bean对象尚未进行实例化,走org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#getSingleton方法:
public Object getSingleton(String beanName, ObjectFactory> singletonFactory) {
synchronized (this.singletonObjects) {
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
beforeSingletonCreation(beanName);
boolean newSingleton = false;
boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
if (recordSuppressedExceptions) {
this.suppressedExceptions = new LinkedHashSet<>();
}
try {
// sy 执行beanFactory的getObject方法即:
// () -> {
// try {
// // sy 最终创建bean代理对象的地方(org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean)
// return createBean(beanName, mbd, args);
// }
// catch (BeansException ex) {
// // Explicitly remove instance from singleton cache: It might have been put there
// // eagerly by the creation process, to allow for circular reference resolution.
// // Also remove any beans that received a temporary reference to the bean.
// destroySingleton(beanName);
// throw ex;
// }
// }
// 创建最终完成增强的完整的singleton代理对象
// 并在下方执行addSingleton(beanName, singletonObject),将其放进单例缓存池中,并将其从三级、二级缓存中删除
singletonObject = singletonFactory.getObject();
newSingleton = true;
}
finally {
if (recordSuppressedExceptions) {
this.suppressedExceptions = null;
}
afterSingletonCreation(beanName);
}
if (newSingleton) {
// sy 将初始化完成的bean对象放入单例池中
addSingleton(beanName, singletonObject);
}
}
return singletonObject;
}
}
由singletonObject = singletonFactory.getObject()执行org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean方法:这里删除了异常处理的代码,主要关注2个方法:resolveBeforeInstantiation、doCreateBean(最终创建Bean对象)
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
RootBeanDefinition mbdToUse = mbd;
try {
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
// sy 听名字有点疑惑,
// 设置BeanPostProcessors的postProcessBeforeInitialization,postProcessAfterInitialization。
// 这样似乎说明会在Bean依赖注入完毕就立马执行BeanPostProcessor ?
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
}
try {
// sy 创建bean对象
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
return beanInstance;
}
}
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean这个方法做了3件事:
-
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean))
将ObjectFactory加入三级缓存中
-
populateBean(beanName, mbd, instanceWrapper)
进行属性注入
-
exposedObject = initializeBean(beanName, exposedObject, mbd)
在bean装配完成后,执行BeanPostProcessor与init-method
源码详解:
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
// Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
// sy factoryBeanInstanceCache.put前会将beanName做一步createBeanInstance
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
// sy 如果为空说明当前尚未创建过Bean对象
if (instanceWrapper == null) {
// sy 最终都会走createBeanInstance方法去实例化对象,仅仅只是实例化原生对象,尚未对bean对象进行属性注入,也未生成代理对象且增强
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
final Object bean = instanceWrapper.getWrappedInstance();
Class> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
// Allow post-processors to modify the merged bean definition.
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
mbd.postProcessed = true;
}
}
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
// sy 在bean实例化之后,将其BeanFactory:() -> getEarlyBeanReference(beanName, mbd, bean)放入三级缓存中,
// 可解决循环依赖问题(默认开启允许循环依赖:this.allowCircularReferences的默认值为true)
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
// Initialize the bean instance.
Object exposedObject = bean;
try {
// sy 为bean对象执行属性注入。
populateBean(beanName, mbd, instanceWrapper);
// sy 在bean装配完成后,执行BeanPostProcessor与init-method
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
// sy 如果在二级缓存中
if (earlySingletonExposure) {
Object earlySingletonReference = getSingleton(beanName, false);
if (earlySingletonReference != null) {
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
}
else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
String[] dependentBeans = getDependentBeans(beanName);
Set actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
for (String dependentBean : dependentBeans) {
if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
actualDependentBeans.add(dependentBean);
}
}
}
}
}
// Register bean as disposable.
try {
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
return exposedObject;
}
重点关注属性装配:org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#populateBean:
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
// 前面做了一系列处理去获取pvs:propertyValues
if (pvs != null) {
// sy 解决@AutoWired注入
applyPropertyValues(beanName, mbd, bw, pvs);
}
}
最终调用了org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyPropertyValues:
这里面主要做了2件事
-
Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);
通过调用BeanDefinitionValueResolver.resolveValueIfNecessary获取该属性的值
-
bw.setPropertyValues(new MutablePropertyValues(deepCopy));
通过BeanWrapper.setPropertyValues方法将获取的属性值,注入到属性对象中。内部使用了PropertyAccessor(属性存取器)做了一些处理,最终在org.springframework.beans.BeanWrapperImpl.BeanPropertyHandler#setValue方法中使用反射进行属性值注入:
public void setValue(final @Nullable Object value) throws Exception { final Method writeMethod = (this.pd instanceof GenericTypeAwarePropertyDescriptor ? ((GenericTypeAwarePropertyDescriptor) this.pd).getWriteMethodForActualAccess() : this.pd.getWriteMethod()); if (System.getSecurityManager() != null) { AccessController.doPrivileged((PrivilegedAction
最终该方法的源码详情:
protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
if (pvs.isEmpty()) {
return;
}
BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter);
// Create a deep copy, resolving any references for values.
List deepCopy = new ArrayList<>(original.size());
boolean resolveNecessary = false;
for (PropertyValue pv : original) {
if (pv.isConverted()) {
deepCopy.add(pv);
}
else {
String propertyName = pv.getName();
Object originalValue = pv.getValue();
// sy 处理property的注入值
Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);
Object convertedValue = resolvedValue;
boolean convertible = bw.isWritableProperty(propertyName) &&
!PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName);
if (convertible) {
convertedValue = convertForProperty(resolvedValue, propertyName, bw, converter);
}
if (resolvedValue == originalValue) {
if (convertible) {
pv.setConvertedValue(convertedValue);
}
deepCopy.add(pv);
}
}
}
// Set our (possibly massaged) deep copy.
try {
// sy 将获取的属性值,通过反射注入到属性对象中
bw.setPropertyValues(new MutablePropertyValues(deepCopy));
}
}
进入org.springframework.beans.factory.support.BeanDefinitionValueResolver#resolveValueIfNecessary方法:
public Object resolveValueIfNecessary(Object argName, @Nullable Object value) {
// 这方法其实东西挺多的,处理的情况也比较多。大部分直接会走第一个if条件,就不看其他的了
if (value instanceof RuntimeBeanReference) {
RuntimeBeanReference ref = (RuntimeBeanReference) value;
// sy 处理引用(即对象引用)
return resolveReference(argName, ref);
}
}
进入org.springframework.beans.factory.support.BeanDefinitionValueResolver#resolveReference方法:
这个方法很关键,是下一轮递归的入口:
private Object resolveReference(Object argName, RuntimeBeanReference ref) {
try {
Object bean;
String refName = ref.getBeanName();
refName = String.valueOf(doEvaluate(refName));
if (ref.isToParent()) {
bean = this.beanFactory.getParentBeanFactory().getBean(refName);
}
else {
// sy 很熟悉吧。又回到了最初的getBean,算是一种递归吧。
// 递归结束的条件即在getBean方法中从三级到一级缓存内获取到了bean对象。此时该bean对象即增强后的代理对象了。
// 如果在缓存内未取得bean对象,则继续向下递归,若取得,则向上回归
bean = this.beanFactory.getBean(refName);
this.beanFactory.registerDependentBean(refName, this.beanName);
}
return bean;
}
}
最终在最后一层递归完成,向上回归到第一次getBean方法内的getSingleton方法中,从一级缓存(单例池)中获取完整对象后,实例化完成。