背景
上一篇我们介绍了自定义标签的解析,本篇我们介绍 bean 的加载
依旧是之前的测试方法
BeanFactory bf = new XmlBeanFactory(new ClassPathResource("beans.xml"));
User userTest = (User) bf.getBean("testBean");
System.out.println(userTest.getEmail());
对于 bean 的加载,在 Spring 中的调用为
User userTest = (User) bf.getBean(“testBean”);
1. 加载流程
1. 转换对应的 beanName
传入的 name 可能是别名,也可能是 FactoryBean,所以需要进行一系列的解析,包括
去除 FactoryBean 的修饰符,也就是说如果 name=”&aa”,那么会首先去除 & 而使 name=”aa”
若指定 alias 所表示的最终 beanName,例如别名 A 指向名称为 B 的 bean,则返回 B,若别名 A 指向别名 B,别名 B 指向别名 C,最终返回 C
this.transformedBeanName(name);
2. 尝试从缓存中加载单例
单例在 Spring 的同一个容器中只会被创建一次,后续再获取 bean,就直接从单例缓存中获取了,当然这里也只是尝试加载,首先尝试从缓存加载,如果加载不成功则再次尝试从 singletonFactories 中加载,因为在创建单例 bean 的时候会存在依赖注入的情况,而在创建依赖的时候为例避免循环依赖,在 Spring 中创建 bean 的原则是不等 bean 创建完成就会将创建 bean 的 ObjectFactory 提早曝光加入到缓存中,一旦下一个 bean 创建的时候需要依赖上一个 bean 则直接使用 ObjectFactory
this.getSingleton(beanName);
3.bean 的实例化
如果从缓存中得到了 bean 的原始状态,则需要对 bean 进行实例化,这里必须强调,缓存中记录的只是最原始的 bean 状态,并不一定是我们要的最终 bean,举个例子,加入我们需要对工厂 bean 进行处理,那么这里得到的其实是工厂 bean 的初始状态,但是我们真正需要的是工厂 bean 中定义的 factory-method 方法中返回的 bean,而 getObjecctForBeanInstance 就是完成这个工作的。
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
4. 原型模式的依赖检查
只有在单例模式下才会尝试解决循环依赖如果存在 A 中有 B 属性,B 中有 A 属性,那么当依赖注入时,就会产生当 A 还未创建完成的时候,因为对于 B 的创建再次返回创建 A,造成循环依赖,也就是说
idpRrototypeCurrentlyInCreation(beanName) 判断 true
5. 检查 parentBeanFactory
从代码上看,如果缓存没有数据的话,直接转到父类工厂上去加载了,
判断条件 parentBeanFaactory!=null&&!containsBeanDefinition(beanName)
parentBeanFactory 如果为空,则一切结束
!containsBeanDefinition(beanName) 能检测到当前加载的 XML 配置文件中不包含 beanName 所对应的配置,就只能到 parentBeanFactory 去尝试,然后再递归调用 getBean 方法
6. 将存储 XML 配置文件的 GenericBeanDefinition 转换为 RootBeanDefinition
因为从 XML 配置文件中读取到的 bean 信息是存储在 GenericBeanDefinition 中的,但是所有的 bean 后续处理都是针对 RootBeanDefinition 的,所以在这里需要一个转换,转换的同时,如果有父类的 bean 不为空的话,则会一并合并父类属性
7. 寻找依赖
因为 bean 初始化的过程很可能会用到某些属性,而某些属性很可能是动态配置的,且配置成依赖于其他其他的 bean,那么在这个时候就必要先加载依赖的 bean,所以在 Spring 的加载顺序中,初始化某一个 bean 的时候会先初始化这个 bean 对应的依赖
8. 针对不同的 scope 进行 bean 创建
在 Spring 中存在不同的 Scope,期中默认是 singletion, 但是还有些其他配置诸如 prototype,request 之类,在这个步骤 中,Spring 会根据不同的配置进行不同的初始化策略
9. 类型转换
程序到了这里返回 bean 后已经基本结束了,通常对该方法的调用参数 requiredType 是为空的,但是可能存在这样的情况,返回的 bean 实际是个 String,但是 requestType 确传入 Integer 类型,那么这时候本步骤就会其作用了,它的功能是将返回的 bean 转换为 requesType 所指定的类型,Spring 提供各种类型转换器
public Object getBean(String name) throws BeansException {return doGetBean(name, null, null, false);
}
2. 执行 doGetBean 过程 doGetBean
package org.springframework.beans.factory.support;
public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport implements ConfigurableBeanFactory {
private final ThreadLocal<Object> prototypesCurrentlyInCreation =
new NamedThreadLocal<>("Prototype beans currently in creation");
/**
* Return an instance, which may be shared or independent, of the specified bean.
* @param name the name of the bean to retrieve
* @param requiredType the required type of the bean to retrieve
* @param args arguments to use when creating a bean instance using explicit arguments
* (only applied when creating a new instance as opposed to retrieving an existing one)
* @param typeCheckOnly whether the instance is obtained for a type check,
* not for actual use
* @return an instance of the bean
* @throws BeansException if the bean could not be created
* 返回一个实例,该实例可以是指定 bean 的共享或独立的。* @param name 要检索的 bean 的名称
* @param requiredType 要检索的 bean 的必需类型
* @param args 参数在使用显式参数创建 bean 实例时使用
*(仅适用于创建新实例而不是检索现有实例)* @param typeCheckOnly 是否获取实例用于类型检查,* 不用于实际用途
* @返回 bean 的实例
* @throws BeansException 如果无法创建 bean
*/
@SuppressWarnings("unchecked")
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
// 提取对应的 beanName
final String beanName = transformedBeanName(name);
Object bean;
// 检查缓存中或者实例工厂中是否有对应的实例
// 在创建单例 bean 的时候存在依赖注入的情况,而在创建依赖的时候为了避免循环依赖,Spring 创建 bean 的原则是不等 bean 创建完成的 ObjectFactory 提早曝光
// 也就是将 Objectactory 加入到缓存中, 一旦下一个 bean 创建的时候需要依赖上个 bean 则直接使用 ObjectFactory
// 直接尝试从缓存获取,或者 singletonFactories 中的 ObjectFactory 中取
// Eagerly check singleton cache for manually registered singletons.
Object sharedInstance = getSingleton(beanName);
// 缓存中或者实例工厂中存在对应的实例
if (sharedInstance != null && args == null) {if (logger.isDebugEnabled()) {if (isSingletonCurrentlyInCreation(beanName)) {
logger.debug("Returning eagerly cached instance of singleton bean'" + beanName +
"'that is not fully initialized yet - a consequence of a circular reference");
}
else {logger.debug("Returning cached instance of singleton bean'" + beanName + "'");
}
}
// 返回对应的实例,有时候存在诸如 BeanFactory 的情况并不是直接返回实例本身而是返回指定方法返回的实例
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
// 缓存中或者实例工厂中不存在对应的实例
else {
// 只有在单例情况下才会尝试解决循环依赖,原型模式的情况下如果存在 A 中有 B 属性,B 中有 A 属性,那么当依赖注入的时候,就会产生当 A 还未创建完成的时候因为对于 B 的创建再次返回 A 造成循环依赖,也就是如下情况
// Fail if we're already creating this bean instance:
// We're assumably within a circular reference.
if (isPrototypeCurrentlyInCreation(beanName)) {// 如果是 Prototype(多例模式)并且 bean 正在创建中,如果是,说明存在循环依赖
throw new BeanCurrentlyInCreationException(beanName);
}
// Check if bean definition exists in this factory.
BeanFactory parentBeanFactory = getParentBeanFactory();
// 如果 beanDefinitionMap 中也就是在所有已加载的类中不包括 beanName 则尝试从 parentBeanFactory 中检测
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);
}
else if (args != null) {
// 递归到 BeanFactory 中寻找
// Delegation to parent with explicit args.
return (T) parentBeanFactory.getBean(nameToLookup, args);
}
else {
// No args -> delegate to standard getBean method.
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
}
// 如果不仅仅做类型检查则是创建 bean,这里要进行记录
if (!typeCheckOnly) {markBeanAsCreated(beanName);
}
try {
// 将存储 XML 配置文件的 GenericBeanDefinition 转换为 RootBeanDefinition,如果指定 BeanName 是子 Bean 的话同时会合并父类的相关属性
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);
// Guarantee initialization of beans that the current bean depends on.
String[] dependsOn = mbd.getDependsOn();
// 若存在依赖则需要递归实例化依赖的 bean
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 + "'");
}
// 缓存依赖调用
registerDependentBean(dep, beanName);
try {getBean(dep);// 在这里重新调用 doGetBean 方法,解析依赖的 beanName 即 dep
}
catch (NoSuchBeanDefinitionException ex) {throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"'"+ beanName +"' depends on missing bean '"+ dep +"'", ex);
}
}
}
// 依赖为空
// 实例化依赖的 bean 后便可实例化 mbd 本身了
//singletion 单例模式的创建
// Create bean instance.
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.
// 销毁单例
destroySingleton(beanName);
throw ex;
}
});
//bean 的实例化
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
// 多例模式
else if (mbd.isPrototype()) {
// It's a prototype -> create a new instance.
//prototype 模式的创建(new)
Object prototypeInstance = null;
try {// 创建前回调, 标记 bean 正在创建中(set 进 ThreadLocal)
beforePrototypeCreation(beanName);
// 创建 bean
prototypeInstance = createBean(beanName, mbd, args);
}
finally {// 创建 bean 后的回调, 标记 bean 不在创建中(从 ThreadLocal 中移除)
afterPrototypeCreation(beanName);
}
//bean 的实例化
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
else {
// 指定的 scope 上实例化 bean
String scopeName = mbd.getScope();
final Scope scope = this.scopes.get(scopeName);
if (scope == null) {throw new IllegalStateException("No Scope registered for scope name'" + scopeName + "'");
}
try {Object scopedInstance = scope.get(beanName, () -> {// 创建前回调, 标记 bean 正在创建中(set 进 ThreadLocal)
beforePrototypeCreation(beanName);
try {
// 创建 bean
return createBean(beanName, mbd, args);
}
finally {// 创建 bean 后的回调, 标记 bean 不在创建中(从 ThreadLocal 中移除)
afterPrototypeCreation(beanName);
}
});
//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 的实际类型, 将返回的 bean 转换为 requesType 所指定的类型
if (requiredType != null && !requiredType.isInstance(bean)) {
try {T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
if (convertedBean == null) {throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
return convertedBean;
}
catch (TypeMismatchException ex) {if (logger.isDebugEnabled()) {
logger.debug("Failed to convert bean'" + name + "'to required type'" +
ClassUtils.getQualifiedName(requiredType) + "'", ex);
}
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
}
return (T) bean;
}
2.1 转换对应的 beanName transformedBeanName
String beanName = this.transformedBeanName(name);
传入的 name 可能是别名,也可能是 FactoryBean,所以需要进行一系列的解析,包括
去除 FactoryBean 的修饰符,也就是说如果 name=”&aa”,那么会首先去除 & 而使 name=”aa”
若指定 alias 所表示的最终 beanName,例如别名 A 指向名称为 B 的 bean,则返回 B,若别名 A 指向别名 B,别名 B 指向别名 C,最终返回 C
/**
* Return the bean name, stripping out the factory dereference prefix if necessary,
* and resolving aliases to canonical names.
* @param name the user-specified name
* @return the transformed bean name
*/
protected String transformedBeanName(String name) {return canonicalName(BeanFactoryUtils.transformedBeanName(name));
}
2.1.1 去除 FactoryBean 的修饰符
String FACTORY_BEAN_PREFIX = "&";
/**
* Return the actual bean name, stripping out the factory dereference
* prefix (if any, also stripping repeated factory prefixes if found).
* @param name the name of the bean
* @return the transformed name
* @see BeanFactory#FACTORY_BEAN_PREFIX
* 返回实际的 bean 名称,删除工厂的取消引用
* 前缀(如果有的话,还会删除重复的工厂前缀(如果找到))。* @param 名称 bean 的名称
*/
public static String transformedBeanName(String name) {Assert.notNull(name, "'name' must not be null");
String beanName = name;
while (beanName.startsWith(BeanFactory.FACTORY_BEAN_PREFIX)) {beanName = beanName.substring(BeanFactory.FACTORY_BEAN_PREFIX.length());
}
return beanName;
}
2.1.2 获取最终指向的 beanName canonicalName
若指定 alias 所表示的最终 beanName,例如别名 A 指向名称为 B 的 bean,则返回 B,若别名 A 指向别名 B,别名 B 指向别名 C,最终返回 C
/**
* Determine the raw name, resolving aliases to canonical names.
* @param name the user-specified name
* @return the transformed name
* 确定原始名称,将别名解析为规范名称。* @param name 用户指定的名称
* @返回转换后的名称
*/
public String canonicalName(String name) {
String canonicalName = name;
// Handle aliasing...
String resolvedName;
do {
// 获取 canonicalName 指向的 Name,再将获取的 Name 赋值给 canonicalName,循环直到返回最后的 Name,aliasMap 保存别名和实际内容直接的映射关系
// 例:别名 1 -> 别名 2 别名 2 -> 别名 3 别名 3 -> 实际 bean, 遍历 aliasMap 得到最终指向的 beanName
resolvedName = this.aliasMap.get(canonicalName);
if (resolvedName != null) {canonicalName = resolvedName;}
}
while (resolvedName != null);
return canonicalName;
}
2.2 尝试从缓存中加载单例 getSingleton
单例在 Spring 的同一个容器中只会被创建一次,后续再获取 bean,就直接从单例缓存中获取了,当然这里也只是尝试加载,首先尝试从缓存加载,如果加载不成功则再次尝试从 singletonFactories 中加载,因为在创建单例 bean 的时候会存在依赖注入的情况,而在创建依赖的时候为例避免循环依赖,在 Spring 中创建 bean 的原则是不等 bean 创建完成就会将创建 bean 的 ObjectFactory 提早曝光加入到缓存中,一旦下一个 bean 创建的时候需要依赖上一个 bean 则直接使用 ObjectFactory
Object sharedInstance = getSingleton(beanName);
@Override
@Nullable
public Object getSingleton(String beanName) {
//true 表示允许早期依赖
return getSingleton(beanName, true);
}
这个方法从 singletonObjects 里获取实例,如果获取不到再从 earlySingletonObjects 里获取,如果还是获取不到再从 singletonFactoies 中获取 baneName 对应的 ObjectFactory,然后调用 ObjectFactory 的 getObject 来创建 bean 并放到 earlySingletonObjects 中,并从 singletonFactories 里面 remove 掉这个 ObjectFactory,而对后续的所有内存操作都是为了循环依赖检测时候使用,也就是在 allowEarlyReference 为 true 的情况下使用
package org.springframework.beans.factory.support;
public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {
// 用于保存 BeanName 和创建 bean 实例之间的关系,beanName -> bean instance
private final Map<String, Object> singletonObjects = new ConcurrentHashMap(256);
// 用于保存 BeanName 和创建 bean 工厂之间的关系,beanName -> ObjectFactory
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap(16);
// 保存 beanName 和创建 bean 实例之间的关系, 与 singletonObjects 不同的地方在于,当一个单例 bean 被放到这里面后,bean 在创建过程中,可以通过 getBean 方法获取到, 目的是用来检测循环引用
private final Map<String, Object> earlySingletonObjects = new HashMap(16);
// 保存当前所有已注册的 bean
private final Set<String> registeredSingletons = new LinkedHashSet(256);
/**
* Return the (raw) singleton object registered under the given name.
* <p>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
* 返回以给定名称注册的(原始)单例对象。* <p> 检查已实例化的单例,并允许早期
* 引用当前创建的单例(解析循环引用)。* @param beanName 要查找的 bean 的名称
* @param allowEarlyReference 允许早期依赖
* @返回注册的单例对象;如果找不到,则返回{@code null}
*/
@Nullable
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
// 检查缓存中是否存在实例
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
// 如果为空, 且正在创建中, 锁定全局变量并进行处理
synchronized (this.singletonObjects) {
// 如果 bean 正在加载则不处理
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
// 当某些方法需要提前初始化的时候会调用 addSingletonFactory 方法将对于 ObjectFactory 初始化策略存储在 singletonFactories
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
// 调用预设的 getObject 方法
singletonObject = singletonFactory.getObject();
// 记录在缓存中 earlySingletonObjects 和 singletonFactories 互斥
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
return singletonObject;
}
2.3 缓存中存在,开始 bean 的实例化 getObjectForBeanInstance
如果从缓存中得到了 bean 的原始状态,则需要对 bean 进行实例化,这里必须强调,缓存中记录的只是最原始的 bean 状态,并不一定是我们要的最终 bean,举个例子,加入我们需要对工厂 bean 进行处理,那么这里得到的其实是工厂 bean 的初始状态,但是我们真正需要的是工厂 bean 中定义的 factory-method 方法中返回的 bean,而 getObjecctForBeanInstance 就是完成这个工作的。
- 对 FactoryBean 正确性的验证
- 对非 FactoryBean 不做处理
- 对 bean 进行转换
- 将 Factory 中解析 bean 的工作委托给 getObjectFromFactoryBean
package org.springframework.beans.factory.support;
public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {
/**
* Get the object for the given bean instance, either the bean
* instance itself or its created object in case of a FactoryBean.
* @param beanInstance the shared bean instance
* @param name name that may include factory dereference prefix
* @param beanName the canonical bean name
* @param mbd the merged bean definition
* @return the object to expose for the bean
* 获取给定 bean 实例的对象,即 bean
* 实例本身或其创建的对象(对于 FactoryBean)。* @param beanInstance 共享 bean 实例
* @param 名称可能包含工厂取消引用前缀的名称
* @param beanName 规范的 bean 名称
* @param mbd 合并的 bean 定义
* @返回对象以为 bean 公开
*/
protected Object getObjectForBeanInstance(Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {
// 如果指定的 name 是工厂相关(且 & 为前缀)且 beanInstance 又不是 FactoryBean 类型则验证不通过
// Don't let calling code try to dereference the factory if the bean isn't a factory.
if (BeanFactoryUtils.isFactoryDereference(name)) {if (beanInstance instanceof NullBean) {return beanInstance;}
if (!(beanInstance instanceof 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.
// 现在有了 bean 的实例,这个实例可能会是正常的 bean 或者 FactoryBean
// 如果是 FactoryBean 我们使用它创建实例,但是如果用户想要直接获取工厂实例而不是工厂的 getObject 方法对应的实例那么传入的 name 应该加前缀 &
if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {return beanInstance;}
// 加载 FactoryBean
Object object = null;
if (mbd == null) {
// 尝试从缓存中加载 bean
object = getCachedObjectForFactoryBean(beanName);
}
if (object == null) {
// Return bean instance from factory.
// 上面做过判断,如果不是 FactoryBean 就已经报错了,到这里确定 beanInstance 是 FactoryBean 类型
FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
// Caches object obtained from FactoryBean if it is a singleton.
// 将存储 XML 配置文件的 GernericBeanDefinition 转换为 RootBeanDefinition, 如果指定了 BeanName 是子 Bean 的话会合并父类相关属性
if (mbd == null && containsBeanDefinition(beanName)) {mbd = getMergedLocalBeanDefinition(beanName);
}
// 是否是用户定义而不是程序本身定义
boolean synthetic = (mbd != null && mbd.isSynthetic());
// 从 FactoryBean 中解析 Bean
object = getObjectFromFactoryBean(factory, beanName, !synthetic);
}
return object;
}
2.3.1 验证 FacoryBean 的正确性 isFactoryDereference
String FACTORY_BEAN_PREFIX = "&";
/**
* Return whether the given name is a factory dereference
* (beginning with the factory dereference prefix).
* @param name the name of the bean
* @return whether the given name is a factory dereference
* @see BeanFactory#FACTORY_BEAN_PREFIX
*/
public static boolean isFactoryDereference(@Nullable String name) {return (name != null && name.startsWith(BeanFactory.FACTORY_BEAN_PREFIX));
}
2.3.2 从缓存中加载 bean,方法为父类 FactoryBeanRegistrySupport 中的方法 getCachedObjectForFactoryBean
/**
* Obtain an object to expose from the given FactoryBean, if available
* in cached form. Quick check for minimal synchronization.
* @param beanName the name of the bean
* @return the object obtained from the FactoryBean,
* or {@code null} if not available
*/
@Nullable
protected Object getCachedObjectForFactoryBean(String beanName) {return this.factoryBeanObjectCache.get(beanName);
}
2.3.3 从 FactoryBean 中解析 Bean getObjectFromFactoryBean
实现了 doGetObjectFromFactoryBean 中的方法后并没有直接返回,而是根据 shouldPostProcess 调用 ObjectFactory 的后处理器
/**
* Obtain an object to expose from the given FactoryBean.
* @param factory the FactoryBean instance
* @param beanName the name of the bean
* @param shouldPostProcess whether the bean is subject to post-processing
* @return the object obtained from the FactoryBean
* @throws BeanCreationException if FactoryBean object creation failed
* @see org.springframework.beans.factory.FactoryBean#getObject()
* 从给定的 FactoryBean 获取要暴露的对象。* @param 工厂的 FactoryBean 实例
* @param beanName bean 的名称
* @param shouldPostProcess Bean 是否要进行后处理
* @返回从 FactoryBean 获得的对象
* 如果 FactoryBean 对象创建失败,则 @@ throws BeanCreationException
* @see org.springframework.beans.factory.FactoryBean#getObject()*/
protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {if (factory.isSingleton() && containsSingleton(beanName)) {
// 单例模式 双重检测
synchronized (getSingletonMutex()) {
// 从缓存中获取,如果 object 不为 null,执行下去直接返回 object
Object object = this.factoryBeanObjectCache.get(beanName);
// 如果获取的对象 object 为 null
if (object == null) {
// 根据 FactoryBean 获取对象
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)
// 仅对上面的 getObject()调用期间尚未进行的后处理和存储进行存储
//(例如,由于自定义 getBean 调用触发了循环引用处理)// 如果此时可以根据缓存获取到对象,就使用根据缓存获取到的
Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
if (alreadyThere != null) {object = alreadyThere;}
else {if (shouldPostProcess) {if (isSingletonCurrentlyInCreation(beanName)) {
// Temporarily return non-post-processed object, not storing it yet..
return object;
}
beforeSingletonCreation(beanName);
try {object = postProcessObjectFromFactoryBean(object, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(beanName,
"Post-processing of FactoryBean's singleton object failed", ex);
}
finally {afterSingletonCreation(beanName);
}
}
if (containsSingleton(beanName)) {this.factoryBeanObjectCache.put(beanName, object);
}
}
}
return object;
}
}
else {
// 不是单例模式
Object object = doGetObjectFromFactoryBean(factory, beanName);
if (shouldPostProcess) {
try {
// 调用 objectFactory 的后处理器
object = postProcessObjectFromFactoryBean(object, beanName);
}
catch (Throwable ex) {throw new BeanCreationException(beanName, "Post-processing of FactoryBean's object failed", ex);
}
}
return object;
}
}
2.3.3.1 执行从 FactoryBean 中解析 Bean doGetObjectFromFactoryBean
如果 bean 声明类型为 FactoryBean 类型,则当提取 bean 时提取的不是 FactoryBean, 而是 FactoryBean 对应的 getObejct 方法返回的 bean
/**
* Obtain an object to expose from the given FactoryBean.
* @param factory the FactoryBean instance
* @param beanName the name of the bean
* @return the object obtained from the FactoryBean
* @throws BeanCreationException if FactoryBean object creation failed
* @see org.springframework.beans.factory.FactoryBean#getObject()
* 从给定的 FactoryBean 获取要暴露的对象。* @param 工厂的 FactoryBean 实例
* @param beanName bean 的名称
* @返回从 FactoryBean 获得的对象
* 如果 FactoryBean 对象创建失败,则 @@ throws BeanCreationException
* @see org.springframework.beans.factory.FactoryBean#getObject()*/
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<Object>) factory::getObject, acc);
}
catch (PrivilegedActionException pae) {throw pae.getException();
}
}
else {
// 直接调用 getObject 方法
object = factory.getObject();}
}
catch (FactoryBeanNotInitializedException ex) {throw new BeanCurrentlyInCreationException(beanName, ex.toString());
}
catch (Throwable ex) {throw new BeanCreationException(beanName, "FactoryBean threw exception on object creation", ex);
}
// Do not accept a null value for a FactoryBean that's not fully
// initialized yet: Many FactoryBeans just return null then.
if (object == null) {if (isSingletonCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName, "FactoryBean which is currently in creation returned null from getObject");
}
object = new NullBean();}
return object;
}
调用 ObjectFactory 的后处理器
2.4 缓存中不存在,重新开始 bean 的加载 getSingleton
之前讲了如何从缓存中加载单例 bean,但是如果缓存中不存在,就需要重新开始 bean 的加载
sharedInstance = getSingleton(beanName, () -> { try {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; } });
使用重载 (方法名相同,参数不同) 的方法实现 bean 的加载
以下代码实际上是在单例创建前后做一些准备和处理操作,真正的获取单例 bean 的方法是在 singletonFactory.getObject(); 中实现的,代码包括以下内容
1. 检查缓存是否加载过
2. 如果没有加载,记录 beanName 的正在加载状态
3. 加载单例前记录加载状态
4. 通过调用参数传入的 ObjectFactory 的个体 Object 方法实例化 bean
5. 加载单例后的处理方法调用
6. 将结果记录至缓存并删除加载 bean 过程中记录的所有辅助状态
7. 返回处理结果
package org.springframework.beans.factory.support;
public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {
/**
* Return the (raw) singleton object registered under the given name,
* creating and registering a new one if none registered yet.
* @param beanName the name of the bean
* @param singletonFactory the ObjectFactory to lazily create the singleton
* with, if necessary
* @return the registered singleton object
* 返回以给定名称注册的(原始)单例对象,* 创建并注册一个新的(如果尚未注册)。* @param beanName bean 的名称
* @param singletonFactory 用于延迟创建单例的 ObjectFactory
* 与(如果需要)* @返回注册的单例对象
*/
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {Assert.notNull(beanName, "Bean name must not be null");
//singletonObjects 是全局变量,需要锁定
synchronized (this.singletonObjects) {
// 首先检查对应的 bean 是否是已经加载过,因为 singleton 模式是复用已创建的 bean
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
// 为空才进行 singleton 的初始化
if (this.singletonsCurrentlyInDestruction) {
// 如果 beanName 正在创建中
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 + "'");
}
// 单例创建前的操作
beforeSingletonCreation(beanName);
boolean newSingleton = false;
boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
if (recordSuppressedExceptions) {
// 异常列表,记录异常原因
this.suppressedExceptions = new LinkedHashSet<>();}
try {
// 初始化 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.
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;}
// 单例创建后的操作
afterSingletonCreation(beanName);
}
if (newSingleton) {
// 如果是新的单例 bean,就加入缓存,将结果记录至缓存并删除家长在 bean 过程中各种辅助状态
addSingleton(beanName, singletonObject);
}
}
return singletonObject;
}
}
/**
* Register an Exception that happened to get suppressed during the creation of a
* singleton bean instance, e.g. a temporary circular reference resolution problem.
* @param ex the Exception to register
* 注册一个在创建过程中被抑制的异常
* 单例 bean 实例,例如 临时循环参考解析问题。* @param 例外注册
*/
protected void onSuppressedException(Exception ex) {synchronized (this.singletonObjects) {if (this.suppressedExceptions != null) {this.suppressedExceptions.add(ex);
}
}
}
2.4.1 单例创建前的操作 beforeSingletonCreation
beforeSingletonCreation(beanName);
/** Names of beans that are currently in creation 正在创建的 bean 名称 */
private final Set<String> singletonsCurrentlyInCreation =
Collections.newSetFromMap(new ConcurrentHashMap<>(16));
/** Names of beans currently excluded from in creation checks 排除校验的 bean 名称 */
private final Set<String> inCreationCheckExclusions =
Collections.newSetFromMap(new ConcurrentHashMap<>(16));
/**
* Callback before singleton creation.
* <p>The default implementation register the singleton as currently in creation.
* @param beanName the name of the singleton about to be created
* @see #isSingletonCurrentlyInCreation
*/
protected void beforeSingletonCreation(String beanName) {
// 将正要创建的 bean 记录在缓存中,这样可以进行循环依赖检测
// 如果 inCreationCheckExclusions 不包含 beanName 且 singletonsCurrentlyInCreation 新增失败,set 无法新增已存在的对象
if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) {throw new BeanCurrentlyInCreationException(beanName);
}
}
2.4.2 创建 bean 操作 createBean
bean 的加载逻辑实际是在传入的 ObjectFactory 类型的参数 singletonFactory 中定义的,实际只是调用了 createBean 方法
之前讲了如何从缓存中加载单例 bean,但是如果缓存中不存在,就需要重新开始 bean 的加载
sharedInstance = getSingleton(beanName, () -> { try {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; } });
1. 根据设置的 class 属性或者根据 className 解析 class
2. 对 override 属性进行标记及验证
在 Spring 中存在 lookuo-method 和 replace-method,这两个配置的加载是将配置统一存放在 BeanDefinition 中的 methodOverrides 属性里,而这个函数的操作也是针对这两个配置的
3. 应用初始化前的后处理器,解析指定 bean 是否存在初始化前的短路操作
4. 创建 bean
package org.springframework.beans.factory.support;
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
implements AutowireCapableBeanFactory {
/**
* Central method of this class: creates a bean instance,
* populates the bean instance, applies post-processors, etc.
* @see #doCreateBean
*/
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {if (logger.isDebugEnabled()) {logger.debug("Creating instance of bean'" + beanName + "'");
}
RootBeanDefinition mbdToUse = mbd;
// Make sure bean class is actually resolved at this point, and
// clone the bean definition in case of a dynamically resolved Class
// which cannot be stored in the shared merged bean definition.
// 确保此时确实解析了 bean 类,并且
// 在动态解析的类的情况下克隆 bean 定义
// 无法存储在共享的合并 bean 定义中。// 反射解析 bean 类
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
// Prepare method overrides.
try {
// 验证及准备覆盖的方法
mbdToUse.prepareMethodOverrides();}
catch (BeanDefinitionValidationException ex) {throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
beanName, "Validation of method overrides failed", ex);
}
try {
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
// 给 BeanPostProcessors 一个机会来返回代理来替代真正的实例
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
// 短路判断,如果经过前置处理后的返回结果不为空,会直接忽略后续的 bean 而直接返回,AOP 就是基于这里判断的
if (bean != null) {return bean;}
}
catch (Throwable ex) {throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
"BeanPostProcessor before instantiation of bean failed", ex);
}
try {
// 创建 bean
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isDebugEnabled()) {logger.debug("Finished creating instance of bean'" + beanName + "'");
}
return beanInstance;
}
catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
// A previously detected exception with proper bean creation context already,
// or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
throw ex;
}
catch (Throwable ex) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
}
}
2.4.2.1 处理 override 属性 prepareMethodOverrides
mbdToUse.prepareMethodOverrides();
之前提到过,在 Spring 中配置了 lookup-method 和 replace-method 这两个配置功能,这两个配置其实就是将配置统一存放在 BeanDefinition 中的 methodOverrides 属性里,这两个功能的实现原理是在 bean 实例化的时候如果检测到存在 methodOverrides 属性,会动态的为当前 bean 生成代理并使用对应的拦截器为 bean 做增强处理,相关逻辑实现在 bean 的实例化部分介绍
对于方法的匹配来说,如果一个类中存在若干个重载的方法,那么在函数调用及增强的时候需要根据参数类型进行匹配,来确认最终调用的是哪个函数,但是 Spring 将一部分匹配工作在这里完成了,如果对应类中的对应方法名个数为 1,就可以直接找到对应的方法,而不需要进行匹配参数的认证,还可以提前对方法的存在进行验证
/**
* Validate and prepare the method overrides defined for this bean.
* Checks for existence of a method with the specified name.
* @throws BeanDefinitionValidationException in case of validation failure
* 验证并准备为此 bean 定义的方法替代。* 检查是否存在具有指定名称的方法。* @如果验证失败,则抛出 BeanDefinitionValidationException
*/
public void prepareMethodOverrides() throws BeanDefinitionValidationException {
// Check that lookup methods exists.
if (hasMethodOverrides()) {Set<MethodOverride> overrides = getMethodOverrides().getOverrides();
synchronized (overrides) {for (MethodOverride mo : overrides) {prepareMethodOverride(mo);
}
}
}
}
/**
* Validate and prepare the given method override.
* Checks for existence of a method with the specified name,
* marking it as not overloaded if none found.
* @param mo the MethodOverride object to validate
* @throws BeanDefinitionValidationException in case of validation failure
* 验证并准备给定的方法重写。* 检查是否存在具有指定名称的方法,* 如果未找到,则将其标记为未过载。* @param mo MethodOverride 对象进行验证
* @如果验证失败,则抛出 BeanDefinitionValidationException
*/
protected void prepareMethodOverride(MethodOverride mo) throws BeanDefinitionValidationException {
// 获取对应类中对应方法名称和个数
int count = ClassUtils.getMethodCountForName(getBeanClass(), mo.getMethodName());
if (count == 0) {
throw new BeanDefinitionValidationException("Invalid method override: no method with name'" + mo.getMethodName() +
"'on class [" + getBeanClassName() + "]");
}
else if (count == 1) {
// Mark override as not overloaded, to avoid the overhead of arg type checking.
// 标记 MethodOverride 暂时未被覆盖,避免参数类型检查的开销
mo.setOverloaded(false);
}
}
2.4.2.2 实例化的前置处理 resolveBeforeInstantiation
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
在真正调用 doCreate 方法创建 bean 的实例前使用了这样一个方法 resolveBeforeInstantiation(beanName,mbd)对 BeanDefinigiton 中的属性做了前置处理,如果前置处理的结果不为空,会直接忽略后续 Bean 的创建而直接返回结果
/**
* Apply before-instantiation post-processors, resolving whether there is a
* before-instantiation shortcut for the specified bean.
* @param beanName the name of the bean
* @param mbd the bean definition for the bean
* @return the shortcut-determined bean instance, or {@code null} if none
* 应用实例化后处理器,以解决是否存在
* 指定 bean 的实例化前快捷方式。* @param beanName bean 的名称
* @param mbd bean 的 bean 定义
* @返回快捷方式确定的 bean 实例;如果没有,则返回{@code null}
*/
@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 = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
if (bean != null) {bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
}
mbd.beforeInstantiationResolved = (bean != null);
}
return bean;
}
2.4.2.3 实例化前的后处理器调用 applyBeanPostProcessorsBeforeInstantiation
bean 的实例化调用,也就是将 AbstractBeanDefinition 转换为 BeanWapper 前的处理,给子类一个修改 BeanDefinition 的机会,也就是当程序经过这个方法后,bean 已经不是我们认为的 bean 了,而是成为了一个经过处理的代理 bean,可能是通过 cglib 生成,也可能是通过其他技术生成的,bean 实例化前后会调用后处理器的方法进行处理
/**
* Apply InstantiationAwareBeanPostProcessors to the specified bean definition
* (by class and name), invoking their {@code postProcessBeforeInstantiation} methods.
* <p>Any returned object will be used as the bean instead of actually instantiating
* the target bean. A {@code null} return value from the post-processor will
* result in the target bean being instantiated.
* @param beanClass the class of the bean to be instantiated
* @param beanName the name of the bean
* @return the bean object to use instead of a default instance of the target bean, or {@code null}
* @see InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation
* 将 InstantiationAwareBeanPostProcessors 应用于指定的 bean 定义
*(按类和名称),调用其 {@code postProcessBeforeInstantiation} 方法。* <p> 任何返回的对象都将用作 bean,而不是实际实例化
* 目标 bean。后处理器的 {@code null} 返回值将
* 导致目标 bean 被实例化。* @param beanClass 要实例化的 bean 的类
* @param beanName bean 的名称
* @返回要使用的 bean 对象,而不是目标 bean 的默认实例,或者{@code null}
* @see InstantiationAwareBeanPostProcessor#
*/
@Nullable
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {for (BeanPostProcessor bp : getBeanPostProcessors()) {if (bp instanceof InstantiationAwareBeanPostProcessor) {InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
if (result != null) {return result;}
}
}
return null;
}
循环依赖
2.4.2.4 创建 bean doCreateBean
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
常规 bean 的创建操作在此完成
package org.springframework.beans.factory.support;
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
implements AutowireCapableBeanFactory {
/**
* Actually create the specified bean. Pre-creation processing has already happened
* at this point, e.g. checking {@code postProcessBeforeInstantiation} callbacks.
* <p>Differentiates between default bean instantiation, use of a
* factory method, and autowiring a constructor.
* @param beanName the name of the bean
* @param mbd the merged bean definition for the bean
* @param args explicit arguments to use for constructor or factory method invocation
* @return a new instance of the bean
* @throws BeanCreationException if the bean could not be created
* @see #instantiateBean
* @see #instantiateUsingFactoryMethod
* @see #autowireConstructor
* 实际创建指定的 bean。预创建处理已经发生
* 在这一点上,例如 检查 {@code postProcessBeforeInstantiation} 回调。* <p> 区分默认的 bean 实例化,使用
* 工厂方法,并自动装配构造函数。* @param beanName bean 的名称
* @param mbd 该 bean 的合并 bean 定义
* @param args 用于构造函数或工厂方法调用的显式参数
* @返回 bean 的新实例
* @throws BeanCreationException 如果无法创建 bean
* @请参阅 #instantiateBean
* @see #instantiateUsingFactoryMethod
* @请参阅 #autowireConstructor
*/
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
// Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
// 从缓存中移除 bean,因为要创建新的 bean 了
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
// 根据指定 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);
}
catch (Throwable ex) {throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing of merged bean definition failed", ex);
}
mbd.postProcessed = true;
}
}
// Eagerly cache singletons to be able to resolve circular references
// even when triggered by lifecycle interfaces like BeanFactoryAware.
// 是否需要提早曝光:单例 & 允许循环依赖 & 当前 bean 正在创建中,检测循环依赖
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {if (logger.isDebugEnabled()) {
logger.debug("Eagerly caching bean'" + beanName +
"'to allow for resolving potential circular references");
}
// 为避免后期循环依赖,可以在 bean 初始化完成前将创建实例的 ObjectFactory 加入工厂,其他 bean 引用此 bean 时直接从 ObjectFactory 获取 bean
//getEarlyBeanReference 对 bean 再一次依赖引用,主要应用 SmartInstantiationAware BeanPost Processor 其中我们熟悉的 AOP 就是在这里将 advance 动态织入 bean 中的,如果没有就直接返回 bean,不做任何处理
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
// Initialize the bean instance.
Object exposedObject = bean;
try {
// 对 bean 进行填充, 将各个属性值注入,其中,可能存在依赖于其他 bean 的属性,则会递归给初始依赖 bean
populateBean(beanName, mbd, instanceWrapper);
// 调用初始化方法,如 init-method
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);
}
}
if (earlySingletonExposure) {Object earlySingletonReference = getSingleton(beanName, false);
//earlySingletonReference 只有在检测到有依赖循环的情况下才会不为空
if (earlySingletonReference != null) {
// 如果 exposedObject 没有在初始化方法中被改变,也就是没有被增强
if (exposedObject == bean) {exposedObject = earlySingletonReference;}
else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {String[] dependentBeans = getDependentBeans(beanName);
Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
for (String dependentBean : dependentBeans) {
// 检测依赖
if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {actualDependentBeans.add(dependentBean);
}
}
// 因为 bean 创建后其所依赖的 bean 一定是已经创建的,actualDependentBeans 不为空则表示当前 bean 创建后其依赖的 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" +
"'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
}
}
}
}
// Register bean as disposable.
try {
// 根据 scopse 注册 bean
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
}
整个程序的思路
1. 如果是单例需要先清除缓存
2. 实例化 bean,将 BeanDefinition 转换为 BeanWrapper
转换是一个复杂的过程
- 如果存在工厂方法则使用工厂方法进行初始化
- 一个类有多个构造函数,每个构造函数都有不同的参数,所以需要根据参数锁定构造函数并进行初始化
- 如果既不存在工厂方法也不存在带有参数的构造函数,则使用默认的构造函数进行 bean 的初始化
3.MergedBeanDefinitionPostProcessor 的应用
bean 合并后的处理,Autowired 注解正是通过此方法实现诸如类型的预解析
4. 依赖处理
在 Spring 中会有循环依赖的情况,例如 A 中存在 B 的属性,而 B 中又存在 A 的属性,这样会构成一个循环依赖,此时如果 A 和 B 都是单例,那么在 Spring 中的处理方式就是当创建 B 的时候,涉及自动注入 A 的步骤时,并不是直接去创建 A,而是通过放入缓存中的 ObjectFactory 来创建实例,这样就解决了循环依赖的问题
5. 属性填充, 将所有属性填充置 bean 的实例中
6. 循环依赖检查
之前有提到过,在 Spring 中解决循环依赖只针对单例有效,而对于 prototype 的 bean,Spring 没有好的解决方法,唯一要做的就是抛出异常,这个步骤会检查以及加载的 bean 是否已经出现了依赖循环,并判断是否需要抛出异常
7. 注册 DisposableBean
如果配置了 destroy-method, 这里需要注册以便于在销毁时调用
8. 完成创建步骤并返回
创建 bean 的实例
2.4.2.4.1 创建 bean 实例 createBeanInstance
/**
* Create a new instance for the specified bean, using an appropriate instantiation strategy:
* factory method, constructor autowiring, or simple instantiation.
* @param beanName the name of the bean
* @param mbd the bean definition for the bean
* @param args explicit arguments to use for constructor or factory method invocation
* @return a BeanWrapper for the new instance
* @see #obtainFromSupplier
* @see #instantiateUsingFactoryMethod
* @see #autowireConstructor
* @see #instantiateBean
* 使用适当的实例化策略为指定的 bean 创建一个新实例:* 工厂方法,构造函数自动装配或简单实例化。* @param beanName bean 的名称
* @param mbd bean 的 bean 定义
* @param args 用于构造函数或工厂方法调用的显式参数
* @返回新实例的 BeanWrapper
* @请参阅 #obtainFromSupplier
* @see #instantiateUsingFactoryMethod
* @请参阅 #autowireConstructor
* @请参阅 #instantiateBean
*/
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
// Make sure bean class is actually resolved at this point.
// 反射解析 class
Class<?> beanClass = resolveBeanClass(mbd, beanName);
//beanClass 需要时 public 的
if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
}
// 从给的的提供者获取 bean 实例
Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
if (instanceSupplier != null) {return obtainFromSupplier(instanceSupplier, beanName);
}
// 如果工厂方法不为空则使用工厂方法初始化策略
if (mbd.getFactoryMethodName() != null) {return instantiateUsingFactoryMethod(beanName, mbd, args);
}
// Shortcut when re-creating the same bean...
boolean resolved = false;// 是否解析过
boolean autowireNecessary = false;// 是否需要自动注入
if (args == null) {synchronized (mbd.constructorArgumentLock) {
// 一个类有多个构造函数,每个构造函数都有不同的参数,所以调用前需要根据参数锁定构造函数或对应的工厂方法
if (mbd.resolvedConstructorOrFactoryMethod != null) {
resolved = true;
autowireNecessary = mbd.constructorArgumentsResolved;
}
}
}
// 如果已经解析过则使用解析好的构造函数方法不需要再次锁定
if (resolved) {if (autowireNecessary) {
// 构造函数自动注入
return autowireConstructor(beanName, mbd, null, null);
}
else {
// 使用默认构造函数构造
return instantiateBean(beanName, mbd);
}
}
// Need to determine the constructor...
// 需要根据参数解析构造函数
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null ||
mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
// 构造函数自动注入
return autowireConstructor(beanName, mbd, ctors, args);
}
// No special handling: simply use no-arg constructor.
// 使用默认构造函数构造
return instantiateBean(beanName, mbd);
}
1. 如果在 RootBeanDefinition 中存在 factoryMethodName 属性,或者在配置文件中配置了 factory-method 方法, 那么 Spring 会尝试使用 instantiateUsingFactoryMethod(beanName, mbd, args)方法根据 RootBeanDefinition 中的配置生成 bean 的实例
2. 解析构造函数并进行构造函数的初始化,因为每个 bean 对应的类中可能有多个构造函数,而每个构造函数的参数不同,Spring 在根据参数及类型取判断最终会使用哪个构造函数进行实例化,但是,判断的过程是个比较消耗性能的步骤,所以采用缓存机制,如果已经解析过了就不再重复解析,而是直接从 RootBeanDefinition 中的属性 reslovedConstructorOfFactoryMethod 缓存的值去取,否则需要再次解析,并将解析的结果添加到 RootBeanDefinition 的属性 reslovedConstructorOrFactoryMethod 中
2.4.2.4.2 带参数的构造函数实例化过程 utowireConstructor
对于实例的创建 Spring 中分了两种情况,一种是通用的实例化,另一种是带有参数的实例化,带有参数的实例化相当复杂,因为存在不确定性,所以在对应参数判断上有大量工作
/**
* "autowire constructor" (with constructor arguments by type) behavior.
* Also applied if explicit constructor argument values are specified,
* matching all remaining arguments with beans from the bean factory.
* <p>This corresponds to constructor injection: In this mode, a Spring
* bean factory is able to host components that expect constructor-based
* dependency resolution.
* @param beanName the name of the bean
* @param mbd the bean definition for the bean
* @param ctors the chosen candidate constructors
* @param explicitArgs argument values passed in programmatically via the getBean method,
* or {@code null} if none (-> use constructor argument values from bean definition)
* @return a BeanWrapper for the new instance
*“自动装配构造函数”(按类型带有构造函数参数)的行为。* 如果指定了显式构造函数参数值,则同样适用
* 将所有剩余的参数与 bean 工厂中的 bean 匹配。* <p> 这对应于构造函数注入:在这种模式下,一个 Spring
* bean factory 能够托管期望基于构造函数的组件
* 依赖关系解析。* @param beanName bean 的名称
* @param mbd bean 的 bean 定义
* @param 约束所选的候选构造函数
* @paramexplicitArgs 参数值通过 getBean 方法以编程方式传递,* 或{@code null}(如果没有)(-> 使用 bean 定义中的构造函数参数值)* @返回新实例的 BeanWrapper
*/
protected BeanWrapper autowireConstructor(String beanName, RootBeanDefinition mbd, @Nullable Constructor<?>[] ctors, @Nullable Object[] explicitArgs) {return new ConstructorResolver(this).autowireConstructor(beanName, mbd, ctors, explicitArgs);
}
package org.springframework.beans.factory.support;
/**
* "autowire constructor" (with constructor arguments by type) behavior.
* Also applied if explicit constructor argument values are specified,
* matching all remaining arguments with beans from the bean factory.
* <p>This corresponds to constructor injection: In this mode, a Spring
* bean factory is able to host components that expect constructor-based
* dependency resolution.
* @param beanName the name of the bean
* @param mbd the merged bean definition for the bean
* @param chosenCtors chosen candidate constructors (or {@code null} if none)
* @param explicitArgs argument values passed in programmatically via the getBean method,
* or {@code null} if none (-> use constructor argument values from bean definition)
* @return a BeanWrapper for the new instance
*“自动装配构造函数”(按类型带有构造函数参数)的行为。* 如果指定了显式构造函数参数值,则同样适用
* 将所有剩余的参数与 bean 工厂中的 bean 匹配。* <p> 这对应于构造函数注入:在这种模式下,一个 Spring
* bean factory 能够托管期望基于构造函数的组件
* 依赖关系解析。* @param beanName bean 的名称
* @param mbd 该 bean 的合并 bean 定义
* @param selectedCtors 选择了候选构造函数(如果没有,则为{@code null})* @paramexplicitArgs 参数值通过 getBean 方法以编程方式传递,* 或{@code null}(如果没有)(-> 使用 bean 定义中的构造函数参数值)* @返回新实例的 BeanWrapper
*/
public BeanWrapper autowireConstructor(final String beanName, final RootBeanDefinition mbd,
@Nullable Constructor<?>[] chosenCtors, @Nullable final Object[] explicitArgs) {BeanWrapperImpl bw = new BeanWrapperImpl();
this.beanFactory.initBeanWrapper(bw);
Constructor<?> constructorToUse = null;
ArgumentsHolder argsHolderToUse = null;
Object[] argsToUse = null;
//explicitArgs 通过 getBean 方法传入
// 如果 getBean 方法调用的时候指定方法参数那么直接使用指定的构造函数参数
if (explicitArgs != null) {argsToUse = explicitArgs;}
else {
// 如果在 getBean 方法时候没有指定则尝试总配置文件中解析
Object[] argsToResolve = null;
// 尝试从缓存中获取参数
synchronized (mbd.constructorArgumentLock) {constructorToUse = (Constructor<?>) mbd.resolvedConstructorOrFactoryMethod;
if (constructorToUse != null && mbd.constructorArgumentsResolved) {
// Found a cached constructor...
// 从缓存中获取的可能是初始的参数也可能是最终的参数,需要经过类型转换器过滤,保证类型对应
argsToUse = mbd.resolvedConstructorArguments;
if (argsToUse == null) {
// 缓存中没有获取到参数
// 配置的构造函数参数
argsToResolve = mbd.preparedConstructorArguments;
}
}
}
// 如果缓存中存在
if (argsToResolve != null) {// 解析参数类型,如果给定方法的构造函数 A(int,int)会通过此方法将配置中的 ("1","1") 转换为 (1,1) 缓存中的值可能是原始值,也可能是最终值
argsToUse = resolvePreparedArguments(beanName, mbd, bw, constructorToUse, argsToResolve);
}
}
// 没有被缓存
if (constructorToUse == null) {
// Need to resolve the constructor.
// 是否自动注入
boolean autowiring = (chosenCtors != null ||
mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR);
ConstructorArgumentValues resolvedValues = null;
int minNrOfArgs;
if (explicitArgs != null) {minNrOfArgs = explicitArgs.length;}
else {
// 提取配置文件中配置的构造函数参数
ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues();
// 用于承载解析后 的构造函数参数的值
resolvedValues = new ConstructorArgumentValues();
// 能够解析到的参数个数
minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);
}
// Take specified constructors, if any.
Constructor<?>[] candidates = chosenCtors;
if (candidates == null) {Class<?> beanClass = mbd.getBeanClass();
try {candidates = (mbd.isNonPublicAccessAllowed() ?
beanClass.getDeclaredConstructors() : beanClass.getConstructors());
}
catch (Throwable ex) {throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Resolution of declared constructors on bean Class [" + beanClass.getName() +
"] from ClassLoader [" + beanClass.getClassLoader() + "] failed", ex);
}
}
// 排序给定的构造函数,public 构造函数优先排列,按照构造函数数量降序,然后是非 public 构造函数,按照后遭函数数量降序
AutowireUtils.sortConstructors(candidates);
int minTypeDiffWeight = Integer.MAX_VALUE;
Set<Constructor<?>> ambiguousConstructors = null;
LinkedList<UnsatisfiedDependencyException> causes = null;
for (Constructor<?> candidate : candidates) {Class<?>[] paramTypes = candidate.getParameterTypes();
if (constructorToUse != null && argsToUse.length > paramTypes.length) {
// Already found greedy constructor that can be satisfied ->
// do not look any further, there are only less greedy constructors left.
// 如果已经找到选用的构造函数或者需要的参数个数小于当前的构造函数参数个数则终止,因为已经按照参数个数降序排列
break;
}
if (paramTypes.length < minNrOfArgs) {
// 参数个数不相等
continue;
}
ArgumentsHolder argsHolder;
if (resolvedValues != null) {
// 有参数则根据参数值构造对应参数类型的参数
try {
// 注释上获取参数名称
String[] paramNames = ConstructorPropertiesChecker.evaluate(candidate, paramTypes.length);
if (paramNames == null) {
// 获取参数名称探索器
ParameterNameDiscoverer pnd = this.beanFactory.getParameterNameDiscoverer();
if (pnd != null) {
// 获取指定构造函数的参数名称
paramNames = pnd.getParameterNames(candidate);
}
}
// 根据名称和数据类型创建参数持有者
argsHolder = createArgumentArray(beanName, mbd, resolvedValues, bw, paramTypes, paramNames,
getUserDeclaredConstructor(candidate), autowiring);
}
catch (UnsatisfiedDependencyException ex) {if (this.beanFactory.logger.isTraceEnabled()) {
this.beanFactory.logger.trace("Ignoring constructor [" + candidate + "] of bean'" + beanName + "':" + ex);
}
// Swallow and try next constructor.
if (causes == null) {causes = new LinkedList<>();
}
causes.add(ex);
continue;
}
}
else {
// Explicit arguments given -> arguments length must match exactly.
if (paramTypes.length != explicitArgs.length) {continue;}
// 构造函数没有参数的情况下
argsHolder = new ArgumentsHolder(explicitArgs);
}
// 检测是否有不确定性的构造函数存在,例如不同构造函数的参数为父子类型
int typeDiffWeight = (mbd.isLenientConstructorResolution() ?
argsHolder.getTypeDifferenceWeight(paramTypes) : argsHolder.getAssignabilityWeight(paramTypes));
// Choose this constructor if it represents the closest match.
// 如果它代表着当前最接近的匹配则选择作为构造函数
if (typeDiffWeight < minTypeDiffWeight) {
constructorToUse = candidate;
argsHolderToUse = argsHolder;
argsToUse = argsHolder.arguments;
minTypeDiffWeight = typeDiffWeight;
ambiguousConstructors = null;
}
else if (constructorToUse != null && typeDiffWeight == minTypeDiffWeight) {if (ambiguousConstructors == null) {ambiguousConstructors = new LinkedHashSet<>();
ambiguousConstructors.add(constructorToUse);
}
ambiguousConstructors.add(candidate);
}
}
if (constructorToUse == null) {if (causes != null) {UnsatisfiedDependencyException ex = causes.removeLast();
for (Exception cause : causes) {this.beanFactory.onSuppressedException(cause);
}
throw ex;
}
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Could not resolve matching constructor" +
"(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities)");
}
else if (ambiguousConstructors != null && !mbd.isLenientConstructorResolution()) {throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Ambiguous constructor matches found in bean'" + beanName + "'" +"(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities): " +
ambiguousConstructors);
}
if (explicitArgs == null) {
// 将解析的构造函数加入缓存
argsHolderToUse.storeCache(mbd, constructorToUse);
}
}
try {final InstantiationStrategy strategy = beanFactory.getInstantiationStrategy();
Object beanInstance;
if (System.getSecurityManager() != null) {
final Constructor<?> ctorToUse = constructorToUse;
final Object[] argumentsToUse = argsToUse;
beanInstance = AccessController.doPrivileged((PrivilegedAction<Object>) () ->
strategy.instantiate(mbd, beanName, beanFactory, ctorToUse, argumentsToUse),
beanFactory.getAccessControlContext());
}
else {beanInstance = strategy.instantiate(mbd, beanName, this.beanFactory, constructorToUse, argsToUse);
}
// 将构建的实例加入 BeanWrapper 中
bw.setBeanInstance(beanInstance);
return bw;
}
catch (Throwable ex) {throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Bean instantiation via constructor failed", ex);
}
}
构造函数参数的确定
根据 explicitArgs 参数判断
如果传入放入参数 explicitArgs 不为空,就可以直接确定参数,因为 explicitArgs 参数是在调用 Bean 的时候用户指定的,在 BeanFactory 类中存在这样的方法
Object getBean(String name,Object …args) throws BeansException;
在获取 bean 的时候,用户不但可以指定 bean 的名称还可以指定 bean 所对应类的构造函数或者工厂方法的参数,主要用于静态工厂方法的调用,而这里是需要给定完全匹配的参数的,所以,便可以判断,如过传入参数 explicitArgs 不为空,则可以确定构造函数就是它
从缓存中获取
除此之外,确定参数的办法如果之前已经分析过,也就是说构造函数参数已经记录在缓存中,那么便可以直接拿来使用,而且在缓存中缓存的可能是参数的最终类型也可能是参数的初始类型,例如构造函数要求 int 类型,原始参数可能是 String 类型的 ”1″,那么即使在缓存中得到了参数,也需要经过类型转换器的过滤以保证参数类型和构造器参数类型完全匹配
配置文件获取
如果不能根据传入参数 explicitArgs 确定构造函数的参数也无法在缓存中得到相关信息,就只能开始新一轮分析了,分析从获取,分析从获取配置文件中配置的构造函数信息开始,经过之前的分析,我们知道,Spring 中配置文件中的信息经过转换都会通过 BeanDefinition 实例承载,也就是参数 mbd 中包含,那么可以通过调用 mdb.getConstructorArgumentValues()来获取配置的构造函数信息,有了配置中的信息便可以获取对应的参数信息了,获取参数值信息包括直接指定值,如:直接指定构造函数中某个值为原始类型 String 类型,或者是一个对其它 bean 的引用,而这一处理委托给 resloveConstructorArguments 方法,并返回能解析到的参数个数
构造函数的确定
经过第一步后已经确定构造函数的参数,结下来的任务就是根据构造函数参数在所构造函数中锁定对应的构造函数,而匹配的方法就是根据参数个数匹配,所以在匹配之前需要先对 构造函数按照 public 构造函数优先参数数量降序,非 public 构造函数参数数量降序,这样可以在遍历的情况下迅速判断排在后面的构造函数参数个数是否符合条件, 由于在配置文件中并不是唯一限制使用参数位置索引的方式去创建,同样还支持指定参数名称进行设置参数值的情况,如 <constructor-arg name=”aa”>, 那么这种情况就需要首先确定构造函数中的参数名称
获取构造函数中参数名称的方式有两种,一种是通过注解的方式直接获取,另一种就是使用 Spring 中提供的工具类 ParameterNameDiscoverer 来获取,构造函数,参数名称,参数类型,参数值都后就可以锁定构造函数以及转换对应的参数类型了
根据确定的构造函数转换对应的参数类型,主要使用 Spring 中提供的类型转换器或者用户提供的自定义准换器进行准换
构造函数不确定性单验证
有时候即使构造函数,参数名称,参数类型,参数值都确定了也不一定会直接锁定构造函数,不同的构造函数参数为父子关系,所以 Spring 在最后又做了一次验证
根据实例化策略以及得到的构造函数以及构造函数参数实例化 bean
2.4.2.4.3 不带参数的构造函数实例化过程 instantiateBean
/**
* Instantiate the given bean using its default constructor.
* @param beanName the name of the bean
* @param mbd the bean definition for the bean
* @return a BeanWrapper for the new instance
* 使用其默认构造函数实例化给定的 bean。* @param beanName bean 的名称
* @param mbd bean 的 bean 定义
* @返回新实例的 BeanWrapper
*/
protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
try {
Object beanInstance;
final BeanFactory parent = this;
if (System.getSecurityManager() != null) {beanInstance = AccessController.doPrivileged((PrivilegedAction<Object>) () ->
getInstantiationStrategy().instantiate(mbd, beanName, parent),
getAccessControlContext());
}
else {beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
}
BeanWrapper bw = new BeanWrapperImpl(beanInstance);
initBeanWrapper(bw);
return bw;
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
}
}
2.4.2.4.4 实例化策略 instantiate
instantiate(mbd, beanName, parent)
如果判断 bd.hasMethodOverrides()为空,也就是用户没有使用 replace 或者 lookup 配置方法,那么直接使用反射的方式,但是如果使用了这两个特效,在直接使用反射就不合适了,因为需要将这两个配置提供的功能切入进去,所以必须要使用动态代理的方式将包含这俩个特性的所对应的逻辑的拦截增强器设置进去, 这样才可以保证在调用方法的时候会被相应的拦截器增强,返回值为包含拦截器的代理实例
package org.springframework.beans.factory.support;
public class SimpleInstantiationStrategy implements InstantiationStrategy {
@Override
public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
// Don't override the class with CGLIB if no overrides.
// 如果有需要覆盖或者动态替换的方法则需要使用 cglib 进行动态代理,因为可以在创建代理的同时将方法织入类中
// 如果没有需要动态代理的方法,为了方便直接反射就行了
if (!bd.hasMethodOverrides()) {
Constructor<?> constructorToUse;
synchronized (bd.constructorArgumentLock) {constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;
if (constructorToUse == null) {final Class<?> clazz = bd.getBeanClass();
if (clazz.isInterface()) {throw new BeanInstantiationException(clazz, "Specified class is an interface");
}
try {if (System.getSecurityManager() != null) {
constructorToUse = AccessController.doPrivileged((PrivilegedExceptionAction<Constructor<?>>) clazz::getDeclaredConstructor);
}
else {constructorToUse = clazz.getDeclaredConstructor();
}
bd.resolvedConstructorOrFactoryMethod = constructorToUse;
}
catch (Throwable ex) {throw new BeanInstantiationException(clazz, "No default constructor found", ex);
}
}
}
return BeanUtils.instantiateClass(constructorToUse);
}
else {
// Must generate CGLIB subclass.
return instantiateWithMethodInjection(bd, beanName, owner);
}
}
package org.springframework.beans.factory.support;
public class CglibSubclassingInstantiationStrategy extends SimpleInstantiationStrategy {
/**
* Create a new instance of a dynamically generated subclass implementing the
* required lookups.
* @param ctor constructor to use. If this is {@code null}, use the
* no-arg constructor (no parameterization, or Setter Injection)
* @param args arguments to use for the constructor.
* Ignored if the {@code ctor} parameter is {@code null}.
* @return new instance of the dynamically generated subclass
*/
public Object instantiate(@Nullable Constructor<?> ctor, @Nullable Object... args) {Class<?> subclass = createEnhancedSubclass(this.beanDefinition);
Object instance;
if (ctor == null) {instance = BeanUtils.instantiateClass(subclass);
}
else {
try {Constructor<?> enhancedSubclassConstructor = subclass.getConstructor(ctor.getParameterTypes());
instance = enhancedSubclassConstructor.newInstance(args);
}
catch (Exception ex) {throw new BeanInstantiationException(this.beanDefinition.getBeanClass(),
"Failed to invoke constructor for CGLIB enhanced subclass [" + subclass.getName() + "]", ex);
}
}
// SPR-10785: set callbacks directly on the instance instead of in the
// enhanced class (via the Enhancer) in order to avoid memory leaks.
Factory factory = (Factory) instance;
factory.setCallbacks(new Callback[] {NoOp.INSTANCE,
new LookupOverrideMethodInterceptor(this.beanDefinition, this.owner),
new ReplaceOverrideMethodInterceptor(this.beanDefinition, this.owner)});
return instance;
}
2.4.2.4.4 记录创建 bean 的 ObjectFactory addSingletonFactory
earlySingletonExposure:是提早曝光的单例
mbd.isSingleton():代表是否是单例
this.allowCircularReferences:是否允许循环依赖,在配置文件中并没有参数配置,可以通过硬编码或者自定义命名空间进行配置
isSingletonCurrentlyInCreation(beanName):该 bean 是否在创建中,在 Spring 中,会有专门的属性默认为 DefaultSingletonBeanRegistry 的 singletonsCurrentlyInCreation 来记录 bean 的加载状态,在 bean 开始创建前会将 beanName 记录在属性中,在 bean 创建结束后会将 beanName 从属性中移除,不同 scope 的位置记录不一样,我们以 singleton 为例子,在 singleton 下记录属性的位置在 DefaultSingleBeanRegistry 类的 public Object getSingleton(String beanName,ObjectFctory singletonFactory)函数的 beforeSingleCreation(beanName)和 afterSingleCreation(beanName)中,在这两段函数中分别 this.singletonsCurrentlyInCreation.add(beanName)和 this.singletonsCurrentlyInCreation.remove(beanName)
package org.springframework.beans.factory.support;
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
implements AutowireCapableBeanFactory {
// Eagerly cache singletons to be able to resolve circular references
// even when triggered by lifecycle interfaces like BeanFactoryAware.
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {if (logger.isDebugEnabled()) {
logger.debug("Eagerly caching bean'" + beanName +
"'to allow for resolving potential circular references");
}
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
/**
* Add the given singleton factory for building the specified singleton
* if necessary.
* <p>To be called for eager registration of singletons, e.g. to be able to
* resolve circular references.
* @param beanName the name of the bean
* @param singletonFactory the factory for the singleton object
*/
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);
}
}
}
经过以上分析,我们知道 earlySingletonExposure 要满足是否是否单例,是否循环依赖,是否对应的 bean 正在创建,三个条件都满足时才会执行 addSingletonFactory 操作
加入 SingletonFactory 的作用
以 AB 循环依赖为例,类 A 中含有属性 B,而 B 中也有属性 A,初始化过程如下
创建 A 的时候会记录 A 所对应的 beanNam,并将 beanA 的创建工厂加入缓存中,在对 A 的属性进行调用也就是调用 populate 方法的时候又会再一次对 B 进行递归创建,同样的因为 B 中同样存在 A 属性,因此在实例化 B 的 populate 方法中,又会再次初始化 A,也就是图中最后,调用 getBean(A),关建在于,这个函数并不是直接实例化 A,而是去检测缓存中是否有一经创建好的对应 bean,或者是否已经创建号的 ObjectFactory,而此时对于 A 的 ObjectFactory 我们早已创建,所以不会再向后执行,而是直接调用 ObjectFactory 创建 A,,这里最关键的是 ObjectFactory 的实现
/**
* Obtain a reference for early access to the specified bean,
* typically for the purpose of resolving a circular reference.
* @param beanName the name of the bean (for error handling purposes)
* @param mbd the merged bean definition for the bean
* @param bean the raw bean instance
* @return the object to expose as bean reference
* 获得早期访问指定 bean 的参考,* 通常用于解决循环引用的目的。* @param beanName bean 的名称(用于错误处理)* @param mbd 该 bean 的合并 bean 定义
* @param bean 原始 bean 实例
* @返回对象公开为 bean 引用
*/
protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
Object exposedObject = bean;
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {for (BeanPostProcessor bp : getBeanPostProcessors()) {if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
}
}
}
return exposedObject;
}
在 getEarlyBeanReference 函数中并没有太多的处理逻辑,或者除了后处理器调用外没有别的工作,根据以上分析,基本可以理清楚 Spring 处理循环依赖的方法,在 B 中创建依赖 A 时通过 ObjectFactory 提供的实例化方法来中断 A 的属性填充,使 B 中持有的 A 仅仅是刚开始初始化并没有填充任何属性的 A,而初始化 A 的步骤还是在最开始创建 A 的时候进行的,但是因为 A 和 B 中的 A 所表示的属性地址是一样的,所以在 A 中创建好的属性填充可以通 B 中的 A 获取这样就解决了循环依赖问题
2.4.2.4.5 属性注入 populateBean
populateBean(beanName, mbd, instanceWrapper);
在了解循环依赖的时候,我们反复提到了 populateBean 这个函数,也了解了这个函数的主要功能就是属性填充,那么究竟是如何实现的呢
package org.springframework.beans.factory.support;
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
implements AutowireCapableBeanFactory {
/**
* Populate the bean instance in the given BeanWrapper with the property values
* from the bean definition.
* @param beanName the name of the bean
* @param mbd the bean definition for the bean
* @param bw BeanWrapper with bean instance
* 使用属性值填充给定 BeanWrapper 中的 bean 实例
* 来自 bean 定义。* @param beanName bean 的名称
* @param mbd bean 的 bean 定义
* @param bw BeanWrapper 与 bean 实例
*/
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {if (bw == null) {if (mbd.hasPropertyValues()) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
}
else {
// Skip property population phase for null instance.
// 没有可填充的属性
return;
}
}
// Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
// state of the bean before properties are set. This can be used, for example,
// to support styles of field injection.
// 给 InstantiationAwareBeanPostProcessors 最后一次机会在属性设置前改变 bean,可以用来支持属性注入的类型
boolean continueWithPropertyPopulation = true;
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {for (BeanPostProcessor bp : getBeanPostProcessors()) {if (bp instanceof InstantiationAwareBeanPostProcessor) {InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
// 返回值是否为继续填充 bean
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
continueWithPropertyPopulation = false;
break;
}
}
}
}
// 如果后处理器发出停止命令则终止后续执行
if (!continueWithPropertyPopulation) {return;}
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||
mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
// Add property values based on autowire by name if applicable.
// 根据名称自动注入
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {autowireByName(beanName, mbd, bw, newPvs);
}
// Add property values based on autowire by type if applicable.
// 根据类型自动注入
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}
// 后处理器已经初始化
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
// 需要依赖检查
boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE);
if (hasInstAwareBpps || needsDepCheck) {if (pvs == null) {pvs = mbd.getPropertyValues();
}
PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
if (hasInstAwareBpps) {for (BeanPostProcessor bp : getBeanPostProcessors()) {if (bp instanceof InstantiationAwareBeanPostProcessor) {InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
// 对所有需要依赖检查的属性进行处理
pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvs == null) {return;}
}
}
}
if (needsDepCheck) {
// 依赖检查,对应 depends-on 属性 3.0 已弃用
checkDependencies(beanName, mbd, filteredPds, pvs);
}
}
if (pvs != null) {
// 将属性应用到 bean 中
applyPropertyValues(beanName, mbd, bw, pvs);
}
}
在 populateBean 函数中提供了这样的处理流程
1.InstantiationAwareBeanPostProcessor 处理器的 postProcessAfterInstantiation 函数的应用,可以控制程序是否继续进行属性填充
2. 根据注入类型(byName/byType),提取依赖的 bean,并统一存入 PropertyValues 中
3. 应用 InstantiationAwareBeanPostProcessor 处理器的 postProcessPropertyValues 方法,对所有需要检查的属性进行处理, 典型是 RequiredAnnotationBeanPostProcessor 类中对属性的验证
4. 将所有 PropertyValues 中的属性填充至 BeanWrapper 中
依赖注入(autowireByName/autowireByType)
autowireByName(beanName, mbd, bw, newPvs);
上文中提到根据注入类型(byName/byType), 提取依赖的 bean, 并统一存入 PropertyValues 中,首先看下 byName 是如何实现的
2.4.2.4.5.1 根据名称属性填充 autowireByName
/**
* Fill in any missing property values with references to
* other beans in this factory if autowire is set to "byName".
* @param beanName the name of the bean we're wiring up.
* Useful for debugging messages; not used functionally.
* @param mbd bean definition to update through autowiring
* @param bw BeanWrapper from which we can obtain information about the bean
* @param pvs the PropertyValues to register wired objects with
* 使用以下内容填写所有缺少的属性值
* 如果 autowire 设置为“byName”,则此工厂中的其他 bean。* @param beanName 我们要连接的 bean 的名称。* 对于调试消息很有用;未在功能上使用。* @param mbd bean 定义可通过自动装配进行更新
* @param bw BeanWrapper,我们可以从中获取有关 bean 的信息
* @param pvs PropertyValues 以注册有线对象
*/
protected void autowireByName(String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
// 寻找 bw 中需要依赖注入的属性
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.isDebugEnabled()) {
logger.debug("Added autowiring by name from bean name'" + beanName +
"'via property'" + propertyName + "'to bean named'" + propertyName + "'");
}
}
else {if (logger.isTraceEnabled()) {
logger.trace("Not autowiring property'" + propertyName + "'of bean'" + beanName +
"'by name: no matching bean found");
}
}
}
}
找到已经加载的 bean,并递归实例化,从而加入到 pvs 中
2.4.2.4.5.2 根据类型属性填充 autowireByType
autowireByType(beanName, mbd, bw, newPvs);
/**
* Abstract method defining "autowire by type" (bean properties by type) behavior.
* <p>This is like PicoContainer default, in which there must be exactly one bean
* of the property type in the bean factory. This makes bean factories simple to
* configure for small namespaces, but doesn't work as well as standard Spring
* behavior for bigger applications.
* @param beanName the name of the bean to autowire by type
* @param mbd the merged bean definition to update through autowiring
* @param bw BeanWrapper from which we can obtain information about the bean
* @param pvs the PropertyValues to register wired objects with
* 定义“按类型自动装配”(按类型的 Bean 属性)行为的抽象方法。* <p> 这类似于 PicoContainer 的默认值,其中必须恰好有一个 bean
* bean 工厂中属性类型的 *。这使 bean 工厂变得简单易行
* 为小型名称空间配置,但不如标准 Spring 正常工作
* 较大应用程序的行为。* @param beanName 按类型自动装配的 bean 名称
* @param mbd 通过自动装配更新合并的 bean 定义
* @param bw BeanWrapper,我们可以从中获取有关 bean 的信息
* @param pvs PropertyValues 以注册有线对象
*/
protected void autowireByType(String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {TypeConverter converter = getCustomTypeConverter();
if (converter == null) {converter = bw;}
Set<String> autowiredBeanNames = new LinkedHashSet<>(4);
// 寻找 bw 中需要依赖注入的属性
String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
for (String propertyName : propertyNames) {
try {PropertyDescriptor pd = bw.getPropertyDescriptor(propertyName);
// Don't try autowiring by type for type Object: never makes sense,
// even if it technically is a unsatisfied, non-simple property.
if (Object.class != pd.getPropertyType()) {
// 探测指定属性的 set 方法
MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd);
// Do not allow eager init for type matching in case of a prioritized post-processor.
boolean eager = !PriorityOrdered.class.isInstance(bw.getWrappedInstance());
DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager);
// 解析指定 beanName 的属性锁匹配得值,并把解析到的属性名称存储在 autowiredArgument 中,当存在多个封装 bean 时,如 @Autowired private List<A> aList; 将会找到所有匹配 A 类型的 bean 并将其注入
Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter);
if (autowiredArgument != null) {pvs.add(propertyName, autowiredArgument);
}
for (String autowiredBeanName : autowiredBeanNames) {
// 注册依赖
registerDependentBean(autowiredBeanName, beanName);
if (logger.isDebugEnabled()) {
logger.debug("Autowiring by type from bean name'" + beanName + "'via property'" +
propertyName + "'to bean named'" + autowiredBeanName + "'");
}
}
autowiredBeanNames.clear();}
}
catch (BeansException ex) {throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName, propertyName, ex);
}
}
}
实现根据名称自动匹配的第一步是寻找 bw 中需要依赖注入的属性,同样对于根据类型自动匹配的实现来讲,第一步也是寻找 bw 中需要依赖注入的属性,然后遍历这些属性并寻找类型匹配的 bean,其中最复杂的就是寻找类型匹配的 bean,同时,Spring 中提供了对集合类型注入的支持,如使用注解的方式
@Autowired
private List<Test> tests;
Spring 将会把所有与 Test 匹配的类型找出来并注入 tests 属性中,正是由于这一因素所以在 autowireByType 函数中,新建了局部遍历 autowiredBeanNames,用于存储所有依赖的 bean,如果只是对非集合类的属性注入来说,此属性并无用处。
对于寻找类型匹配的逻辑实现封装在了 resloveDependency 函数中
Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter);
@Override
@Nullable
public Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName,
@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {descriptor.initParameterNameDiscovery(getParameterNameDiscoverer());
if (Optional.class == descriptor.getDependencyType()) {
//ObjectFactory 类注入的特殊处理
return createOptionalDependency(descriptor, requestingBeanName);
}
else if (ObjectFactory.class == descriptor.getDependencyType() ||
ObjectProvider.class == descriptor.getDependencyType()) {
//javaxInjectProviderClass 类注入的特殊处理
return new DependencyObjectProvider(descriptor, requestingBeanName);
}
else if (javaxInjectProviderClass == descriptor.getDependencyType()) {return new Jsr330ProviderFactory().createDependencyProvider(descriptor, requestingBeanName);
}
else {Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(descriptor, requestingBeanName);
if (result == null) {
// 通用处理逻辑
result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
}
return result;
}
}
2.4.2.4.5.3 通用处理 doResolveDependency
result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
@Nullable
public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName,
@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor);
try {Object shortcut = descriptor.resolveShortcut(this);
if (shortcut != null) {return shortcut;}
Class<?> type = descriptor.getDependencyType();
// 用于支持 Value 注解
Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);
if (value != null) {if (value instanceof String) {String strVal = resolveEmbeddedValue((String) value);
BeanDefinition bd = (beanName != null && containsBean(beanName) ? getMergedBeanDefinition(beanName) : null);
value = evaluateBeanDefinitionString(strVal, bd);
}
TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
return (descriptor.getField() != null ?
converter.convertIfNecessary(value, type, descriptor.getField()) :
converter.convertIfNecessary(value, type, descriptor.getMethodParameter()));
}
Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
if (multipleBeans != null) {return multipleBeans;}
// 根据属性类型找到 beanFactory 中所有类型的匹配 bean
// 返回值的构成为:key= 匹配的 beanName,value=beanName 对应的实例化后的 bean(通过 getBean(beanName)返回)
Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
if (matchingBeans.isEmpty()) {
// 如果 autowire 的 require 属性为 true 而找到的匹配项为空则只能抛出异常
if (isRequired(descriptor)) {raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
}
return null;
}
String autowiredBeanName;
Object instanceCandidate;
// 找到的匹配 bean 数量大于 1,if (matchingBeans.size() > 1) {autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);
if (autowiredBeanName == null) {if (isRequired(descriptor) || !indicatesMultipleBeans(type)) {return descriptor.resolveNotUnique(type, matchingBeans);
}
else {
// In case of an optional Collection/Map, silently ignore a non-unique case:
// possibly it was meant to be an empty collection of multiple regular beans
// (before 4.3 in particular when we didn't even look for collection beans).
return null;
}
}
instanceCandidate = matchingBeans.get(autowiredBeanName);
}
else {
// We have exactly one match.
Map.Entry<String, Object> entry = matchingBeans.entrySet().iterator().next();
autowiredBeanName = entry.getKey();
instanceCandidate = entry.getValue();}
if (autowiredBeanNames != null) {autowiredBeanNames.add(autowiredBeanName);
}
if (instanceCandidate instanceof Class) {instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this);
}
Object result = instanceCandidate;
if (result instanceof NullBean) {if (isRequired(descriptor)) {raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
}
result = null;
}
if (!ClassUtils.isAssignableValue(type, result)) {throw new BeanNotOfRequiredTypeException(autowiredBeanName, type, instanceCandidate.getClass());
}
return result;
}
finally {ConstructorResolver.setCurrentInjectionPoint(previousInjectionPoint);
}
}
寻找类型匹配的执行顺序的时候,首先尝试使用解析器进行解析,如果解析器没有成功解析,那么可能是使用默认的解析器没有做处理,或是使用了自定义解析器,但是对于集合等类型来说并不在解析范围内,所以再次对不同类型进行不同情况的处理,虽然对于不同类型处理方式不一致,但是大致的思路还是一致的
/**
* Raise a NoSuchBeanDefinitionException or BeanNotOfRequiredTypeException
* for an unresolvable dependency.
*/
private void raiseNoMatchingBeanFound(Class<?> type, ResolvableType resolvableType, DependencyDescriptor descriptor) throws BeansException {checkBeanNotOfRequiredType(type, descriptor);
throw new NoSuchBeanDefinitionException(resolvableType,
"expected at least 1 bean which qualifies as autowire candidate." +
"Dependency annotations:" + ObjectUtils.nullSafeToString(descriptor.getAnnotations()));
}
/**
* Determine the autowire candidate in the given set of beans.
* <p>Looks for {@code @Primary} and {@code @Priority} (in that order).
* @param candidates a Map of candidate names and candidate instances
* that match the required type, as returned by {@link #findAutowireCandidates}
* @param descriptor the target dependency to match against
* @return the name of the autowire candidate, or {@code null} if none found
* 在给定的 bean 组中确定自动装配候选。* <p> 查找 {@code @Primary} 和{@code @Priority}(按此顺序)。* @param candidates 候选人名称和候选人实例的 Map
* 与 {@link #findAutowireCandidates} 返回的类型相匹配
* @param descriptor 要匹配的目标依赖项
* @返回自动接线候选者的名称,如果找不到,则为{@code null}
*/
@Nullable
protected String determineAutowireCandidate(Map<String, Object> candidates, DependencyDescriptor descriptor) {Class<?> requiredType = descriptor.getDependencyType();
String primaryCandidate = determinePrimaryCandidate(candidates, requiredType);
if (primaryCandidate != null) {return primaryCandidate;}
String priorityCandidate = determineHighestPriorityCandidate(candidates, requiredType);
if (priorityCandidate != null) {return priorityCandidate;}
// Fallback
for (Map.Entry<String, Object> entry : candidates.entrySet()) {String candidateName = entry.getKey();
Object beanInstance = entry.getValue();
if ((beanInstance != null && this.resolvableDependencies.containsValue(beanInstance)) ||
matchesBeanName(candidateName, descriptor.getDependencyName())) {return candidateName;}
}
return null;
}
/**
* Determine whether the given candidate name matches the bean name or the aliases
* stored in this bean definition.
* 确定给定的候选名称是否与 bean 名称或别名匹配
* 存储在此 bean 定义中。*/
protected boolean matchesBeanName(String beanName, @Nullable String candidateName) {
return (candidateName != null &&
(candidateName.equals(beanName) || ObjectUtils.containsElement(getAliases(beanName), candidateName)));
}
2.4.2.4.5.4 设置值 applyPropertyValues
applyPropertyValues(beanName, mbd, bw, pvs);
/**
* Apply the given property values, resolving any runtime references
* to other beans in this bean factory. Must use deep copy, so we
* don't permanently modify this property.
* @param beanName the bean name passed for better exception information
* @param mbd the merged bean definition
* @param bw the BeanWrapper wrapping the target object
* @param pvs the new property values
* 应用给定的属性值,解析所有运行时引用
* 该豆工厂中的其他豆。必须使用深层复制,因此我们
* 不要永久修改此属性。* @param beanName 为更好的异常信息而传递的 bean 名称
* @param mbd 合并的 bean 定义
* @param bw 包裹目标对象的 BeanWrapper
* @param pvs 新属性值
*/
protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {if (pvs.isEmpty()) {return;}
if (System.getSecurityManager() != null && bw instanceof BeanWrapperImpl) {((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext());
}
MutablePropertyValues mpvs = null;
List<PropertyValue> original;
if (pvs instanceof MutablePropertyValues) {mpvs = (MutablePropertyValues) pvs;
// 如果 mpvs 中的值已经被转换为对应的类型那么可以直接设置到 beanwapper 中
if (mpvs.isConverted()) {
// Shortcut: use the pre-converted values as-is.
try {bw.setPropertyValues(mpvs);
return;
}
catch (BeansException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Error setting property values", ex);
}
}
original = mpvs.getPropertyValueList();}
else {
// 如果 pvs 并不是使用 MutablePropertyValues 封装的类型,那么使用原始的属性值获取方法
original = Arrays.asList(pvs.getPropertyValues());
}
TypeConverter converter = getCustomTypeConverter();
if (converter == null) {converter = bw;}
// 获取对应的解析器
BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter);
// Create a deep copy, resolving any references for values.
List<PropertyValue> 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();
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);
}
// Possibly store converted value in merged bean definition,
// in order to avoid re-conversion for every created bean instance.
if (resolvedValue == originalValue) {if (convertible) {pv.setConvertedValue(convertedValue);
}
deepCopy.add(pv);
}
else if (convertible && originalValue instanceof TypedStringValue &&
!((TypedStringValue) originalValue).isDynamic() &&
!(convertedValue instanceof Collection || ObjectUtils.isArray(convertedValue))) {pv.setConvertedValue(convertedValue);
deepCopy.add(pv);
}
else {
resolveNecessary = true;
deepCopy.add(new PropertyValue(pv, convertedValue));
}
}
}
if (mpvs != null && !resolveNecessary) {mpvs.setConverted();
}
// Set our (possibly massaged) deep copy.
try {bw.setPropertyValues(new MutablePropertyValues(deepCopy));
}
catch (BeansException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Error setting property values", ex);
}
}
2.4.2.4.6 初始化 bean initializeBean
exposedObject = initializeBean(beanName, exposedObject, mbd);
在配置 bean 时有一个 init-method 的属性,这个属性的作用是在 bean 实例化之前调用 init-method 指定的方法,根据用户业务进行实例化,我们现在进入这个方法了,首先看一下方法的执行位置,Spring 中程序已经执行过 bean 的实例化,并且进行了属性的填充,而就在这时会调用用户设置的初始化方法
/**
* Initialize the given bean instance, applying factory callbacks
* as well as init methods and bean post processors.
* <p>Called from {@link #createBean} for traditionally defined beans,
* and from {@link #initializeBean} for existing bean instances.
* @param beanName the bean name in the factory (for debugging purposes)
* @param bean the new bean instance we may need to initialize
* @param mbd the bean definition that the bean was created with
* (can also be {@code null}, if given an existing bean instance)
* @return the initialized bean instance (potentially wrapped)
* @see BeanNameAware
* @see BeanClassLoaderAware
* @see BeanFactoryAware
* @see #applyBeanPostProcessorsBeforeInitialization
* @see #invokeInitMethods
* @see #
* 初始化给定的 bean 实例,应用工厂回调
* 以及初始化方法和 bean 后处理器。* <p> 从 {@link #createBean} 调用,用于传统定义的 Bean,*,并从 {@link #initializeBean} 获取现有的 Bean 实例。* @param beanName 工厂中的 bean 名称(用于调试)* @param bean 我们可能需要初始化的新 bean 实例
* @param mbd 创建该 bean 的 bean 定义
*(如果给定现有的 bean 实例,也可以是{@code null})* @返回初始化的 bean 实例(可能包装)* @请参阅 BeanNameAware
* @请参阅 BeanClassLoaderAware
* @请参阅 BeanFactoryAware
* @请参阅 #applyBeanPostProcessorsBeforeInitialization
* @see #invokeInitMethods
* @see #applyBeanPostProcessorsAfterInitialization
*/
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {if (System.getSecurityManager() != null) {AccessController.doPrivileged((PrivilegedAction<Object>) () -> {invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {
// 对特殊 bean 的处理,Aware/BeanClassLoadAware/BeanFactoryAware
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
// 应用后处理器
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
// 激活用户自定义的 init 方法
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException((mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
if (mbd == null || !mbd.isSynthetic()) {
// 后处理器应用
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
次函数的主要工作是进行客户设定的初始化方法的调用,但是除此之外还有其他工作
2.4.2.4.6.1 激活 Aware 方法
Spring 提供一写 Aware 相关接口,比如 BeanFactoryAware/ApplocationContextAware/ResourceLoaderAware/ServletContextAware 等,实现这些 Aware 接口的 bean 在被初始化之后,可以获取一些相应的资源,例如实现 BeanFactoryAware 的 bean 在初始后,Spring 容器将会注入 BeanFactory 的实例,而实现 ApplicationContextAware 的 bean,在被初始化后,将会被注入 ApplicationContext 的实例等。
2.4.2.4.6.2 处理器的应用 applyBeanPostProcessorsBeforeInitialization
BeanPostProcessor 给用户充足的权限去更改或者扩展 Spring
@Override
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {Object current = beanProcessor.postProcessBeforeInitialization(result, beanName);
if (current == null) {return result;}
result = current;
}
return result;
}
@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {Object current = beanProcessor.postProcessAfterInitialization(result, beanName);
if (current == null) {return result;}
result = current;
}
return result;
}
2.4.2.4.6.3 激活自定义的 init 方法 invokeInitMethods
invokeInitMethods(beanName, wrappedBean, mbd);
/**
* Give a bean a chance to react now all its properties are set,
* and a chance to know about its owning bean factory (this object).
* This means checking whether the bean implements InitializingBean or defines
* a custom init method, and invoking the necessary callback(s) if it does.
* @param beanName the bean name in the factory (for debugging purposes)
* @param bean the new bean instance we may need to initialize
* @param mbd the merged bean definition that the bean was created with
* (can also be {@code null}, if given an existing bean instance)
* @throws Throwable if thrown by init methods or by the invocation process
* @see #invokeCustomInitMethod
*/
protected void invokeInitMethods(String beanName, final Object bean, @Nullable RootBeanDefinition mbd)
throws Throwable {
// 检查是否是 isInitializingBean, 是的话需要调用 afterPropertiesSet 方法
boolean isInitializingBean = (bean instanceof InitializingBean);
if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {if (logger.isDebugEnabled()) {logger.debug("Invoking afterPropertiesSet() on bean with name'" + beanName + "'");
}
if (System.getSecurityManager() != null) {
try {AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {((InitializingBean) bean).afterPropertiesSet();
return null;
}, getAccessControlContext());
}
catch (PrivilegedActionException pae) {throw pae.getException();
}
}
else {
// 属性初始化后的处理
((InitializingBean) bean).afterPropertiesSet();}
}
if (mbd != null && bean.getClass() != NullBean.class) {String initMethodName = mbd.getInitMethodName();
if (StringUtils.hasLength(initMethodName) &&
!(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
!mbd.isExternallyManagedInitMethod(initMethodName)) {
// 调用自定义初始化方法
invokeCustomInitMethod(beanName, bean, mbd);
}
}
}
2.4.2.4.6.4. 注册 DisposableBean registerDisposableBeanIfNecessary
registerDisposableBeanIfNecessary
/**
* Add the given bean to the list of disposable beans in this factory,
* registering its DisposableBean interface and/or the given destroy method
* to be called on factory shutdown (if applicable). Only applies to singletons.
* @param beanName the name of the bean
* @param bean the bean instance
* @param mbd the bean definition for the bean
* @see RootBeanDefinition#isSingleton
* @see RootBeanDefinition#getDependsOn
* @see #registerDisposableBean
* @see #registerDependentBean
*/
protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) {AccessControlContext acc = (System.getSecurityManager() != null ? getAccessControlContext() : null);
if (!mbd.isPrototype() && requiresDestruction(bean, mbd)) {if (mbd.isSingleton()) {
// Register a DisposableBean implementation that performs all destruction
// work for the given bean: DestructionAwareBeanPostProcessors,
// DisposableBean interface, custom destroy method.
// 单例模式下注册需要销毁的 bean,此方法中会处理实现 DisposableBean 的 bean, 并对所有的 bean 使用 DestructionAwareBeanPostProcessors 处理
//DisposableBean DestructionAwareBeanPostProcessor
registerDisposableBean(beanName,
new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
}
else {
// A bean with a custom scope...
Scope scope = this.scopes.get(mbd.getScope());
if (scope == null) {throw new IllegalStateException("No Scope registered for scope name'" + mbd.getScope() + "'");
}
scope.registerDestructionCallback(beanName,
new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
}
}
}
2.4.2.5 实例化后的后处理应用 applyBeanPostProcessorsAfterInitialization
在讲解从缓存中获取单例 bean 的时候提到过,Spring 中的规则是在 bean 的初始化后尽可能保证将注册的后处理器的 postProcessAfterInstantiation 方法应用到该 bean 中,因为如果返回的 bean 不为空,那么将不会再次经历普通 bean 的创建过程,所以只能在这里应用后处理器的 postProcessAfterInstantiation 方法
@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {Object current = beanProcessor.postProcessAfterInitialization(result, beanName);
if (current == null) {return result;}
result = current;
}
return result;
}
2.4.3 单例创建后的操作 afterSingletonCreation
/** Names of beans that are currently in creation 正在创建的 bean 名称 */
private final Set<String> singletonsCurrentlyInCreation =
Collections.newSetFromMap(new ConcurrentHashMap<>(16));
/** Names of beans currently excluded from in creation checks 排除校验的 bean 名称 */
private final Set<String> inCreationCheckExclusions =
Collections.newSetFromMap(new ConcurrentHashMap<>(16));
/**
* Callback after singleton creation.
* <p>The default implementation marks the singleton as not in creation anymore.
* @param beanName the name of the singleton that has been created
* @see #isSingletonCurrentlyInCreation
*/
protected void afterSingletonCreation(String beanName) {
// 创建后的 bean 移出缓存
if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.remove(beanName)) {throw new IllegalStateException("Singleton'" + beanName + "'isn't currently in creation");
}
}
2.4.4 缓存结果并清除加载 bean 过程中各种辅助状态 addSingleton
// 用于保存 BeanName 和创建 bean 实例之间的关系,beanName -> bean instance
private final Map<String, Object> singletonObjects = new ConcurrentHashMap(256);
// 用于保存 BeanName 和创建 bean 的工厂之间的关系,beanName -> ObjectFactory
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap(16);
// 保存 beanName 和创建 bean 实例之间的关系, 与 singletonObjects 不同的地方在于,当一个单例 bean 被放到这里面后,bean 在创建过程中,可以通过 getBean 方法获取到, 目的是用来检测循环引用
private final Map<String, Object> earlySingletonObjects = new HashMap(16);
// 保存当前所有已注册的 bean
private final Set<String> registeredSingletons = new LinkedHashSet(256);
/**
* Add the given singleton object to the singleton cache of this factory.
* <p>To be called for eager registration of singletons.
* @param beanName the name of the bean
* @param singletonObject the singleton object
* 将给定的单例对象添加到该工厂的单例缓存中。* <p> 被要求进行单例的急切注册。* @param beanName bean 的名称
* @param singletonObject 单例对象
*/
protected void addSingleton(String beanName, Object singletonObject) {synchronized (this.singletonObjects) {this.singletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.add(beanName);
}
}