5 bean 的加载
5 bean 的加载
概述
Demo 入口
加载 bean
的过程,在 Spring 中的调用方式,如我们第 2 章的代码:
package com.stu.spring.context.chapter02;
public class BeanFactoryTest {
@Test
public void getTestStrTest(){
BeanFactory bf = new XmlBeanFactory(new ClassPathResource("chapter02\\myContainerTest.xml"));
// 分析 bean 的加载过程,getBean 方法为 XmlBeanFactory 的 父类往上找,找到了 AbstractBeanFactory 中
MyContainerTest bfBean = (MyContainerTest) bf.getBean("myContainerTest");
System.out.println(bfBean.getTestStr());
}
}
快速体验 AbstractBeanFactory.doGetBean()
public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport implements ConfigurableBeanFactory {
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}
protected <T> T doGetBean(
String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
throws BeansException {
// 1. 转换对应 beanName。
String beanName = transformedBeanName(name);
Object bean;
/**
* 检查缓存中或者实例工厂中是否有对应的实例
* 为什么首先会使用这段代码呢,
* 因为在创建单例 bean 的时候会存在依赖注入的情况,而在创建依赖的时候为了避免循环依赖,
* Spring 创建 bean 的原则是不等 bean 创建完成就会将创建 bean 的 ObjectFactory 提早曝光
* 也就是将 ObjectFactory 加入到缓存中,一旦下个 bean 创建时候需要依赖上个 bean 则直接使用 ObjectFactory
*/
// 2. 尝试从缓存中加载单例。
// 直接尝试从缓存获取或者 singletonFactories 中的 ObjectFactory 中获取
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
if (logger.isTraceEnabled()) {
if (isSingletonCurrentlyInCreation(beanName)) {
logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +
"' that is not fully initialized yet - a consequence of a circular reference");
}
else {
logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
}
}
// 3. bean 的实例化。
// 返回对应的实例,有时候存在诸如 BeanFactory 的情况并不是直接返回实例本身而是返回指定方法返回的实例
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
else {
// 4. 原型模式的依赖检查。
// 只有在单例情况才会尝试解决循环依赖,原型模式情况下,如果存在A->B B->A 相互依赖时,会造成循环依赖,会直接报错
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
// Check if bean definition exists in this factory.
BeanFactory parentBeanFactory = getParentBeanFactory();
// 5. 检测 parentBeanFactory。
// 如果 beanDefinitionMap 中也就是在所有已加载的类中不包括 beanName 则尝试从 parentBeanFactory 中检测
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// Not found -> check parent.
String nameToLookup = originalBeanName(name);
// 递归到 BeanFactory 中寻找
if (parentBeanFactory instanceof AbstractBeanFactory) {
return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
nameToLookup, requiredType, args, typeCheckOnly);
}
else if (args != null) {
// Delegation to parent with explicit args.
return (T) parentBeanFactory.getBean(nameToLookup, args);
}
else if (requiredType != null) {
// No args -> delegate to standard getBean method.
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
else {
return (T) parentBeanFactory.getBean(nameToLookup);
}
}
// 如果不是仅仅做类型检查则是创建 bean,这里要进行记录
if (!typeCheckOnly) {
markBeanAsCreated(beanName);
}
try {
// 6. 将存储 XML 配置文件的 GenericBeanDefinition 转换为 RootBeanDefinition。
// 如果指定BeanName 是子 Bean 的话同时会合并父类的相关属性
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);
// Guarantee initialization of beans that the current bean depends on.
String[] dependsOn = mbd.getDependsOn();
// 7. 寻找依赖。
// 若存在依赖则需要递归实例化依赖的 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);
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
}
}
}
// 8. 针对不同的 scope 进行 bean 的创建。
// 实例化依赖的 bean 后便可以实例化 mbd 本身了
// Create bean instance. singleton 模式的创建
if (mbd.isSingleton()) {
// 获取单例
/**
* 生命周期,待验证及补充,从这个进去可以看到
* 应该是先执行 postProcessBeforeInitialization -> init-method -> postProcessAfterInitialization
*/
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 = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
else if (mbd.isPrototype()) {
// prototype 模式的创建
// It's a prototype -> create a new instance.
Object prototypeInstance = null;
try {
beforePrototypeCreation(beanName);
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
else {
// 指定 scope 上实例化 bean
String scopeName = mbd.getScope();
if (!StringUtils.hasLength(scopeName)) {
throw new IllegalStateException("No scope name defined for bean '" + beanName + "'");
}
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, () -> {
beforePrototypeCreation(beanName);
try {
return createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
});
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;
}
}
// 9. 类型转换。
// 检查需要的类型是否符合 bean 的实际类型
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.isTraceEnabled()) {
logger.trace("Failed to convert bean '" + name + "' to required type '" +
ClassUtils.getQualifiedName(requiredType) + "'", ex);
}
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
}
return (T) bean;
}
}
1. 转换对应 beanName
传入的参数可能是别名,也可能是 FactoryBean
,所以需要进行一系列的解析,这些解析包括以下内容。
- 去除
FactoryBean
的修饰符,也就是name="&aa"
,那么会首先去除 & 而使name = "aa"
。 - 取指定
alias
所表示的最终beanName
,例如别名 A 指向名称为 B 的 bean 则返回 B;若别名 A 指向别名B,别名 B 又指向名称为 C 的 bean 则返回 C。
2. 尝试从缓存中加载单例
单例在 Spring 的同一个容器内只会被创建一次,首先尝试从缓存中加载,如果加载不成功则再次尝试从 singletonFactories
中加载。这里有一个比较重要的循环依赖问题,后续会重点说明。
3. bean 的实例化
如果从缓存中得到了 bean
的原始状态,则需要对 bean
进行实例化。注意:缓存中记录的只是最原始的 bean
状态,并不一定是我们最终想要的 bean
。比如:加入我们需要对工厂 bean
进行处理,那么这里得到的其实是工厂 bean
的初始状态。如果我们真正需要的是 bean
中定义的 factory-method
方法中返回的 bean
,而 getObjectForBeanInstance
就是完成这个工作的。
4. 原型模式的依赖检查
只有在单例情况下才会尝试解决循环依赖。
5. 检测 parentBeanFactory
重点关注 !containsBeanDefinition(beanName)
,即如果当前加载的 XML 配置文件中不包含 beanName 所对应的配置,就只能到 parentBeanFactory
去尝试下了,然后再去递归的调用 getBean
方法。
6. 将存储 XML 配置文件的 GenericBeanDefinition 转换为 RootBeanDefinition
因为从 XML 配置文件中读取到的 Bean 信息是存储在 GenericBeanDefinition 中的,但是所有的 Bean 后续处理都是针对于 RootBeanDefinition 的,所以这里需要进行一个转换,转换的同时如果父类 bean 不为空的话,则会一并合并父类的属性。
7. 寻找依赖
bean
的初始化过程中很可能会用到某些属性,而这些属性很可能是动态配置的,并且配置成依赖于其他的 bean,那么这个时候就有必要先加载依赖的 bean,因此初始化这个 bean
的时候首先会初始化这个 bean
所对应的依赖。
8. 针对不同的 scope 进行 bean 的创建
Spring 会根据不同的配置进行不同的初始化策略。
9. 类型转换
程序到这里返回 bean 后已经基本结束了,通常对该方法的调用参数 requiredType 是为空的,但是可能会存在这样的情况,返回的 bean 其实是个 String,但是 requiredType 却传入 Integer 类型,那么这个时候本步骤就会起作用了,他的功能是将返回的 bean 转换为 requiredType 所指定的类型。
在细化分析各个步骤前,先来了解 FactoryBean
的用法,流程图等可参考 关于 Spring 中 getBean 的全流程源码解析。
5.1 FactoryBean 的使用
FactoryBean 的使用
一般情况,Spring 通过反射机制利用 bean
的 class
属性指定实现类来实例化 bean
。如果实例化 bean
过程比较复杂,这是采用编码的方式会更方便,用户可以通过实现 org.springframework.beans.factory.FactoryBean
。
FactoryBean
接口对于 Spring
框架来说占有重要的地位,Spring 自身就提供了 70 多个 FactoryBean
的实现。它们隐藏了实例化一些复杂 bean
的细节,给上层应用带来了便利。该类主要结构如下:
public interface FactoryBean<T> {
T getObject() throws Exception;
Class<?> getObjectType();
default boolean isSingleton() {
return true;
}
}
使用示例见代码 com.stu.spring.context.chapter05.factorybean.BookBeanFactoryTest
,示例代码简化了多个 property 属性的配置。
5.2 缓存中获取单例 bean
对应 2. 尝试从缓存中加载单例
。
getSingleton 缓存加载
public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {
public Object getSingleton(String beanName) {
// 参数 true 设置表示允许早期依赖
return getSingleton(beanName, true);
}
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
/**
* 1 级缓存 singletonObjects;2 级缓存 earlySingletonObjects;3 级缓存 singletonFactory
* 首先尝试从 singletonObjects 里面获取实例,如果获取不到再从 earlySingletonObjects 里面获取,
* 如果还获取不到,再尝试从 singletonFactories 里面获取 beanName 对应的 ObjectFactory,
* 然后调用这个 ObjectFactory 的 getObject 来创建 bean,并放到 earlySingletonObjects 里面去,
* 并且从 singletonFactories 里面 remove 掉这个 ObjectFactory,而对于后续的所有内存操作都只为了循环依赖检测时候使用。
*/
// 检查缓存中是否存在实例
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
// 如果为空,则锁定全局变量并进行处理
synchronized (this.singletonObjects) {
// 如果此 bean 正在加载则不处理
singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null) {
// 当某些方法需要提前初始化的时候则会调用 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;
}
}
getSingleton
方法加载流程主要为:首先尝试从缓存中加载,然后再次尝试从 singletonFactories
中加载。因为在创建单例 bean
的时候会存在依赖注入的情况,而在创建依赖的时候为了避免循环依赖,Spring 创建 bean
的原则是不等 bean
创建完成就会将创建 bean
的 ObjectFactory
提早曝光加入到缓存中,一旦下一个 bean
创建时需要依赖上个 bean,则直接使用 ObjectFacoty
。
这里几个核心的 map
变量说明如下:
singletonObjects
:用于保存BeanName
和创建bean
实例之间的关系,bean name --> bean instance。earlySingletonObjects
:也是保存BeanName
和创建bean
实例之间的关系,与singletonObjects
的不同之处在于,当一个bean
被放到这里面后,那么当bean
还在创建过程中,就可以通过getBean
方法获取到了,其目的是用于检测循环引用。singletonFactories
:用于保存BeanName
和创建bean
的工厂之间的关系,bean name --> ObjectFactory。registeredSingletons
:用来保存当前所有已注册的bean
。
5.3 从 bean 的实例中获取对象
对应 3.
bean 的实例化
。
getObjectForBeanInstance()
public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport implements ConfigurableBeanFactory {
protected Object getObjectForBeanInstance(
Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {
// 1. 对 FactoryBean 正确性的验证。
// 如果指定的 name 是工厂相关(以 & 为前缀)且 beanInstance 又不是 FactoryBean 类型则验证不通过
if (BeanFactoryUtils.isFactoryDereference(name)) {
if (beanInstance instanceof NullBean) {
return beanInstance;
}
if (!(beanInstance instanceof FactoryBean)) {
throw new BeanIsNotAFactoryException(beanName, beanInstance.getClass());
}
if (mbd != null) {
mbd.isFactoryBean = true;
}
return beanInstance;
}
// 2. 对非 FactoryBean 不做任何处理。
// 现在我们有了个 bean 的实例,这个实例可能会是正常的 bean 或者是 FactoryBean
// 如果是 FactoryBean 我们使用它创建实例,但是如果用户想要直接获取工厂实例而不是工厂的
// getObject 方法对应的实例那么传入的 name 应该加入前缀 &
if (!(beanInstance instanceof FactoryBean)) {
return beanInstance;
}
// 3. 对 bean 进行转换。
// 加载 FactoryBean
Object object = null;
if (mbd != null) {
// mbd 一定是 FactoryBean 类型了
mbd.isFactoryBean = true;
}
else {
// 尝试从缓存中加载 bean
object = getCachedObjectForFactoryBean(beanName);
}
if (object == null) {
// 到这里已经明确知道 beanInstance 一定是 FactoryBean 类型
FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
// containsBeanDefinition 检测 beanDefinitionMap 中也就是在所有已经加载的类中检测是否定义 beanName
if (mbd == null && containsBeanDefinition(beanName)) {
// 将存储 XML 配置文件的 GenericBeanDefinition 转换为 RootBeanDefinition,
// 如果指定 BeanName 是子 Bean 的话同时会合并父类的相关属性。
mbd = getMergedLocalBeanDefinition(beanName);
}
// 是否是用户定义的而不是应用程序本身定义的
boolean synthetic = (mbd != null && mbd.isSynthetic());
// 4. 将从 Factory 中解析 bean 的工作委托给 getObjectFromFactoryBean。
object = getObjectFromFactoryBean(factory, beanName, !synthetic);
}
return object;
}
}
- 无论是从缓存中获得
bean
还是根据不同的scope
策略加载bean
。总之,我们得到bean
的实例后要做的第一步就是调用这个方法来检测以下正确性,其实就是用于检测当前bean
是否是FactoryBean
类型的bean
,如果是,那么需要调用该bean
对应的FactoryBean
实例中的getObject()
作为返回值。 - 无论是从缓存中获取到的
bean
还是通过不同的scope
策略加载的bean
都只是最简单的bean
状态,并不一定是我们最终想要的bean
。如:加入我们需要对工厂bean
中定义的factory-method
方法中返回的bean
,而getObjectForBeanInstance
方法就是完成这个工作的。
以下是 getObjectForBeanInstance
方法所做的工作。
- 对
FactoryBean
正确性的验证。 - 对非
FactoryBean
不做任何处理。 - 对
bean
进行转换。 - 将从
Factory
中解析bean
的工作委托给getObjectFromFactoryBean
,该方法逻辑略,可以跟踪源码查看对应备注了解,注意调用了后处理器逻辑。
FactoryBeanRegistrySupport 代码
public abstract class FactoryBeanRegistrySupport extends DefaultSingletonBeanRegistry {
protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {
// 如果是单例模式
if (factory.isSingleton() && containsSingleton(beanName)) {
synchronized (getSingletonMutex()) {
Object object = this.factoryBeanObjectCache.get(beanName);
if (object == null) {
// FactoryBean.getObject() 方法调用
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)
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 {
// 调用 ObjectFactory 的后处理器,
// 多态调用的是 AbstractAutowireCapableBeanFactory.postProcessObjectFromFactoryBean
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 的后处理器,
// 多态调用的是 AbstractAutowireCapableBeanFactory.postProcessObjectFromFactoryBean
object = postProcessObjectFromFactoryBean(object, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "Post-processing of FactoryBean's object failed", ex);
}
}
return object;
}
}
private Object doGetObjectFromFactoryBean(FactoryBean<?> factory, 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) {
// scope 为单例时,返回的 bean 为 null 时则会报抛出异常。
if (isSingletonCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(
beanName, "FactoryBean which is currently in creation returned null from getObject");
}
object = new NullBean();
}
return object;
}
}
AbstractAutowireCapableBeanFactory 代码
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
implements AutowireCapableBeanFactory {
protected Object postProcessObjectFromFactoryBean(Object object, String beanName) {
return applyBeanPostProcessorsAfterInitialization(object, beanName);
}
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
// Spring 的规则是在 bean 的初始化后尽可能保证将注册的后处理器 postProcessAfterInitialization 方法应用到该 bean 中。
// 因为如果返回的 bean 不为空,那么便不会再次经理普通 bean 的创建过程,所以只能在这里应用后处理器的 postProcessAfterInitializetion 方法。
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor.postProcessAfterInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
}
5.4 获取单例
对应 8. 针对不同的 scope 进行 bean 的创建
。
getSingleton 非缓存加载
public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(beanName, "Bean name must not be null");
// 全局变量需要同步
synchronized (this.singletonObjects) {
// 1. 检查缓存是否已经加载过。
// 首先检查对应的 bean 是否已经加载过,因为 singleton 模式其实就是复用已创建的 bean。
Object singletonObject = this.singletonObjects.get(beanName);
// 如果为空才进行 bean 的初始化
if (singletonObject == null) {
// this.singletonsCurrentlyInDestruction 是个 boolean,记录的是当前这个单例是否正在被销毁,
//如果是 true,代表单例已经执行了自身的 destroy 销毁方法,或者有异常的时候执行了 destroySingleton 方法等情况
if (this.singletonsCurrentlyInDestruction) {
throw new BeanCreationNotAllowedException(beanName,
"Singleton bean creation not allowed while singletons of this factory are in destruction " +
"(Do not request a bean from a BeanFactory in a destroy method implementation!)");
}
if (logger.isDebugEnabled()) {
logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
}
// 2. 若没有加载,则记录 beanName 的正在加载状态。
// 3. 加载单例前记录状态。
// 子类实现,记录加载状态,即通过 this.singletonsCurrentlyInCreation.add(beanName) 将当前正要创建的 bean记录在缓存中。
beforeSingletonCreation(beanName);
boolean newSingleton = false;
boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
if (recordSuppressedExceptions) {
this.suppressedExceptions = new LinkedHashSet<>();
}
try {
// 4. 通过调用参数传入的 ObjectFactory 的个体 Object 方法实例化 bean。
// 初始化 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;
}
// 5. 加载单例后的处理方法调用。
afterSingletonCreation(beanName);
}
if (newSingleton) {
// 6. 将结果记录至缓存并删除加载 bean 过程中所记录的各种辅助状态。
addSingleton(beanName, singletonObject);
}
}
// 7. 返回处理结果。
return singletonObject;
}
}
}
public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {
protected void beforeSingletonCreation(String beanName) {
// this.singletonsCurrentlyInCreation.add(beanName) 将当前正要创建的 bean记录在缓存中。
if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
}
protected void afterSingletonCreation(String beanName) {
if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.remove(beanName)) {
throw new IllegalStateException("Singleton '" + beanName + "' isn't currently in creation");
}
}
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);
}
}
}
如果从缓存中获取单例实例为 null,就需要从头开始 bean
的加载过程了,而 Spring 中使用 getSingleton
的重载方法实现 bean
的加载过程,具体可以看源码备注,以下是方法的主要步骤。
- 检查缓存是否已经加载过。
- 若没有加载,则记录
beanName
的正在加载状态。 - 加载单例前记录状态。
- 通过调用参数传入的
ObjectFactory
的个体Object
方法实例化bean
。 - 加载单例后的处理方法调用。
- 将结果记录至缓存并删除加载
bean
过程中所记录的各种辅助状态。 - 返回处理结果。
ObjectFactory
的核心部分其实只是调用了 createBean
的方法,因此我们继续查看该方法源码。
5.5 准备创建 bean
对应 8. 针对不同的 scope 进行 bean 的创建
。
getSingleton 非缓存加载
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
implements AutowireCapableBeanFactory {
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
if (logger.isTraceEnabled()) {
logger.trace("Creating instance of bean '" + beanName + "'");
}
RootBeanDefinition mbdToUse = mbd;
// 1. 根据设置的 class 属性或者根据 className 来解析 Class。
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
// 2. 对 override 属性进行标记及验证。
// 验证及准备覆盖的方法
try {
mbdToUse.prepareMethodOverrides();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
beanName, "Validation of method overrides failed", ex);
}
try {
// 3. 应用初始化的后处理器,解析指定 bean 是否存在初始化前的短路操作。
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 {
// 4. 创建 bean
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isTraceEnabled()) {
logger.trace("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);
}
}
}
以下是 createBean
方法的主要步骤。
- 根据设置的
class
属性或者根据className
来解析Class
。 - 对
override
属性进行标记及验证。 这个函数的操作主要是针对Spring
配置的lookup-method
和replace-method
的。 - 应用初始化的后处理器,解析指定
bean
是否存在初始化前的短路操作。 - 创建
bean
。
5.5.1 处理 override 属性
prepareMethodOverrides
public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccessor
implements BeanDefinition, Cloneable {
public void prepareMethodOverrides() throws BeanDefinitionValidationException {
// Check that lookup methods exist and determine their overloaded status.
if (hasMethodOverrides()) {
getMethodOverrides().getOverrides().forEach(this::prepareMethodOverride);
}
}
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) {
// 标记 MethodOverride 暂未被覆盖,避免参数类型检查的开销。
mo.setOverloaded(false);
}
}
}
这个功能的实现原理是在 bean
实例化的时候如果检测到存在 methodOverrides
属性,会动态地为当前 bean
生成代理并使用对应的拦截器为 bean
做增强处理,相关逻辑实现在 bean
的实例化部分再做探讨。
5.5.2 实例化的前置处理
resolveBeforeInstantiation
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
implements AutowireCapableBeanFactory {
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) {
// 实例化前的后处理器应用。对 InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation 调用
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
if (bean != null) {
// 实例化后的后处理器应用。对 InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation 调用
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
}
mbd.beforeInstantiationResolved = (bean != null);
}
return bean;
}
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;
}
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
// Spring 的规则是在 bean 的初始化后尽可能保证将注册的后处理器 postProcessAfterInitialization 方法应用到该 bean 中。
// 因为如果返回的 bean 不为空,那么便不会再次经理普通 bean 的创建过程,所以只能在这里应用后处理器的 postProcessAfterInitializetion 方法。
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor.postProcessAfterInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
}
注意关注下 实例化前的后处理器应用
和 实例化后的后处理器应用
两个方法。
5.6 循环依赖
5.6.1 什么是循环依赖
略。
5.6.2 Spring 如何解决循环依赖
Spring 容器循环依赖包括构造器循环依赖和 setter
循环依赖。Spring 将循环依赖的处理分为 3 种情况。
1. 构造器循环依赖
表示通过构造器注入构成的循环依赖,此依赖是无法解决的,只能抛出 BeanCurrentlyInCreationException
异常表示循环依赖。
Spring 容器将每一个正在创建的 bean
标识符放在一个 “当前创建 bean 池” 中,bean 标识符在创建过程中将一直保持在这个池中,因此如果在创建 bean
过程中发现自己已经在 “当前创建 bean 池” 里时,将抛出 BeanCurrentlyInCreationException
异常表示循环依赖,而对于创建完毕的 bean
将从 “当前创建 bean 池” 中清除掉。
使用示例见代码 com.stu.spring.context.chapter05.circle.CircleConstructorTest
,可以调试跟踪下代码加深印象。
2. setter 循环依赖
表示通过 setter
注入方式构成的循环依赖。对于 setter
注入造成的依赖是通过 Spring
容器提前暴露刚完成构造器注入但未完成其他步骤(如 setter
注入)的 bean
来完成的,而且只能解决单例作用域的 bean
循环依赖。通过提前暴露一个单例工厂方法,从而使其他 bean
能引用到该 bean
。 使用示例见代码 com.stu.spring.context.chapter05.circle.CircleSetterTest
,解决了应用初始化时抛出异常的问题,可以正常注入依赖。
3. prototype 范围的依赖处理
对于 “prototype” 作用域 bean
,Spring 容器无法完成依赖注入,因为 Spring
容器不进行缓存 “prototype” 作用域的 bean
,因此无法提前暴露一个创建中的 bean
。
使用示例见代码 com.stu.spring.context.chapter05.circle.CirclePrototypeTest
。
TIP
对于 “singleton” 作用域 bean,可以通过 “setAllowCircularReferences(false);” 来禁用循环引用。
需要注意使用的具体方式得参考 "6 IOC 容器的功能扩展",定制 BeanFactory
方法,通过子类覆盖方法实现(我理解只能这样,不然初始化 BeanFactory 完后,再设置的话迟了),使用示例详见代码 com.stu.spring.context.chapter05.circle.DisabledCircleSingletonTest
。
5.7 创建 bean
doCreateBean
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
implements AutowireCapableBeanFactory {
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
// Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
// 1. 如果是单例则需要首先清除缓存。
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
// 2. 实例化 bean,将 BeanDefinition 转换为 BeanWrapper。
// 根据指定 bean 使用对应的策略创建新的实例,如:工厂方法、构造函数自动注入、简单初始化
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
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 {
// 3. MergedBeanDefinitionPostProcessor 的应用。
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing of merged bean definition failed", ex);
}
mbd.postProcessed = true;
}
}
// 4. 依赖处理。
// 是否需要提前曝光:单例 & 允许循环依赖 & 当前 bean 正在创建中,检测循环依赖
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isTraceEnabled()) {
logger.trace("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
// 为避免后期循环依赖,可以在 bean 初始化完成前将创建实例的 ObjectFactory 加入工厂
// getEarlyBeanReference 对 bean 再一次依赖引用,主要应用 SmartInstantiationAware BeanPostProcessor
// 其中 AOP 就是在这里将 advice 动态织入 bean 中,若没有则直接返回 bean,不做任何处理。
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
// Initialize the bean instance.
Object exposedObject = bean;
try {
// 5. 属性填充。将所有属性填充至 bean 的实例中。
// 对 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);
}
}
// 6. 循环依赖检查。
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 " +
"'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.");
}
}
}
}
// Register bean as disposable.
try {
// 7. 注册 DisposableBean。
// 根据 scope 注册 bean
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
// 8. 完成创建并返回。
return exposedObject;
}
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;
}
}
doCreateBean
函数的主要思路如下:
- 如果是单例则需要首先清除缓存。
- 实例化 bean,将 BeanDefinition 转换为 BeanWrapper。
转换的过程很复杂,核心转换逻辑如下
- 如果存在工厂方法则使用工厂方法进行初始化。
- 一个类有多个构造函数,每个构造函数都有不同的参数,所以需要根据参数锁定构造函数并进行初始化。
- 如果既不存在工厂方法也不存在带有参数的构造函数,则使用默认的构造函数进行 bean 的实例化。
- MergedBeanDefinitionPostProcessor 的应用。
bean 合并后的处理,Autowired 注解正是通过此方法实现诸如类型的预解析。
4. 依赖处理。
5. 属性填充。将所有属性填充至 bean 的实例中。
6. 循环依赖检查。
在 Spring
中解决循环依赖只对单例有效,而对于 prototype
的 bean
,Spring
没有好的解决办法,唯一要做的就是抛出异常。
7. 注册 DisposableBean。
如果配置了 destory-method
,这里需要注册以便于在销毁时候调用。
8. 完成创建并返回。
5.7.1 创建 bean 的实例
对应 实例化 bean,将 BeanDefinition 转换为 BeanWrapper
。
createBeanInstance
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
implements AutowireCapableBeanFactory {
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
// 解析 class
Class<?> beanClass = resolveBeanClass(mbd, beanName);
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());
}
Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
if (instanceSupplier != null) {
return obtainFromSupplier(instanceSupplier, beanName);
}
// 1. 如果在 `RootBeanDefinition` 中存在 `factoryMethodName` 属性,或者在配置文件中配置了 `factory-method`,
// 那么 Spring 会尝试使用 `instantiateUsingFactoryMethod(beanName, mbd, args)` 方法
// 根据 `RootBeanDefinition` 中的配置生成 bean 的实例。
if (mbd.getFactoryMethodName() != null) {
return instantiateUsingFactoryMethod(beanName, mbd, args);
}
// 2. 解析构造函数并进行构造函数的实例化。判定的过程是个比较耗费性能的步骤,所以采用了缓存机制,
// 缓存的属性为 `RootBeanDefinition.resolvedConstructorOrFactoryMethod`。
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);
}
}
// 需要根据参数解析构造函数
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
// 构造函数自动注入
return autowireConstructor(beanName, mbd, ctors, args);
}
// Preferred constructors for default construction?
ctors = mbd.getPreferredConstructors();
if (ctors != null) {
return autowireConstructor(beanName, mbd, ctors, null);
}
// 使用默认构造函数构造
return instantiateBean(beanName, mbd);
}
}
createBeanInstance
函数的主要思路如下:
- 如果在
RootBeanDefinition
中存在factoryMethodName
属性,或者在配置文件中配置了factory-method
,那么Spring
会尝试使用instantiateUsingFactoryMethod(beanName, mbd, args)
方法根据RootBeanDefinition
中的配置生成bean
的实例。 - 解析构造函数并进行构造函数的实例化。判定的过程是个比较耗费性能的步骤,所以采用了缓存机制,缓存的属性为
RootBeanDefinition.resolvedConstructorOrFactoryMethod
。
1. autowireConstructor
对于实例的创建 Spring 中分成了两种情况,一种是通用的实例化,另一种是带有参数的实例化,带有参数的实例化过程很复杂,如下代码。
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
implements AutowireCapableBeanFactory {
protected BeanWrapper autowireConstructor(
String beanName, RootBeanDefinition mbd, @Nullable Constructor<?>[] ctors, @Nullable Object[] explicitArgs) {
return new ConstructorResolver(this).autowireConstructor(beanName, mbd, ctors, explicitArgs);
}
}
class ConstructorResolver {
public BeanWrapper autowireConstructor(String beanName, RootBeanDefinition mbd,
@Nullable Constructor<?>[] chosenCtors, @Nullable Object[] explicitArgs) {
BeanWrapperImpl bw = new BeanWrapperImpl();
this.beanFactory.initBeanWrapper(bw);
Constructor<?> constructorToUse = null;
ArgumentsHolder argsHolderToUse = null;
Object[] argsToUse = null;
// 1. 构造函数参数的确定。
// explicitArgs 通过 getBean 方法传入,如果 getBean 方法调用的时候指定方法参数那么直接调用
if (explicitArgs != null) {
// 1.1 根据 explicitArgs 参数判断。
argsToUse = explicitArgs;
}
else {
// 1.2 缓存中获取,注意有可能做参数类型转换。
// 如果在 getBean 方法时候没有指定则尝试从配置文件中解析
Object[] argsToResolve = null;
// 尝试从缓存中获取
synchronized (mbd.constructorArgumentLock) {
constructorToUse = (Constructor<?>) mbd.resolvedConstructorOrFactoryMethod;
if (constructorToUse != null && mbd.constructorArgumentsResolved) {
// 从缓存中取
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 || argsToUse == null) {
// 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);
}
}
if (candidates.length == 1 && explicitArgs == null && !mbd.hasConstructorArgumentValues()) {
Constructor<?> uniqueCandidate = candidates[0];
if (uniqueCandidate.getParameterCount() == 0) {
synchronized (mbd.constructorArgumentLock) {
mbd.resolvedConstructorOrFactoryMethod = uniqueCandidate;
mbd.constructorArgumentsResolved = true;
mbd.resolvedConstructorArguments = EMPTY_ARGS;
}
bw.setBeanInstance(instantiate(beanName, mbd, uniqueCandidate, EMPTY_ARGS));
return bw;
}
}
// Need to resolve the constructor.
boolean autowiring = (chosenCtors != null ||
mbd.getResolvedAutowireMode() == AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR);
ConstructorArgumentValues resolvedValues = null;
int minNrOfArgs;
if (explicitArgs != null) {
minNrOfArgs = explicitArgs.length;
}
else {
// 1.3 配置文件获取。
// 提取配置文件中的配置的构造函数参数
ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues();
// 用于承载解析后的构造函数参数的值
resolvedValues = new ConstructorArgumentValues();
// 能解析到的参数个数
minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);
}
// 2. 构造函数的确定。
// 排序给定的构造函数,public 构造函数优先参数数量排序,非 public 构造函数参数数量降序
AutowireUtils.sortConstructors(candidates);
int minTypeDiffWeight = Integer.MAX_VALUE;
Set<Constructor<?>> ambiguousConstructors = null;
LinkedList<UnsatisfiedDependencyException> causes = null;
for (Constructor<?> candidate : candidates) {
int parameterCount = candidate.getParameterCount();
if (constructorToUse != null && argsToUse != null && argsToUse.length > parameterCount) {
// 如果已经找到选用的构造函数或者需要的参数个数小于当前的构造函数参数个数则终止
// 因为已经按照参数个数降序排列
break;
}
if (parameterCount < minNrOfArgs) {
// 参数个数不相等
continue;
}
ArgumentsHolder argsHolder;
Class<?>[] paramTypes = candidate.getParameterTypes();
if (resolvedValues != null) {
// 有参数则根据值构造对应参数类型的参数
try {
// 注释上获取参数名称
String[] paramNames = ConstructorPropertiesChecker.evaluate(candidate, parameterCount);
if (paramNames == null) {
// 获取参数名称探索器
ParameterNameDiscoverer pnd = this.beanFactory.getParameterNameDiscoverer();
if (pnd != null) {
// 获取指定构造函数的参数名称
paramNames = pnd.getParameterNames(candidate);
}
}
// 3. 根据确定的构造函数转换对应的参数类型。
// 根据名称和数据类型创建参数持有者
argsHolder = createArgumentArray(beanName, mbd, resolvedValues, bw, paramTypes, paramNames,
getUserDeclaredConstructor(candidate), autowiring, candidates.length == 1);
}
catch (UnsatisfiedDependencyException ex) {
if (logger.isTraceEnabled()) {
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 (parameterCount != explicitArgs.length) {
continue;
}
// 构造函数没有参数的情况
argsHolder = new ArgumentsHolder(explicitArgs);
}
// 探测是否有不确定性的构造函数存在,例如不同构造函数的参数为父子关系
int typeDiffWeight = (mbd.isLenientConstructorResolution() ?
argsHolder.getTypeDifferenceWeight(paramTypes) : argsHolder.getAssignabilityWeight(paramTypes));
// 如果它代表着当前最接近的匹配则选择作为构造函数
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);
}
}
// 4. 构造函数不确定性的验证。
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 on bean class [" + mbd.getBeanClassName() + "] " +
"(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 on bean class [" + mbd.getBeanClassName() + "] " +
"(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities): " +
ambiguousConstructors);
}
// 5. 根据实例化策略以及得到的构造函数及构造函数参数实例化 Bean。
if (explicitArgs == null && argsHolderToUse != null) {
// 将解析的构造函数加入缓存
argsHolderToUse.storeCache(mbd, constructorToUse);
}
}
Assert.state(argsToUse != null, "Unresolved constructor arguments");
// 将构建的实例加入 BeanWrapper 中。
bw.setBeanInstance(instantiate(beanName, mbd, constructorToUse, argsToUse));
return bw;
}
}
autowireConstructor
方法主要步骤如下:
- 构造函数参数的确定。
- 1.1 根据
explicitArgs
参数判断。 - 1.2 缓存中获取,注意有可能做参数类型转换。
- 1.3 配置文件获取。
- 构造函数的确定。
- 根据确定的构造函数转换对应的参数类型。
- 构造函数不确定性的验证。
- 根据实例化策略以及得到的构造函数及构造函数参数实例化
Bean
。
- 根据实例化策略以及得到的构造函数及构造函数参数实例化
2. instantiateBean
不带参数的构造函数实例化过程相对简单些,代码如下。
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
implements AutowireCapableBeanFactory {
protected BeanWrapper instantiateBean(String beanName, RootBeanDefinition mbd) {
try {
Object beanInstance;
if (System.getSecurityManager() != null) {
beanInstance = AccessController.doPrivileged(
(PrivilegedAction<Object>) () -> getInstantiationStrategy().instantiate(mbd, beanName, this),
getAccessControlContext());
}
else {
beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, this);
}
BeanWrapper bw = new BeanWrapperImpl(beanInstance);
initBeanWrapper(bw);
return bw;
}
catch (Throwable ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
}
}
}
3. 实例化策略
最简单的实例化策略是直接反射来构造实例对象,但是 Spring
并没有这么做。
public class SimpleInstantiationStrategy implements InstantiationStrategy {
public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
/**
* 如果有需要覆盖或者动态替换的方法则当前需要使用 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.
// PS: CGLIB
return instantiateWithMethodInjection(bd, beanName, owner);
}
}
}
public class CglibSubclassingInstantiationStrategy extends SimpleInstantiationStrategy {
protected Object instantiateWithMethodInjection(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
return instantiateWithMethodInjection(bd, beanName, owner, null);
}
protected Object instantiateWithMethodInjection(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner,
@Nullable Constructor<?> ctor, Object... args) {
// Must generate CGLIB subclass...
return new CglibSubclassCreator(bd, owner).instantiate(ctor, args);
}
public Object instantiate(@Nullable Constructor<?> ctor, 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;
}
}
5.7.2 记录创建 bean 的 ObjectFactory
对应 4. 依赖处理
。
doCreateBean 中的依赖处理
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
implements AutowireCapableBeanFactory {
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
// 4. 依赖处理。
// 是否需要提前曝光:单例 & 允许循环依赖 & 当前 bean 正在创建中,检测循环依赖
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isTraceEnabled()) {
logger.trace("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
// 为避免后期循环依赖,可以在 bean 初始化完成前将创建实例的 ObjectFactory 加入工厂
// getEarlyBeanReference 对 bean 再一次依赖引用,主要应用 SmartInstantiationAware BeanPostProcessor
// 其中 AOP 就是在这里将 advice 动态织入 bean 中,若没有则直接返回 bean,不做任何处理。
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, 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;
}
}
理解如下:
earlySingletonExposure
:提早曝光的单例,需要关注的是由哪些条件影响这个值。mbd.isSingleton()
:此RootBeanDifinition
代表的是否是单例。this.allowCircularReferences
:是否允许循环依赖,这个没找到在配置文件中如何配置,但是可以通过硬编码配置:new ClassPathXmlApplicationContext("test.xml").setAllowCircularReferences(false);
,注意实际 debug 时发现没有生效,详细使用示例见代码com.stu.spring.context.chapter05.circle.CircleSingletonTest
。isSingletonCurrentlyInCreation(beanName))
:该bean
是否在创建中。
当是单例、允许循环依赖和对应的 bean
正在创建 3 个条件都满足时,加入 SingleFactory
的作用主要是解决循环依赖,主要步骤如下,也可以查看代码了解,重点关注 getEarlyBeanReference
方法。
Spring
处理循环依赖的解决办法,在 B 中创建依赖 A 时通过 ObjectFactory
提供的实例化方法来中断 A 中的属性填充,使 B 中持有的 A 仅仅是刚刚初始化并没有填充任何属性的 A,而这正初始化 A 的步骤还是在最开始创建 A 的时候进行的,但是因为 A 与 B 中的 A 所表示的属性地址是一样的,所以在 A 中创建好的属性填充自然可以通过 B 中的 A 获取,这样就解决了循环依赖的问题。
5.7.3 属性注入
对应 5. 属性填充
。
属性填充
顾名思义,属性填充。
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
implements AutowireCapableBeanFactory {
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 {
// 没有可填充的属性
return;
}
}
// 1. InstantiationAwareBeanPostProcessor 处理器的 postProcessAfterInstantiation 函数的应用。
// 给 InstantiationAwareBeanPostProcessors 最后一次机会在属性设置前来改变 bean
// 如:可以用来支持属性注入的类型
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
// 返回值为是否继续填充 bean
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
// 后处理器发出停止填充命令则终止后续的执行
return;
}
}
}
}
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
// 2. 根据注入类型(byName/byType),提取依赖的 bean,并统一存入 PropertyValues 中。
int resolvedAutowireMode = mbd.getResolvedAutowireMode();
if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
// 根据名称自动注入
if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
// 根据类型自动注入
if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}
// 后处理器已经初始化
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
// 需要依赖检查
boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);
PropertyDescriptor[] filteredPds = null;
if (hasInstAwareBpps) {
if (pvs == null) {
pvs = mbd.getPropertyValues();
}
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
if (filteredPds == null) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
// 3. 应用 InstantiationAwareBeanPostProcessor 处理器的 postProcessPropertyValues 方法,对属性获取完毕前对属性的再次处理。
// 对所有需要依赖检查的属性进行后处理
pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
return;
}
}
pvs = pvsToUse;
}
}
}
if (needsDepCheck) {
if (filteredPds == null) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
// 依赖检查,对应 depends-on 属性,3.0 已经弃用该属性。
checkDependencies(beanName, mbd, filteredPds, pvs);
}
if (pvs != null) {
// 4. 将所有 PropertyValues 中的属性填充至 BeanWrapper 中。
// 将属性应用到 bean 中。
applyPropertyValues(beanName, mbd, bw, pvs);
}
}
}
populateBean
函数的处理流程如下:
InstantiationAwareBeanPostProcessor
处理器的postProcessAfterInstantiation
函数的应用。 此函数可以控制程序是否继续进行属性填充。- 根据注入类型(byName/byType),提取依赖的
bean
,并统一存入PropertyValues
中。 - 应用
InstantiationAwareBeanPostProcessor
处理器的postProcessPropertyValues
方法,对属性获取完毕前对属性的再次处理。 典型应用是RequiredAnnotationBeanPostProcesser
类中对属性的验证。 - 将所有
PropertyValues
中的属性填充至BeanWrapper
中。
1 autowireByName
简单来说就是在传入的参数 pvs 中找出已经加载的 bean,并递归实例化,进而加入到 pvs 中。
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
implements AutowireCapableBeanFactory {
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.isTraceEnabled()) {
logger.trace("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");
}
}
}
}
}
2 autowireByType
注意,Spring 中提供了对集合的类型注入的支持。
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
implements AutowireCapableBeanFactory {
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 = !(bw.getWrappedInstance() instanceof PriorityOrdered);
DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager);
/**
* 解析指定 beanName 的属性所匹配的值,并把解析到的属性名称存储在 autowiredBeanNames 中,
* 当属性存在多个封装 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.isTraceEnabled()) {
logger.trace("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);
}
}
}
}
(1) resolveDependency
寻找类型匹配的逻辑代码。
public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory
implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {
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()) {
return new DependencyObjectProvider(descriptor, requestingBeanName);
}
else if (javaxInjectProviderClass == descriptor.getDependencyType()) {
// javaxInjectProviderClass 类注入的特殊处理
return new Jsr330Factory().createDependencyProvider(descriptor, requestingBeanName);
}
else {
Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(
descriptor, requestingBeanName);
if (result == null) {
// 通用处理逻辑
result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
}
return result;
}
}
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();
// 用于支持 Spring 中新增的注解 @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());
try {
return converter.convertIfNecessary(value, type, descriptor.getTypeDescriptor());
}
catch (UnsupportedOperationException ex) {
// A custom TypeConverter which does not support TypeDescriptor resolution...
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;
}
Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
if (matchingBeans.isEmpty()) {
if (isRequired(descriptor)) {
raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
}
return null;
}
String autowiredBeanName;
Object instanceCandidate;
if (matchingBeans.size() > 1) {
autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);
if (autowiredBeanName == null) {
if (isRequired(descriptor) || !indicatesMultipleBeans(type)) {
return descriptor.resolveNotUnique(descriptor.getResolvableType(), 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)) {
// 如果 autowired 的 require 属性为 true 而找到的 匹配项却为空则只能抛出异常
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);
}
}
private Object resolveMultipleBeans(DependencyDescriptor descriptor, @Nullable String beanName,
@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) {
Class<?> type = descriptor.getDependencyType();
if (descriptor instanceof StreamDependencyDescriptor) {
Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
if (autowiredBeanNames != null) {
autowiredBeanNames.addAll(matchingBeans.keySet());
}
Stream<Object> stream = matchingBeans.keySet().stream()
.map(name -> descriptor.resolveCandidate(name, type, this))
.filter(bean -> !(bean instanceof NullBean));
if (((StreamDependencyDescriptor) descriptor).isOrdered()) {
stream = stream.sorted(adaptOrderComparator(matchingBeans));
}
return stream;
}
// 属性是数组类型
else if (type.isArray()) {
Class<?> componentType = type.getComponentType();
// 根据属性类型找到 beanFactory 中所有类型的匹配 bean
// 返回值的构成为:key = 匹配的 beanName,value = beanName 对应的实例化后的 bean (通过 getBean(beanName) 返回)
ResolvableType resolvableType = descriptor.getResolvableType();
Class<?> resolvedArrayType = resolvableType.resolve(type);
if (resolvedArrayType != type) {
componentType = resolvableType.getComponentType().resolve();
}
if (componentType == null) {
return null;
}
Map<String, Object> matchingBeans = findAutowireCandidates(beanName, componentType,
new MultiElementDescriptor(descriptor));
if (matchingBeans.isEmpty()) {
return null;
}
if (autowiredBeanNames != null) {
autowiredBeanNames.addAll(matchingBeans.keySet());
}
TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
// 通过转换器将 bean 的值转换为对应的 type 类型
Object result = converter.convertIfNecessary(matchingBeans.values(), resolvedArrayType);
if (result instanceof Object[]) {
Comparator<Object> comparator = adaptDependencyComparator(matchingBeans);
if (comparator != null) {
Arrays.sort((Object[]) result, comparator);
}
}
return result;
}
// 属性是 Collection 类型
else if (Collection.class.isAssignableFrom(type) && type.isInterface()) {
Class<?> elementType = descriptor.getResolvableType().asCollection().resolveGeneric();
if (elementType == null) {
return null;
}
Map<String, Object> matchingBeans = findAutowireCandidates(beanName, elementType,
new MultiElementDescriptor(descriptor));
if (matchingBeans.isEmpty()) {
return null;
}
if (autowiredBeanNames != null) {
autowiredBeanNames.addAll(matchingBeans.keySet());
}
TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
Object result = converter.convertIfNecessary(matchingBeans.values(), type);
if (result instanceof List) {
if (((List<?>) result).size() > 1) {
Comparator<Object> comparator = adaptDependencyComparator(matchingBeans);
if (comparator != null) {
((List<?>) result).sort(comparator);
}
}
}
return result;
}
// 属性是 Map 类型
else if (Map.class == type) {
ResolvableType mapType = descriptor.getResolvableType().asMap();
Class<?> keyType = mapType.resolveGeneric(0);
if (String.class != keyType) {
return null;
}
Class<?> valueType = mapType.resolveGeneric(1);
if (valueType == null) {
return null;
}
Map<String, Object> matchingBeans = findAutowireCandidates(beanName, valueType,
new MultiElementDescriptor(descriptor));
if (matchingBeans.isEmpty()) {
return null;
}
// 已经可以确定只有一个匹配项
if (autowiredBeanNames != null) {
autowiredBeanNames.addAll(matchingBeans.keySet());
}
return matchingBeans;
}
else {
return null;
}
}
}
3 applyPropertyValues
获取到属性,并将其应用到已经实例化的 bean 中。
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
implements AutowireCapableBeanFactory {
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 中的值已经被转换为对应的类型那么可以直接设置到 beanwrapper 中
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();
if (originalValue == AutowiredPropertyMarker.INSTANCE) {
Method writeMethod = bw.getPropertyDescriptor(propertyName).getWriteMethod();
if (writeMethod == null) {
throw new IllegalArgumentException("Autowire marker for property without write method: " + pv);
}
originalValue = new DependencyDescriptor(new MethodParameter(writeMethod, 0), true);
}
// 里面有调用 SpEL 函数的方法
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);
}
}
}
5.7.4 初始化 bean
对应 5. 属性填充
的下一行代码。
初始化 bean
Spring 中程序已经执行过 bean 的实例化,并且进行了属性的填充,而就在这时将会调用用户设定的初始化方法。
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
implements AutowireCapableBeanFactory {
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {
// 对特殊 bean 处理:Aware、BeanClassLoaderAware、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;
}
}
1 激活 Aware 方法
Spring 提供了一些 Aware 相关接口,比如 BeanFactoryAware
、ApplicationContextAware
、ResourceLoaderAware
、ServletContextAware
等。
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
implements AutowireCapableBeanFactory {
private void invokeAwareMethods(String beanName, Object bean) {
if (bean instanceof Aware) {
if (bean instanceof BeanNameAware) {
((BeanNameAware) bean).setBeanName(beanName);
}
if (bean instanceof BeanClassLoaderAware) {
ClassLoader bcl = getBeanClassLoader();
if (bcl != null) {
((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
}
}
if (bean instanceof BeanFactoryAware) {
((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
}
}
}
}
2 处理器的应用
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
implements AutowireCapableBeanFactory {
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
// 支持在调用客户自定义初始化方法前以及调用自定义初始化方法后分别会调用 BeanPostProcessor 的 postProcessBeforeInitialization 和 postProcessAfterInitialization
Object current = processor.postProcessBeforeInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
// Spring 的规则是在 bean 的初始化后尽可能保证将注册的后处理器 postProcessAfterInitialization 方法应用到该 bean 中。
// 因为如果返回的 bean 不为空,那么便不会再次经理普通 bean 的创建过程,所以只能在这里应用后处理器的 postProcessAfterInitializetion 方法。
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor.postProcessAfterInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
}
3 激活自定义的 init 方法
定制的初始化方法除了 init-method 外,还有使自定义的 bean 实现 InitializingBean 接口,并在 afterPropertiesSet 中实现自己的初始化业务逻辑。
init-method 与 afterPropertiesSet 都是在初始化 bean 时执行,执行顺序是 afterPropertiesSet 先执行,而 init-method 后执行。
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
implements AutowireCapableBeanFactory {
protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBeanDefinition mbd)
throws Throwable {
// 首先会检查是否是 InitializingBean,如果是的话需要调用 afterPropertiesSet 方法。
boolean isInitializingBean = (bean instanceof InitializingBean);
if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
if (logger.isTraceEnabled()) {
logger.trace("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);
}
}
}
}
5.7.5 注册 DisposableBean
对应 7. 注册 DisposableBean
。
注册 DisposableBean
和初始化方法类似,Spring 还提供了销毁方法的扩展入口。
除了配置属性 destroy-method 方法外,用户还可以注册后处理器 DestructionAwareBeanPostProcessor 来统一处理 bean 的销毁方法。
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
implements AutowireCapableBeanFactory {
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()) {
// 单例模式下注册需要销毁的 bean,此方法中会处理实现 DisposableBean 的 bean,
// 并且对所有的 bean 使用 DestructionAwareBeanPostProcessors 处理 Disposable DestructionAwareBeanPostProcessors
registerDisposableBean(beanName,
new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
}
else {
// 自定义 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));
}
}
}
}