在上节文章 ApplicationContext refresh 刷新 中我们学习了Spring启动是如何将所有的bean实例化并加载的,其中我们只分析到了Spring将bean的定义转换为 BeanDefinition,并注册到 BeanFactory 中,后续的bean的实例化和初始化(bean的加载)我们没有讲解,我们将 bean 的实例化和初始化称之为 bean 的加载,本文将从 BeanFactory 的 getBean 方法分析开始,通过源码来解读Spring是如何将 BeanDefinition 实例化成 bean?又是如何初始化bean的?
bean 的加载是从 BeanFactory 的 getBean 方法开始的,我们先看一下 BeanFactory 接口,源码如下:
public interface BeanFactory {
/**
* Used to dereference a {@link FactoryBean} instance and distinguish it from
* beans created by the FactoryBean. For example, if the bean named
* {@code myJndiObject} is a FactoryBean, getting {@code &myJndiObject}
* will return the factory, not the instance returned by the factory.
*/
// FactoryBean 名称的前缀
// 如果bean是一个 FactoryBean,名字是 name,则 getBean("&name") 获取的是 Factory,而不是其 实例bean
String FACTORY_BEAN_PREFIX = "&";
// 获取指定名称的实例bean
Object getBean(String name) throws BeansException;
// 获取指定名称和指定类型的实例bean
T getBean(String name, Class requiredType) throws BeansException;
// 获取指定名称和指定参数的实例bean
Object getBean(String name, Object... args) throws BeansException;
// 获取指定类型的实例bean
T getBean(Class requiredType) throws BeansException;
// 获取指定类型和指定参数的实例bean
T getBean(Class requiredType, Object... args) throws BeansException;
// ......其他省略方法
}
BeanFactory 接口中的 getBean 方法是在 AbstractBeanFactory 类中实现的,如下图:
下面我们从 AbstractBeanFactory 的 getBean 方法分析开始,源码如下:
// 1、AbstractBeanFactory 的 getBean 方法
@Override
public Object getBean(String name) throws BeansException {
// 调用 doGetBean 方法获取实例bean
return doGetBean(name, null, null, false);
}
// 2、AbstractBeanFactory 的 doGetBean 方法
@SuppressWarnings("unchecked")
protected T doGetBean(final String name, @Nullable final Class requiredType,
@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
// 1、获取bean真实名称,这里指去除名称"&"前缀 && 将别名转换为bean原始名称
final String beanName = transformedBeanName(name);
Object bean;
// Eagerly check singleton cache for manually registered singletons.
// 2、尝试从单例缓存对象中获取bean实例
// Spring 为了解决bean的循环依赖问题,会提前暴露bean,即使bean还没有完全实例化结束,这样的话就不需要重复去实例这个bean了
Object sharedInstance = getSingleton(beanName);
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 + "'");
}
}
// 3、获取bean对应的实例,如果 sharedInstance 是 FactoryBean,则使用 FactoryBean 创建bean实例,否则的话直接返回该bean实例即可
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
else {
// Fail if we're already creating this bean instance:
// We're assumably within a circular reference.
// 4、是否存在原型bean在创建中(即原型bean存在循环依赖),Spring只处理单例bean的循环依赖问题
if (isPrototypeCurrentlyInCreation(beanName)) {
// 原型类型的bean循环依赖Spring直接抛出异常
throw new BeanCurrentlyInCreationException(beanName);
}
// Check if bean definition exists in this factory.
// 获取父类 BeanFactory
BeanFactory parentBeanFactory = getParentBeanFactory();
// 5、当前 BeanFactory 的 beanDefinitionMap 中不包含 beanName 对应的bean定义 BeanDefinition,则使用父类 BeanFactory 加载bean实例
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// Not found -> check parent.
// 获取 bean 的原始名称
String nameToLookup = originalBeanName(name);
// 使用 parentBeanFactory 获取bean实例
if (parentBeanFactory instanceof AbstractBeanFactory) {
return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
nameToLookup, requiredType, args, typeCheckOnly);
}
else if (args != null) {
// Delegation to parent with explicit args.
return (T) parentBeanFactory.getBean(nameToLookup, args);
}
else if (requiredType != null) {
// No args -> delegate to standard getBean method.
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
else {
return (T) parentBeanFactory.getBean(nameToLookup);
}
}
// 如果不是仅仅做bean的类型检查的话,那么就是在创建bean
if (!typeCheckOnly) {
// 将bean标记为已创建
markBeanAsCreated(beanName);
}
try {
// 6、获取bean的顶级父类的 bean 定义,即 RootBeanDefinition
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
// 检查 RootBeanDefinition 是否是抽象的,如果是则抛出异常
checkMergedBeanDefinition(mbd, beanName, args);
// Guarantee initialization of beans that the current bean depends on.
// 7、获取 bean 所有依赖的 bean 名称,保证所有依赖的bean被实例化
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
for (String dep : dependsOn) {
// beanName 和 dep 的依赖关系已经存在了,说明依赖的bean已经实例过了,这里直接抛出异常
if (isDependent(beanName, dep)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
// 存储 bean 的依赖关系到 dependentBeanMap 和 dependenciesForBeanMap 中
registerDependentBean(dep, beanName);
try {
// 实例化依赖bean
getBean(dep);
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
}
}
}
// Create bean instance.
// 8、单例bean实例化,依赖的bean实例化之后,就是实例化当前bean自己了
if (mbd.isSingleton()) {
// 从单例缓存对象中获取bean实例
sharedInstance = getSingleton(beanName, () -> {
try {
// 创建bean
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.
// 创建异常的话直接销毁bean
destroySingleton(beanName);
throw ex;
}
});
// 获取bean对应的实例,如果 sharedInstance 是 FactoryBean,则使用 FactoryBean 创建bean实例,否则的话直接返回该bean实例即可
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
// 8、原型bean实例化
else if (mbd.isPrototype()) {
// It's a prototype -> create a new instance.
Object prototypeInstance = null;
try {
// 缓存该原型bean到创建中的 prototypesCurrentlyInCreation 属性中
beforePrototypeCreation(beanName);
// 创建bean
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
// bean实例化好之后,从创建中的缓存中移除
afterPrototypeCreation(beanName);
}
// 获取bean对应的实例,如果 sharedInstance 是 FactoryBean,则使用 FactoryBean 创建bean实例,否则的话直接返回该bean实例即可
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
else {
// 8、自定义scope类型的bean实例化
String scopeName = mbd.getScope();
final Scope scope = this.scopes.get(scopeName);
if (scope == null) {
// 对于没有注册过的 scope 抛出异常
throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
}
try {
Object scopedInstance = scope.get(beanName, () -> {
// 缓存该scope类型的bean到创建中的 prototypesCurrentlyInCreation 属性中
beforePrototypeCreation(beanName);
try {
// 创建bean
return createBean(beanName, mbd, args);
}
finally {
// bean实例化好之后,从创建中的缓存中移除
afterPrototypeCreation(beanName);
}
});
// 获取bean对应的实例,如果 sharedInstance 是 FactoryBean,则使用 FactoryBean 创建bean实例,否则的话直接返回该bean实例即可
bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
}
catch (IllegalStateException ex) {
throw new BeanCreationException(beanName,
"Scope '" + scopeName + "' is not active for the current thread; consider " +
"defining a scoped proxy for this bean if you intend to refer to it from a singleton",
ex);
}
}
}
catch (BeansException ex) {
cleanupAfterBeanCreationFailure(beanName);
throw ex;
}
}
// Check if required type matches the type of the actual bean instance.
// 检查创建的bean实例是否是传参要求的Class类型
if (requiredType != null && !requiredType.isInstance(bean)) {
// 创建的bean实例与传参要求的Class类型不符,则使用 TypeConverter 将创建的bean实例转换为传参要求的Class类型
try {
T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
if (convertedBean == null) {
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
return convertedBean;
}
catch (TypeMismatchException ex) {
if (logger.isTraceEnabled()) {
logger.trace("Failed to convert bean '" + name + "' to required type '" +
ClassUtils.getQualifiedName(requiredType) + "'", ex);
}
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
}
// 返回创建好的 bean 实例
return (T) bean;
}
从上述代码可以看出bean的加载过程是一个相当复杂的过程,对于加载过程所涉及到的加载步骤大致如下:
1)、获取bean真实名称(transformedBeanName 方法)
这里的传入的参数name并不一定是真正的 beanName,它可能是别名,也可能是 FactoryBean,所以需要一系列的解析,解析过程大致如下:
1.1)、去除 FactoryBean 的修饰符,也就是如果 name=“&aa”,那么首先会去除 & 而使 name=“aa”
1.2)、获取指定alias所表示的最终beanName,例如别名 A 指向名称为 B 的 Bean 则 返回 B;若别名 A 指向别名 B,别名 B 又指向名称为 C 的 Bean 则返回 C
2)、尝试从单例缓存对象中获取bean实例(getSingleton 方法)
单例bean在Spring容器中只会被创建一次,后续再获取bean,就直接从单例缓存中获取了。当然这里只是尝试加载,首先尝试从 singletonObjects 缓存中加载,如果加载不成功则再次尝试从 earlySingletonObjects 中加载,如果还是加载不成功则再次尝试从 singletonFactories 中加载,为什么这样设计呢?
答案是:在创建单例Bean的时候会存在依赖注入的情况,而在创建的时候为了避免循环依赖,在Spring中创建Bean的原则就是不等bean创建完成就会将创建bean的 ObjectFactory 提早曝光加入到缓存中,一旦下一个bean创建的时候需要依赖上一个bean则直接调用 ObjectFactory 的 getObject 方法获取bean实例
3)、从 FactoryBean 中获取 bean 实例(getObjectForBeanInstance 方法)
如果得到了bean的原始状态,则需要对bean做进一步的实例化。这里有必要强调一下,缓存中记录的或者createBean 方法创建的只是最原始状态的bean,并一定是我们想要的最终的bean。举个例子,假如我们需要对 FactoryBean(工厂bean)进行处理,那么这里得到的其实是 FactoryBean 的原始状态,但是我们真正需要的是 FactoryBean 中定义的 getObject 方法返回的bean,而 getObjectForBeanInstance 方法就是完成这个工作的
4)、原型模式的依赖检查(isPrototypeCurrentlyInCreation 方法)
Spring只处理单例bean的循环依赖问题,对于原型bean循环依赖则直接抛出异常,例如:
如果存在A中有B属性,B中有A属性,那么当依赖注入的时候,就会产生A还未创建完的时候因为对于B的创建再次返回创建A,这样就造成了循环依赖,也就是 isPrototypeCurrentlyInCreation(beanName)返回 true,直接抛出 BeanCurrentlyInCreationException 异常
5)、检查父类 BeanFactory
如果当前 BeanFactory 的 beanDefinitionMap 缓存中不包含 beanName 对应的bean定义 BeanDefinition && 父类 BeanFactory 存在,则使用父类 BeanFactory 的 getBean 方法获取bean实例
6)、获取bean的顶级父类的 bean 定义,即 RootBeanDefinition(getMergedLocalBeanDefinition 方法)
因为bean有继承关系的存在,这里需要将父类bean的所有属性都合并到子类中去,然后创建出后续bean处理所需要的 RootBeanDefinition 对象
7)、依赖bean实例化
bean之间往往都是需要依赖其他很多的bean的,此时需要先加载所有依赖的bean,因此在Spring的加载顺序中,在初始化某一个bean的时候会先初始化这个bean所对应的依赖
8)、针对不同scope类型的bean进行bean的创建
在Spring中存在不同的scope,其中默认的是 singleton,其他 scope 有 prototype、request、session 和 globalSession。 Spring会根据不同的scope进行不同的创建bean策略
9)、Class类型转换
如果要求的Class类型不为空 && 创建的bean实例与传参要求的Class类型不符,则使用 TypeConverter 将创建的bean实例转换为传参要求的Class类型。在Spring中提供了各种各样的转换器,用户也可以自己扩展转换器来满足特定需求
下面分别对这上述9个步骤中某些重要步骤展开详细的源码分析
传入的参数name并不一定是真正的 beanName,这里需要转换一下,入口在 transformedBeanName 方法,源码如下:
// 1、AbstractBeanFactory 的 transformedBeanName 方法
protected String transformedBeanName(String name) {
// 调用 BeanFactoryUtils 的 transformedBeanName 方法去除name前缀"&"
// 调用 canonicalName 方法获取别名对应的bean原始名称
return canonicalName(BeanFactoryUtils.transformedBeanName(name));
}
// 2、BeanFactoryUtils 的 transformedBeanName 方法
public static String transformedBeanName(String name) {
Assert.notNull(name, "'name' must not be null");
if (!name.startsWith(BeanFactory.FACTORY_BEAN_PREFIX)) {
// 名称不是以"&"开头,直接返回name
return name;
}
// 循环去除名称的前缀"&",直到name不以"&"开头
return transformedBeanNameCache.computeIfAbsent(name, beanName -> {
do {
beanName = beanName.substring(BeanFactory.FACTORY_BEAN_PREFIX.length());
}
while (beanName.startsWith(BeanFactory.FACTORY_BEAN_PREFIX));
return beanName;
});
}
// 3、获取别名对应的bean的原始名称
public String canonicalName(String name) {
String canonicalName = name;
// Handle aliasing...
String resolvedName;
// 循环取别名对应的名称,直到取到了原始名称
do {
resolvedName = this.aliasMap.get(canonicalName);
if (resolvedName != null) {
canonicalName = resolvedName;
}
}
while (resolvedName != null);
return canonicalName;
}
transformedBeanName 方法实现了以下逻辑:
1)、去除 FactoryBean 的修饰符,也就是如果 name="&aa",那么首先会去除 & 而使 name="aa"
2)、获取指定alias所表示的最终beanName,例如别名 A 指向名称为 B 的 Bean 则 返回 B;若别名 A 指向别名 B,别名 B 又指向名称为 C 的 Bean 则返回 C
单例bean在Spring容器中只会被创建一次,后续再获取bean,就直接从单例缓存中获取了,因此这里先从单例缓存对象中获取,入口在 DefaultSingletonBeanRegistry 的 getSingleton 方法,源码如下:
// 1、DefaultSingletonBeanRegistry 的 getSingleton 方法
@Override
@Nullable
public Object getSingleton(String beanName) {
// 调用 getSingleton 方法获取单例对象,allowEarlyReference 默认true,即允许创建早期引用
return getSingleton(beanName, true);
}
/**
* Return the (raw) singleton object registered under the given name.
* Checks already instantiated singletons and also allows for an early
* reference to a currently created singleton (resolving a circular reference).
* @param beanName the name of the bean to look for
* @param allowEarlyReference whether early references should be created or not
* @return the registered singleton object, or {@code null} if none found
*/
// 2、DefaultSingletonBeanRegistry 的 getSingleton 方法
@Nullable
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
// 1、从 singletonObjects 缓存中获取
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
// singletonObjects 缓存中不存在 && 单例bean已经在创建中了,这时需要加锁处理
synchronized (this.singletonObjects) {
// 2、从 earlySingletonObjects 缓存中获取
singletonObject = this.earlySingletonObjects.get(beanName);
// earlySingletonObjects 缓存中不存在 && 允许创建早期引用
if (singletonObject == null && allowEarlyReference) {
// 3、从 singletonFactories 缓存中获取早期暴露的bean引用 ObjectFactory 对象
// 某些实例对象允许创建早起引用(提前暴露已解决循环依赖问题)时,则会调用 addSingletonFactory
// 方法将对应的 ObjectFactory 存储在 singletonFactories 中
ObjectFactory> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
// 调用 ObjectFactory 的 getObject 方法获取实例bean
singletonObject = singletonFactory.getObject();
// 提前暴露的ObjectFactory 放入 earlySingletonObjects 缓存中,为了解决循环依赖检测问题
this.earlySingletonObjects.put(beanName, singletonObject);
// 移除已经使用过的 ObjectFactory
this.singletonFactories.remove(beanName);
}
}
}
}
return singletonObject;
}
上述代码的逻辑并不复杂,但是几个用于存储 bean 的 Map 到底是做什么的呢?分别说明如下:
singletonObjects:用于保存beanName和创建的单例bean实例之间的关系,beanName --> bean instance
earlySingletonObjects:也是保存beanName和创建的单例bean实例之间的关系,与 singletonObjects 不同的是,当一个单例 bean 被放到这里面后,那么当 bean 还在创建过程中就可以通过 getBean 方法好获取到了,其目的是用来检测循环依赖引用
singletonFactories:用于保存 beanName 和创建单例 bean 的工厂之间的关系,beanName --> ObjectFactory
registeredSingletons:用来保存当前所有已注册的单例 bean
无论是从缓存中获得bean还是根据不同的scope策略加载bean,都需要调用 getObjectForBeanInstance 方法获取 bean 的实例,源码过程如下:
// 1、AbstractBeanFactory 的 getObjectForBeanInstance 方法
protected Object getObjectForBeanInstance(
Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {
// Don't let calling code try to dereference the factory if the bean isn't a factory.
// name 是否以 "&" 开头
if (BeanFactoryUtils.isFactoryDereference(name)) {
if (beanInstance instanceof NullBean) {
return beanInstance;
}
if (!(beanInstance instanceof FactoryBean)) {
// 以"&" 开头的 bean 不是 FactoryBean 则抛出异常
throw new BeanIsNotAFactoryException(transformedBeanName(name), beanInstance.getClass());
}
}
// Now we have the bean instance, which may be a normal bean or a FactoryBean.
// If it's a FactoryBean, we use it to create a bean instance, unless the
// caller actually wants a reference to the factory.
if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {
// bean 实例不是 FactoryBean 或者 需要获取的就是 FactoryBean 实例本身,而不是 FactoryBean 创建的是 bean 实例
// 直接返回 bean 实例即可
return beanInstance;
}
Object object = null;
if (mbd == null) {
// 从 FactoryBean 缓存中获取实例 bean
object = getCachedObjectForFactoryBean(beanName);
}
if (object == null) {
// Return bean instance from factory.
// 将 bean 实例转换为 FactoryBean
FactoryBean> factory = (FactoryBean>) beanInstance;
// Caches object obtained from FactoryBean if it is a singleton.
if (mbd == null && containsBeanDefinition(beanName)) {
// 获取顶层父类的 BeanDefinition,合并父类属性
mbd = getMergedLocalBeanDefinition(beanName);
}
// BeanDefinition 是否用户自定义的,不是由应用程序本身定义的
boolean synthetic = (mbd != null && mbd.isSynthetic());
// 调用 getObjectFromFactoryBean 方法获取 bean 实例
object = getObjectFromFactoryBean(factory, beanName, !synthetic);
}
return object;
}
// 2、FactoryBeanRegistrySupport 的 getObjectFromFactoryBean 方法
protected Object getObjectFromFactoryBean(FactoryBean> factory, String beanName, boolean shouldPostProcess) {
if (factory.isSingleton() && containsSingleton(beanName)) {
// FactoryBean 是单例 && bean 已经在创建中
// 对 singletonObjects 缓存加锁,防止其他线程修改
synchronized (getSingletonMutex()) {
// 从 FactoryBean 创建的单例 bean 缓存 factoryBeanObjectCache 中获取 bean 实例
Object object = this.factoryBeanObjectCache.get(beanName);
if (object == null) {
// doGetObjectFromFactoryBean 方法真正实现了 FactoryBean 创建bean 实例
object = doGetObjectFromFactoryBean(factory, beanName);
// Only post-process and store if not put there already during getObject() call above
// (e.g. because of circular reference processing triggered by custom getBean calls)
// 如果此时 factoryBeanObjectCache 缓存中存在 bean 实例,则更新为从 FactoryBean 中获取的最新的 bean 实例
Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
if (alreadyThere != null) {
object = alreadyThere;
}
else {
// factoryBeanObjectCache 缓存中不存在 bean 实例 && bean 是非用户自定义的
if (shouldPostProcess) {
if (isSingletonCurrentlyInCreation(beanName)) {
// Temporarily return non-post-processed object, not storing it yet..
// bean 实例在创建中,直接返回 bean
return object;
}
// bean 实例创建加入 singletonsCurrentlyInCreation 缓存中
beforeSingletonCreation(beanName);
try {
// 调用 BeanFactory 的初始化后置处理器
object = postProcessObjectFromFactoryBean(object, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(beanName,
"Post-processing of FactoryBean's singleton object failed", ex);
}
finally {
// singletonsCurrentlyInCreation 缓存中移除 bean
afterSingletonCreation(beanName);
}
}
if (containsSingleton(beanName)) {
// FactoryBean 创建的单例 bean 加入到缓存 factoryBeanObjectCache 中
this.factoryBeanObjectCache.put(beanName, object);
}
}
}
return object;
}
}
else {
// 缓存中不存在或者非单例bean,则直接使用 FactoryBean 创建bean 实例
Object object = doGetObjectFromFactoryBean(factory, beanName);
if (shouldPostProcess) {
try {
object = postProcessObjectFromFactoryBean(object, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "Post-processing of FactoryBean's object failed", ex);
}
}
return object;
}
}
// 3、FactoryBeanRegistrySupport 的 doGetObjectFromFactoryBean 方法
private Object doGetObjectFromFactoryBean(final FactoryBean> factory, final String beanName)
throws BeanCreationException {
Object object;
try {
if (System.getSecurityManager() != null) {
AccessControlContext acc = getAccessControlContext();
try {
object = AccessController.doPrivileged((PrivilegedExceptionAction
getObjectForBeanInstance 方法主要实现了以下逻辑:
1)、如果 bean 实例不是 FactoryBean 类型或者需要获取的就是 FactoryBean 实例本身,而不是 FactoryBean 创建的是 bean 实例,则直接返回 bean 实例即可
2)、从 FactoryBean 缓存中获取实例 bean,获取到了直接返回 bean 即可
3)、调用 FactoryBean 的 getObject 方法获取 bean 实例
4)、获取 bean 实例后调用 BeanFactory 的初始化后置处理方法 postProcessObjectFromFactoryBean -> applyBeanPostProcessorsAfterInitialization(例如 AbstractAutowireCapableBeanFactory 的 postProcessObjectFromFactoryBean -> applyBeanPostProcessorsAfterInitialization 方法)
至于 FactoryBean 获取 bean 实例的过程, 即 FactoryBean 的 getObject 方法调用,后续单独讲解,这里不做赘述了
因为bean有继承关系的存在,如果有父类的话,需要将父类的所有属性都合并到子类中去,然后创建出后续bean处理所需要的 RootBeanDefinition 对象,入口在 getMergedLocalBeanDefinition 方法,源码如下:
// 1、AbstractBeanFactory 的 getMergedLocalBeanDefinition 方法
protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName) throws BeansException {
// Quick check on the concurrent map first, with minimal locking.
RootBeanDefinition mbd = this.mergedBeanDefinitions.get(beanName);
if (mbd != null) {
// 已经merge过的bean的缓存中存在,则直接返回
return mbd;
}
// 获取merge的bean定义 BeanDefinition
return getMergedBeanDefinition(beanName, getBeanDefinition(beanName));
}
// 2、AbstractBeanFactory 的 getMergedBeanDefinition 方法
protected RootBeanDefinition getMergedBeanDefinition(String beanName, BeanDefinition bd)
throws BeanDefinitionStoreException {
// 继续调用 getMergedBeanDefinition 重载方法,第三个参数是原始bean定义,默认为空
return getMergedBeanDefinition(beanName, bd, null);
}
// 3、AbstractBeanFactory 的 getMergedBeanDefinition 方法
protected RootBeanDefinition getMergedBeanDefinition(
String beanName, BeanDefinition bd, @Nullable BeanDefinition containingBd)
throws BeanDefinitionStoreException {
synchronized (this.mergedBeanDefinitions) {
RootBeanDefinition mbd = null;
// Check with full lock now in order to enforce the same merged instance.
if (containingBd == null) {
// 再次从缓存中获取,之所以这样有可能是其他地方已经merge好bean定义了
mbd = this.mergedBeanDefinitions.get(beanName);
}
if (mbd == null) {
// 当前 BeanDefinition 没有父类
if (bd.getParentName() == null) {
// Use copy of given root bean definition.
if (bd instanceof RootBeanDefinition) {
// 如果 BeanDefinition 是 RootBeanDefinition 类型,则直接将 BeanDefinition 所有内容拷贝到 RootBeanDefinition 对象
mbd = ((RootBeanDefinition) bd).cloneBeanDefinition();
}
else {
// BeanDefinition 作为构造参数入参,创建 RootBeanDefinition
mbd = new RootBeanDefinition(bd);
}
}
else {
// BeanDefinition 存在父类
// Child bean definition: needs to be merged with parent.
BeanDefinition pbd;
try {
// 获取父类的真实beanName
String parentBeanName = transformedBeanName(bd.getParentName());
// 父类beanName和子类beanName不同
if (!beanName.equals(parentBeanName)) {
// 递归获取父类的bean定义,即合并所有的父类属性到 BeanDefinition 中
pbd = getMergedBeanDefinition(parentBeanName);
}
else {
// 父类beanName和子类beanName相同
BeanFactory parent = getParentBeanFactory();
if (parent instanceof ConfigurableBeanFactory) {
// 父类BeanFactory 是 ConfigurableBeanFactory,则递归获取父类的bean定义,即合并所有的父类属性到 BeanDefinition 中
pbd = ((ConfigurableBeanFactory) parent).getMergedBeanDefinition(parentBeanName);
}
else {
throw new NoSuchBeanDefinitionException(parentBeanName,
"Parent name '" + parentBeanName + "' is equal to bean name '" + beanName +
"': cannot be resolved without an AbstractBeanFactory parent");
}
}
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanDefinitionStoreException(bd.getResourceDescription(), beanName,
"Could not resolve parent bean definition '" + bd.getParentName() + "'", ex);
}
// Deep copy with overridden values.
// 创建 RootBeanDefinition
mbd = new RootBeanDefinition(pbd);
// 深拷贝子类全部属性到 RootBeanDefinition 中
mbd.overrideFrom(bd);
}
// Set default singleton scope, if not configured before.
if (!StringUtils.hasLength(mbd.getScope())) {
mbd.setScope(RootBeanDefinition.SCOPE_SINGLETON);
}
// A bean contained in a non-singleton bean cannot be a singleton itself.
// Let's correct this on the fly here, since this might be the result of
// parent-child merging for the outer bean, in which case the original inner bean
// definition will not have inherited the merged outer bean's singleton status.
if (containingBd != null && !containingBd.isSingleton() && mbd.isSingleton()) {
// 原始bean定义的 scope 和目前创建的 RootBeanDefinition 的 scope 不同,则以原始bean定义的 scope 为准
mbd.setScope(containingBd.getScope());
}
// Cache the merged bean definition for the time being
// (it might still get re-merged later on in order to pick up metadata changes)
if (containingBd == null && isCacheBeanMetadata()) {
// 合并过的bean定义存入mergedBeanDefinitions缓存中
this.mergedBeanDefinitions.put(beanName, mbd);
}
}
return mbd;
}
}
// 4、AbstractBeanDefinition 的 overrideFrom 方法
public void overrideFrom(BeanDefinition other) {
// 将所有的子类属性拷贝到 RootBeanDefinition 属性中
if (StringUtils.hasLength(other.getBeanClassName())) {
setBeanClassName(other.getBeanClassName());
}
if (StringUtils.hasLength(other.getScope())) {
setScope(other.getScope());
}
setAbstract(other.isAbstract());
if (StringUtils.hasLength(other.getFactoryBeanName())) {
setFactoryBeanName(other.getFactoryBeanName());
}
if (StringUtils.hasLength(other.getFactoryMethodName())) {
setFactoryMethodName(other.getFactoryMethodName());
}
setRole(other.getRole());
setSource(other.getSource());
copyAttributesFrom(other);
if (other instanceof AbstractBeanDefinition) {
AbstractBeanDefinition otherAbd = (AbstractBeanDefinition) other;
if (otherAbd.hasBeanClass()) {
setBeanClass(otherAbd.getBeanClass());
}
if (otherAbd.hasConstructorArgumentValues()) {
getConstructorArgumentValues().addArgumentValues(other.getConstructorArgumentValues());
}
if (otherAbd.hasPropertyValues()) {
getPropertyValues().addPropertyValues(other.getPropertyValues());
}
if (otherAbd.hasMethodOverrides()) {
getMethodOverrides().addOverrides(otherAbd.getMethodOverrides());
}
Boolean lazyInit = otherAbd.getLazyInit();
if (lazyInit != null) {
setLazyInit(lazyInit);
}
setAutowireMode(otherAbd.getAutowireMode());
setDependencyCheck(otherAbd.getDependencyCheck());
setDependsOn(otherAbd.getDependsOn());
setAutowireCandidate(otherAbd.isAutowireCandidate());
setPrimary(otherAbd.isPrimary());
copyQualifiersFrom(otherAbd);
setInstanceSupplier(otherAbd.getInstanceSupplier());
setNonPublicAccessAllowed(otherAbd.isNonPublicAccessAllowed());
setLenientConstructorResolution(otherAbd.isLenientConstructorResolution());
if (otherAbd.getInitMethodName() != null) {
setInitMethodName(otherAbd.getInitMethodName());
setEnforceInitMethod(otherAbd.isEnforceInitMethod());
}
if (otherAbd.getDestroyMethodName() != null) {
setDestroyMethodName(otherAbd.getDestroyMethodName());
setEnforceDestroyMethod(otherAbd.isEnforceDestroyMethod());
}
setSynthetic(otherAbd.isSynthetic());
setResource(otherAbd.getResource());
}
else {
getConstructorArgumentValues().addArgumentValues(other.getConstructorArgumentValues());
getPropertyValues().addPropertyValues(other.getPropertyValues());
setLazyInit(other.isLazyInit());
setResourceDescription(other.getResourceDescription());
}
}
getMergedLocalBeanDefinition 方法主要实现了一个逻辑:
递归将所有的父类属性和子类属性都合并到 RootBeanDefinition 中
经过 2.5 开始创建单例 bean 并存入 singletonObjects 缓存中,则 2.2 中的 getSingleton 方法才能获取到缓存中的创建中的bean,这两个步骤中的 getSingleton 方法是 DefaultSingletonBeanRegistry 类中重载的方法,实现逻辑不一样,开始创建单例 bean 的 getSingleton 方法源码如下:
// 1、DefaultSingletonBeanRegistry 的 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);
// singletonObjects 缓存中不存在 bean
if (singletonObject == null) {
// 单例bean在销毁中抛出异常
if (this.singletonsCurrentlyInDestruction) {
throw new BeanCreationNotAllowedException(beanName,
"Singleton bean creation not allowed while singletons of this factory are in destruction " +
"(Do not request a bean from a BeanFactory in a destroy method implementation!)");
}
if (logger.isDebugEnabled()) {
logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
}
// 将bean加入在创建中的 singletonsCurrentlyInCreation 缓存中,为循环依赖检测准备
beforeSingletonCreation(beanName);
boolean newSingleton = false;
boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
if (recordSuppressedExceptions) {
this.suppressedExceptions = new LinkedHashSet<>();
}
try {
// 调用匿名类的 createBean 方法创建 bean 实例
singletonObject = singletonFactory.getObject();
newSingleton = true;
}
catch (IllegalStateException ex) {
// Has the singleton object implicitly appeared in the meantime ->
// if yes, proceed with it since the exception indicates that state.
// 创建bean过程中如果出现异常,则从缓存中获取该bean,如果能正常获取到,则直接返回bean即可,否则抛出异常
singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
throw ex;
}
}
catch (BeanCreationException ex) {
if (recordSuppressedExceptions) {
for (Exception suppressedException : this.suppressedExceptions) {
ex.addRelatedCause(suppressedException);
}
}
throw ex;
}
finally {
if (recordSuppressedExceptions) {
this.suppressedExceptions = null;
}
// 创建完 bean 实例后,将 bean 从创建中的 singletonsCurrentlyInCreation 缓存中移除
afterSingletonCreation(beanName);
}
if (newSingleton) {
// 单例bean创建成功,加入缓存中
addSingleton(beanName, singletonObject);
}
}
return singletonObject;
}
}
// 2、DefaultSingletonBeanRegistry 的 addSingleton 方法
protected void addSingleton(String beanName, Object singletonObject) {
synchronized (this.singletonObjects) {
// bean 存入 singletonObjects 缓存中
this.singletonObjects.put(beanName, singletonObject);
// bean创建过程中的辅助状态标记从 singletonFactories、earlySingletonObjects 缓存中移除
this.singletonFactories.remove(beanName);
this.earlySingletonObjects.remove(beanName);
// 创建好的bean实例加入 registeredSingletons 缓存中
this.registeredSingletons.add(beanName);
}
}
getSingleton 方法主要实现了以下逻辑:
1)、beforeSingletonCreation 和 afterSingletonCreation 方法记录了 bean 创建过程中的状态,beforeSingletonCreation 通过 this.singletonsCurrentlyInCreation.add(beanName) 将当前正在创建的 bean 记录在缓存中,这样便可以对循环依赖进行检测,而 afterSingletonCreation 方法则将创建好 bean 实例之后从 singletonsCurrentlyInCreation 缓存中删除
2)、调用匿名类的 createBean 方法创建 bean 实例
3)、bean 实例创建好之后,加入 singletonObjects 和 registeredSingletons 缓存中,singletonFactories 和 earlySingletonObjects 缓存删除 bean 创建过程中的辅助状态标记
创建bean 是一个非常复杂的过程,我们单独写篇文章来分析创建bean的整个过程,这里不做过多的赘述了
Spring中bean的加载是一个比较复杂的过程,其核心逻辑大致如下:
1)、先尝试从缓存中获取bean实例,如果获取到的不是真正的bean实例,则调用 FactoryBean 获取bean,否则直接返回bean实例即可
2)、 缓存中没有bean实例的话,先创建bean总定义RootBeanDefinition,然后根据 scope 调用不同的策略来创建bean