在spring源码分析加载bean总览中对加载bean进行了总体分析,主要是对非延迟加载bean流程的关键点分析,本文将对每个关键点进行详细分析,体现在AbstractBeanFactory->doGetBean方法中的主要关键点进行代码分析,笔者如有分析错误,还请及时指出。
String beanName = transformedBeanName(name);
transformedBeanName方法负责将普通bean的别名或去除工厂bean的前缀转化为beanName。
(1)BeanFactoryUtils.transformedBeanName方法是去除FactoryBean类型的bean的前缀“&”,里面有do…while循环保证beanName前缀无“&”;
(2)canonicalName方法是将bean中配置的别名转化为实际的beanName,也是采用do…while循环进行获取。
transformedBeanName代码如下:
protected String transformedBeanName(String name) {
//上述(1)、(2)点具体代码执行点
return canonicalName(BeanFactoryUtils.transformedBeanName(name));
}
BeanFactoryUtils工具类进行封装去除“&”,具体代码如下:
public static String transformedBeanName(String name) {
if (!name.startsWith(BeanFactory.FACTORY_BEAN_PREFIX)) {//检查是否是"&"开头的beanName
return name;
}
//使用并发map作为缓存,transformedBeanNameCache中进行do...while进行截取
return transformedBeanNameCache.computeIfAbsent(name, beanName -> {
do {
beanName = beanName.substring(BeanFactory.FACTORY_BEAN_PREFIX.length());
} while (beanName.startsWith(BeanFactory.FACTORY_BEAN_PREFIX));
return beanName;
});
}
别名转换委托给SimpleAliasRegistry类canonicalName来进行转换,代码如下:
public String canonicalName(String name) {
String canonicalName = name;
String resolvedName;
//链式转换,一直寻找到最顶级的beanName,在生成BeanDefinition时,最顶级的beanName是在第一位
do {
resolvedName = this.aliasMap.get(canonicalName);
if (resolvedName != null) {
canonicalName = resolvedName;
}
} while (resolvedName != null);
return canonicalName;
}
Object sharedInstance = getSingleton(beanName);
Spring中对于单例的bean是采用三个缓存分别来实现bean的管理,一级缓存(singletonObjects)、二级缓存(earlySingletonObjects)、三级缓存(singletonFactories)。
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
三种缓存作用如下:
(1)一级缓存singletonObjects主要是存储spring中一些实例化完成好的bean,也是常说的IOC容器,实际上就是一个并发map;
(2)二级缓存earlySingletonObjects主要是存储提前暴露的,未完成好的bean,如循环依赖时属性未注入时的bean;
(3)三级缓存singletonFactories主要是为了解决循环依赖,保存一些bean的创建单例时的ObjectFactory,用于获得bean。
getSingleton方法是委托DefaultSingletonBeanRegistry类来实现,默认支持单例循环依赖,具体代码如下:
public Object getSingleton(String beanName) {
return getSingleton(beanName, true);//支持bean的循环依赖
}
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
//从一级缓存中先尝试获取bean
Object singletonObject = this.singletonObjects.get(beanName);
//判断是否已从一级缓存中获取到bean和单例bean检查
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
synchronized (this.singletonObjects) {//添加内置锁synchronized并发
//在一级缓存中未获得bean时,再从二级缓存中获取提前暴露bean
singletonObject = this.earlySingletonObjects.get(beanName);
//二级缓存中是否获得到bean和是否支持循环依赖
if (singletonObject == null && allowEarlyReference) {
//从三级缓存中尝试获取bean的Factory
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
//调用ObjectFactory中getObject方法来得到bean
singletonObject = singletonFactory.getObject();
//将得到的半成品bean放置到二级缓存
this.earlySingletonObjects.put(beanName, singletonObject);
//从三级缓存中移除创建bean的Factory,A和B互相依赖A->B时,三级缓存将A将自身放入,等创建B时直接获取A并将其移除
this.singletonFactories.remove(beanName);
}
}
}
}
return singletonObject;
}
自定义容器与spring的AbstractBeanFactory递归获取bean,父类容器中获取bean即AbstractBeanFactory中的doGetBean,此处其实是防止自定义容器实现doGetBean中未找到则在AbstractBeanFactory容器中再次获取,代码如下:
BeanFactory parentBeanFactory = getParentBeanFactory();//获取父类容器
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
//获取beanName,此处与transformedBeanName获取beanName不同,会返回普通bean和工厂bean的beanName
String nameToLookup = originalBeanName(name);
if (parentBeanFactory instanceof AbstractBeanFactory) {
/**
* 父类容器中获取bean即AbstractBeanFactory中的doGetBean,此处其实是防止自定义容器实现doGetBean中未找到
* 则在AbstractBeanFactory容器中再次获取
*/
return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
nameToLookup, requiredType, args, typeCheckOnly);
} else if (args != null) {
// 有参数args时则委托给父类容器获取bean
return (T) parentBeanFactory.getBean(nameToLookup, args);
} else if (requiredType != null) {
// 无参数时且requiredType不为空也委托给父类容器获取bean
return parentBeanFactory.getBean(nameToLookup, requiredType);
} else {
//不满足上述if和else if条件时则默认使用父类容器获取bean
return (T) parentBeanFactory.getBean(nameToLookup);
}
}
private final Set<String> alreadyCreated = Collections.newSetFromMap(new ConcurrentHashMap<>(256));
spring在创建bean前会处理下该bean是否允许重复创建即合并覆盖原有的bean,使用alreadyCreated变量(Set)存储防止重复,代码如下:
protected void markBeanAsCreated(String beanName) {
if (!this.alreadyCreated.contains(beanName)) {
synchronized (this.mergedBeanDefinitions) {
if (!this.alreadyCreated.contains(beanName)) {//该beanName未被创建过
clearMergedBeanDefinition(beanName);//将BeanDefinition中的stale设置为true,代表允许再次创建
this.alreadyCreated.add(beanName);//将其加入到已创建过集合set中即alreadyCreated
}
}
}
}
protected void clearMergedBeanDefinition(String beanName) {
RootBeanDefinition bd = this.mergedBeanDefinitions.get(beanName);
if (bd != null) {
bd.stale = true;//改变BeanDefinition中stale值,可以合并创建
}
}
isDependent方法检查该bean是否有循环依赖,如果存在相互先实例化的关系则抛出异常,此处的depend-on属性中是指当前bean实例化之前必须先实例化该属性值中bean,与我们常说的循环依赖是不一样的,该处仅仅是检查该bean必须在另一个bean实例化的前面,可以被注入也可以不被注入。
具体代码如下:
private boolean isDependent(String beanName, String dependentBeanName, @Nullable Set<String> alreadySeen) {
if (alreadySeen != null && alreadySeen.contains(beanName)) {
return false;
}
//规范化bean,此处仅仅是别名转换,无FactoryBean的前缀去除
String canonicalName = canonicalName(beanName);
//依赖集合中获取是否存在先后实例化的关系
Set<String> dependentBeans = this.dependentBeanMap.get(canonicalName);
if (dependentBeans == null) {
return false;
}
if (dependentBeans.contains(dependentBeanName)) {
return true;
}
for (String transitiveDependency : dependentBeans) {
if (alreadySeen == null) {
alreadySeen = new HashSet<>();
}
alreadySeen.add(beanName);
//递归检测是否依赖中还存在依赖
if (isDependent(transitiveDependency, dependentBeanName, alreadySeen)) {
return true;
}
}
return false;
}
单例bean创建是getSingleton重载方法且传入的是lamda表达式传入,而创建prototype、request或session作用域bean的时候,是直接调用createBean方法,具体代码如下:
protected Object createBean(String beanName,RootBeanDefinition mbd,Object[] args)
throws BeanCreationException {
RootBeanDefinition mbdToUse = mbd;
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);//返回bean的class类型
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
try {
//预处理方法覆盖的方法,lookup-method和replaced-method两个属性
mbdToUse.prepareMethodOverrides();
} catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
beanName, "Validation of method overrides failed", ex);
}
try {
/**
* 实例化前的后置处理器InstantiationAwareBeanPostProcessor和初始化后的后置处理器BeanPostProcessor
* 分别对应postProcessBeforeInstantiation后置方法和postProcessAfterInitialization后置方法
*/
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);
}
try {
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
return beanInstance;
} catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
throw ex;
} catch (Throwable ex) {
throw new BeanCreationException(
mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
}
}
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
Object bean = null;
//检测该bean是否有实例化后置处理器
if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
//验证bean是否实际已经被解析完成
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
//验证BeanDefinition中的类型和目标类型是否匹配
Class<?> targetType = determineTargetType(beanName, mbd);
if (targetType != null) {
//实例化前的后置处理器InstantiationAwareBeanPostProcessor->postProcessBeforeInstantiation后置方法
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
if (bean != null) {
//BeanPostProcessor->postProcessAfterInitialization后置方法
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
}
mbd.beforeInstantiationResolved = (bean != null);//将bean实例化成功或失败的结果重新赋值
}
return bean;
}
bean只要实现了InstantiationAwareBeanPostProcessor后置处理器,那么在加载bean的过程中,所有bean都会被执行实例化前postProcessBeforeInstantiation方法即用户自定义实现InstantiationAwareBeanPostProcessor时会执行该方法,如果子类重写了该方法,那么将执行子类中的方法,代码如下:
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {//获取所有后置处理器
//只处理实现了InstantiationAwareBeanPostProcessor的后置处理器
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
//执行InstantiationAwareBeanPostProcessor中的实例化前postProcessBeforeInstantiation后置方法
Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
if (result != null) {
return result;
}
}
}
return null;
}
bean只要实现了BeanPostProcessor后置处理器,那么在加载bean的过程中,所有bean都会被执行初始化后postProcessAfterInitialization方法即用户自定义实现BeanPostProcessor时会执行该方法,如果子类重写了该方法,那么将执行子类中的方法,代码如下:
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {//获取所有后置处理器
//执行BeanPostProcessor中的初始化后postProcessAfterInitialization后置方法
Object current = processor.postProcessAfterInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
createBean->resolveBeforeInstantiation方法中返回的结果如果非空,则代表已经创建了代理对象,代码不会执行doCreateBean,反之则返回一个空对象bean,此时spring知道resolveBeforeInstantiation方法中没有生成代理对象,则开始自身着手创建bean即doCreateBean方法,熟悉干实事的doXXX,代码如下:
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);//获取未实例化的bean并去除缓存
}
if (instanceWrapper == null) {
/**
* 缓存中未获得实例化wrapper手动创建,spring提供了三种实例化bean的方式,取决于用户指定那种实例化方式
* (1)工厂类创建
* (2)bean的类有多个构造函数,会根据参数自动匹配
* (3)spring使用默认的无参构造函数实例化
*/
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
Object bean = instanceWrapper.getWrappedInstance();//实例化bean
Class<?> beanType = instanceWrapper.getWrappedClass();//获取class对象
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
//与上述实例化前和初始化后的后置处理器模式类似
//此处是执行MergedBeanDefinitionPostProcessor后置处理器中的postProcessMergedBeanDefinition后置方法
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
} catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing of merged bean definition failed", ex);
}
mbd.postProcessed = true;
}
}
//提前暴露未完整的bean,主要是处理当前正在创建的bean且存在循环依赖时,将自身放入三级缓存中,解决循环依赖
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));
}
Object exposedObject = bean;
try {
//属性注入,前面实例化的bean进行属性填充,请关注后续文章
populateBean(beanName, mbd, instanceWrapper);
//执行一些后置处理器如BeanNameAware、BeanFactoryAware等Aware后置方法调用
exposedObject = initializeBean(beanName, exposedObject, mbd);
} catch (Throwable ex) {
if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
throw (BeanCreationException) ex;
} else {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
}
}
//earlySingletonExposure根据执行的逻辑判断循环依赖是否需要检查
if (earlySingletonExposure) {
//从getSingleton中获取bean,false代表不从三级缓存中获得,此处只从一级和二级缓存获取
Object earlySingletonReference = getSingleton(beanName, false);
if (earlySingletonReference != null) {//判断是否存在,如果不为空则代表有循环依赖
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
} else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {//是否存在已经被其他bean依赖注入过
String[] dependentBeans = getDependentBeans(beanName);//获取依赖
Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
for (String dependentBean : dependentBeans) {
if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {//删除仅仅用于类型检查的依赖
actualDependentBeans.add(dependentBean);//删除失败则代表有除了类型检查以外的其他用途,此时需要记录下来
}
}
//actualDependentBeans有值,代表上述for循环中发现bean已被用于其他用途,循环依赖检查抛出异常
if (!actualDependentBeans.isEmpty()) {
throw new BeanCurrentlyInCreationException(beanName,
"Bean with name '" + beanName + "' has been injected into other beans [" +
StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
"] in its raw version as part of a circular reference, but has eventually been " +
"wrapped. This means that said other beans do not use the final version of the " +
"bean. This is often the result of over-eager type matching - consider using " +
"'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.");
}
}
}
}
try {
//对于是否配置bean的destory-method方法进行处理,注册时将销毁方法也注册进去,如果没有配置则使用spring默认的销毁方法
registerDisposableBeanIfNecessary(beanName, bean, mbd);
} catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
}
getObjectForBeanInstance方法在doGetBean中被多次调用,主要是从缓存中、spring手动创建并返回实例后再次被调用,用于检测该bean的引用是FactoryBean或普通bean实例,如果是工厂bean,则需要调用工厂bean的getObject,返回bean的实例,代码如下:
protected Object getObjectForBeanInstance(Object beanInstance,String name,String beanName,RootBeanDefinition mbd) {
//检查name是否是自带“&”的工厂bean
if (BeanFactoryUtils.isFactoryDereference(name)) {
if (beanInstance instanceof NullBean) {
return beanInstance;
}
if (!(beanInstance instanceof FactoryBean)) {
throw new BeanIsNotAFactoryException(beanName, beanInstance.getClass());
}
if (mbd != null) {
mbd.isFactoryBean = true;
}
return beanInstance;
}
// beanInstance判断是普通bean则直接返回
if (!(beanInstance instanceof FactoryBean)) {
return beanInstance;
}
Object object = null;
if (mbd != null) {
mbd.isFactoryBean = true;
} else {
object = getCachedObjectForFactoryBean(beanName);//从缓存中获取
}
if (object == null) {
FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
if (mbd == null && containsBeanDefinition(beanName)) {
mbd = getMergedLocalBeanDefinition(beanName);
}
boolean synthetic = (mbd != null && mbd.isSynthetic());
//若object为空则从FactoryBean的引用中调用getObject获得bean实例
object = getObjectFromFactoryBean(factory, beanName, !synthetic);
}
return object;
}