【Spring 源码深度解析】04 Bean 的加载

本文详细解析了Spring框架中Bean的加载过程,包括Bean定义的解析、单例Bean的缓存处理、循环依赖解决方案、以及Bean实例化的具体步骤。深入探讨了FactoryBean的使用、依赖查找逻辑、实例化前的处理与AOP的应用。

1 bean 加载的基本逻辑

加载 bean 的功能,在 Spring 中的调用方式。

TestBean testBean = (TestBean) xmlBeanFactory.getBean("testBean");

功能实现源码:

// AbstractBeanFactory.java
public Object getBean(String name) throws BeansException {
	return doGetBean(name, null, null, false);
}

/**
 * 1. 转换对应的 beanName,传入的name可能是别名,FactoryBean,要进行以下的处理 transformedBeanName
 * 	 * 去除FactoryBean 的修饰符,即name="$aa",就先去除& 变成 name="aa"
 * 	 * 取指定alias所表示的最终beanName
 * 2. 尝试从缓存中加载单例 getSingleton
 * 3. bean 的实例化 getObjectForBeanInstance
 * 4. 原型模式的依赖检查 isPrototypeCurrentlyInCreation(beanName)
 * 5. 检测 parentBeanFactory
 * 6. 将存储 XML 配置文件的 GernericBeanDefinition 转换为RootBeanDefinition getMergedLocalBeanDefinition
 * 7. 寻找依赖 getDependsOn
 * 8. 针对不同的 scope 进行 bean 的创建
 * 9. 类型转换
 *
 * 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
 */
@SuppressWarnings("unchecked")
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
		@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
	//1. 转换对应的 beanName,获取对应的beanName, "&test" -> "test"
	final String beanName = transformedBeanName(name);
	Object bean;

	// Eagerly check singleton cache for manually registered singletons.
	/*
	 *  检查缓存中或实例工厂中是否有对应的实例
	 *
	 *  在创建单例bean 时对存在依赖注入的情况,而在创建依赖时为了避免循环依赖,
	 *  Spring 创建bean 的原则是不等bean 创建完机会将创建bean 的ObjectFactory 提早曝光
	 *  也就是将ObjectFactory 加入缓存中,一旦下个bean 创建时需要依赖上个bean 则直接使用 ObjectFactory
	 */
	// 2. 直接尝试从缓存中获取 或者从 singletonFactories 中的 ObjectFactory 中获取
	// singletonObjects > earlySingletonObjects > singletonFactories
	// singletonObjects -> 在 getSingleton(beanName, ObjectFactory) 方法中 addSingleton 加入
	// earlySingletonObjects -> singletonFactories 获取 objectFactory#getObject 后 加入
	// singletonFactories -> 在 creatBean -> doCreateBean 方法中创建完成实例后 如果需要循环依赖由 addSingletonFactory 加入
	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. 返回对应的实例,有时候存在诸如 FactoryBean#getObject 的情况并不是直接返回实例本身而是返回指定方法返回的实例
		bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
	}
	else {
		// 没有缓存
		// Fail if we're already creating this bean instance:
		// We're assumably within a circular reference.
		// 只有在单例情况下才会尝试解决循环依赖,原型模式下,
		// 如果存在 A中有B的属性,B中有A的属性,那么依赖注入的时候就会
		// 4. 产生当A还未创建完成的时候因为B的创建再次返回创建A,造成循环依赖
		if (isPrototypeCurrentlyInCreation(beanName)) {
			// 如果 scope 为 property 时,要获取的 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);
			}
			// 递归到 BeanFactory 中寻找
			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 {
			//将存储XML 配置文件的 GernericBeanDefinition 转换为 RootDefinition,
			//如果指定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);
					}
					catch (NoSuchBeanDefinitionException ex) {
						throw new BeanCreationException(mbd.getResourceDescription(), beanName,
								"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
					}
				}
			}

			// Create bean instance.
			//实例化依赖后,就可以实例化本身了
			//singleton
			if (mbd.isSingleton()) {
				//到这里,说明缓存中没有该实例, 在 getSingleton 方法中会记录 beanName 正在加载的状态
				//getSingleton(beanName, ObjectFactory)
				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;
					}
				});
				//返回对应的实例,有时候存在诸如 FactoryBean#getObject 的情况并不是直接返回实例本身而是返回指定方法返回的实例
				bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
			}
			//property
			else if (mbd.isPrototype()) {
				// 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 实例化
				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, () -> {
						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;
		}
	}

	// Check if required type matches the type of the actual bean instance.
	// 检查需要的类型是否符合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
传入的 name 可能是别名,FactoryBean,要进行以下的处理。transformedBeanName方法。
* 去除 FactoryBean 的修饰符,即 name="$aa",就先去除& 变成 name=“aa”
* 取指定alias所表示的最终 beanName

2)尝试从缓存中加载单例
单例在 Spring 的容器只会被实例化一次,后续再获取 bean 就直接从缓存单例缓存中获取。尝试从缓存中加载,如果加载不成功,就再次尝试从 singletonFactories 中加载。由于再创建单例的时候会存在依赖注入的情况,为了避免循环依赖,再Spring中创建 bean 的原则是不等 bean 创建完成就将创建 ObjectFactory 提早曝光到缓存中,需要依赖时就直接使用 ObjectFactort。getSingleton方法。

3)bean 的实例化
如果从缓存中获取了 bean 的原始状态,则需要对 bean 进行实例化。需要说明,缓存中记录的只是最原始的 bean 状态。比如,我们需要对工厂bean 进行处理,这里得到的只是工厂 bean 的初始状态,真正需要的时工厂 bean 中定义的 factory-method 方法中返回的bean。getObjectForBeanInstance方法。

4)原型模式的依赖检查
只有单例模式下才会尝试解决循环依赖。当isPrototypeCurrentlyInCreation(beanName) == true时处理。

5)检测 parentBeanFactory
parentBeanFactory != null && !containsBeanDefinition(beanName),如果当前加载的 XML 配置文件不包含 beanName 的配置且 parentBeanFactory 不为空,则只能到 parentBeanFactory 去尝试加载,然后递归去调用 getBean 方法。

6)将存储 XML 配置文件的 GernericBeanDefinition 转换为 RootBeanDefinition getMergedLocalBeanDefinition方法。
因为从 XML 配置文件中读取到的 bean 信息是存储在 GernericBeanDefinition 中的,但是所有的 bean 后续处理都是针对 RootBeanDefinition 的,所以需要转换,转换时如果父类 bean 不为空的话,则会一并合并父类的属性。

7)寻找依赖 getDependsOn方法。
因为 bean 的初始化中可能会用到吗某些属性,而某些属性可能是动态配置的,并且配置成依赖于其他的 bean,那么就需要先加载依赖的 bean,所以在 Spring 的加载顺序中,在初始化某一个 bean 的时候会首先初始化这个 bean 所对于的依赖。

8)针对不同的 scope 进行 bean 的创建。
在 Spring 中存在着不同的 scope,其中默认的是 singleton,还有其它例如 prototype,request 之类的。

9)类型转换
该功能的作用是将返回的 bean 转换为 requiredType 所指定的类型。在 String 中提供了各式的转换器,也可以自定义扩展转换器。

请添加图片描述

2 FactoryBean 的使用

某些情况下直接实例化 bean 过程比较复杂。这时采用编码的方式可以提供一个简单的方案,可以通过实现 FactoryBean 接口定制实例化 bean 的逻辑。

FactoryBean 接口对于 Spring 框架来说有重要的地位,本身提供了 70 多个 FactoryBean 的实现。下面是该接口的声明:

public interface FactoryBean<T> {
	/**
	 * 返回由 FactoryBean 创建的 Bean 实例,如果 isSingleton() 返回 true,
	 * 则该实例会放到 Spring 容器中的单实例缓存池中
	 * /
	T getObject() throws Exception;
	/**
	 * 返回 FactoryBean 创建的 bean 类型
	 * /
	Class<?> getObjectType();
	/**
	 * 返回由 FactoryBean 创建的 bean 实例的作用域是 Singleton 还是 prototype
	 * /
	default boolean isSingleton() {
		return true;
	}
}

当配置文件中 的 class 属性配置的实现类的 FactoryBean 时,通过getBean()方法返回的不是 FactoryBean 本身,而是FactoryBean#getObject()方法所返回的对象,相当于FactoryBean#getObject()代理了getBean()方法。例子如下:

// 真正需要创建的 bean
public class Car {

	private int maxSpeed;

	private String brand;

	private double price;

	public int getMaxSpeed() {
		return maxSpeed;
	}

	public void setMaxSpeed(int maxSpeed) {
		this.maxSpeed = maxSpeed;
	}

	public String getBrand() {
		return brand;
	}

	public void setBrand(String brand) {
		this.brand = brand;
	}

	public double getPrice() {
		return price;
	}

	public void setPrice(double price) {
		this.price = price;
	}

	@Override
	public String toString() {
		return "Car{" +
				"maxSpeed=" + maxSpeed +
				", brand='" + brand + '\'' +
				", price=" + price +
				'}';
	}
}

// 使用 FactoryBean#getObject 方法创建
public class CarFactoryBean implements FactoryBean<Car> {
	private String carInfo;

	@Override
	public Car getObject() throws Exception {
		Car car = new Car();
		String[] split = carInfo.split(",");
		car.setMaxSpeed(Integer.parseInt(split[0]));
		car.setBrand(split[1]);
		car.setPrice(Double.parseDouble(split[2]));
		return car;
	}

	@Override
	public Class<?> getObjectType() {
		return Car.class;
	}

	@Override
	public boolean isSingleton() {
		return true;
	}

	public String getCarInfo() {
		return carInfo;
	}

	public void setCarInfo(String carInfo) {
		this.carInfo = carInfo;
	}
}

配置文件配置 bean:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

	<bean id="car" class="org.springframework.test.factoryb.CarFactoryBean">
		<property name="carInfo" value="400,跑车,200000" />
	</bean>
</beans>

当调用 getBean(“carInfo”) 时,Spring 通过反射发现 CarFactoryBean 实现了 FactoryBean 接口,就会调用 CarFactoryBean#getObject方法返回。如果希望获取 CarFactoryBean 的实例,则需要在 beanName 前加上"&“前缀,如 getBean(”&carInfo")。

3 缓存中获取单例 bean

尝试从缓存中加载单例,单例在Spring的容器只会被实例化一次,后续再获取 bean 就直接从缓存单例缓存中获取。尝试从缓存中加载,如果加载不成功,就再次尝试从 singletonFactories 中加载。由于再创建单例的时候会存在依赖注入的情况,为了避免循环依赖,再Spring中创建 bean 的原则是不等 bean 创建完成就将创建 ObjectFactory 提早曝光到缓存中,需要依赖时就直接使用 ObjectFactory。

/*
 *  检查缓存中或实例工厂中是否有对应的实例
 *
 *  在创建单例bean 时对存在依赖注入的情况,而在创建依赖时为了避免循环依赖,
 *  Spring 创建bean 的原则是不等bean 创建完机会将创建bean 的ObjectFactory 提早曝光
 *  也就是将ObjectFactory 加入缓存中,一旦下个bean 创建时需要依赖上个bean 则直接使用 ObjectFactory
 */
@Override
@Nullable
public Object getSingleton(String beanName) {
	//设置标识,允许早期依赖
	return getSingleton(beanName, true);
}

/**
 * 1. singletonObjects(一级缓存):用于保存 BeanName 和创建 bean 实例之间的关系,beanName -> bean instance
 * 2. singletonFactories(三级缓存):用于保存 BeanName 和创建 bean 的工厂之间的关系,beanName -> ObjectFactory
 * 3. earlySingletonObjects(二级缓存):也是用来保存 BeanName 和创建 bean 实例之间的关系,
 * 当一个单例 bean 被放到这里后,在bean 的创建过程中,就可以通过 getBean 方法获取到了,其目的是用来检测循环用
 */
@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 方法将对应的
				//ObjectFacFactory 初始化策略存储在 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;
}

获取逻辑:
1)首先尝试从 singletonObjects 中获取实例。
2)获取不到,尝试从 earlySingletonObjectts 中获取。
3)依然获取不到则尝试从 singletonFactories 中获取 beanName 对应的 ObjectFactory,然后调用这个 ObjectFactory 的 getObject 方法来创建bean,并放到 earlySingletonObjects 中去,然后从 singletonFactories 移除 beanName 对应的 ObjectFactory。该操作在需要循环依赖的时候才进行,即 allowEarlyReference 为 true 的时候。

4 从 bean 的实例中获取对象

无论是从缓存中获取 bean 还是根据不同的 scope 策略加载 bean。获得 bean 的第一件事就是调用这个方法来检测准确性。检测当前 bean 是否为 FactoryBean,如果是就要调用该 bean 中的 getObject 方法返回。如果是工厂 bean,需要获取 factor-method 方法中返回的 bean。

protected Object getObjectForBeanInstance(
	Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {

	// Don't let calling code try to dereference the factory if the bean isn't a factory.
	//如果指定的 name 是以工厂相关的(以&为前缀)
	if (BeanFactoryUtils.isFactoryDereference(name)) {
		//空
		if (beanInstance instanceof NullBean) {
			return beanInstance;
		}
		//不是FactoryBean 类型,则抛出异常
		if (!(beanInstance instanceof FactoryBean)) {
			throw new BeanIsNotAFactoryException(beanName, 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.
	//如果 beanInstance 是普通 bean 或是 FactoryBean 且以 & 为前缀
	if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {
		return beanInstance;
	}

	//加载FactoryBean
	Object object = null;
	if (mbd == null) {
		//从缓存中加载
		object = getCachedObjectForFactoryBean(beanName);
	}
	if (object == null) {
		// Return bean instance from factory.
		//到这里表名一定是 FactoryBean 类型
		FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
		// Caches object obtained from FactoryBean if it is a singleton.
		//containsBeanDefinition j检测beanDefinitionMap 中也就是在所有
		//已经加载的类中检测是否定义beanName
		if (mbd == null && containsBeanDefinition(beanName)) {
			//将XML配置文件的GernericBeanDefinition 转换为RootBeanDefinition
			//,如果BeanName 是子 Bean 的话同时合并父类的相关属性
			mbd = getMergedLocalBeanDefinition(beanName);
		}
		//是否是用户自定义而不是应用程序本身定义的
		boolean synthetic = (mbd != null && mbd.isSynthetic());
		//核心
		object = getObjectFromFactoryBean(factory, beanName, !synthetic);
	}
	return object;
}

上述代码主要逻辑:
1)对 FactoryBean 正确性验证
2)对非 FactoryBean 不做处理
3)如果是从缓存中获取的 bean 即参数 mbd == null,则尝试调用getCachedObjectForFactoryBean(beanName)方法从 factoryBeanObjectCache 缓存中获取对象。

protected Object getCachedObjectForFactoryBean(String beanName) {
	return this.factoryBeanObjectCache.get(beanName);
}

4)对 bean 进行装换成 FactoryBean
5)将从 Factory 中解析 bean 的工作委托给 getObjectFromFactoryBean

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) {
				//获取
				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 {
							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的后处理器,see AbstractAutowireCapableBeanFactory
				object = postProcessObjectFromFactoryBean(object, beanName);
			}
			catch (Throwable ex) {
				throw new BeanCreationException(beanName, "Post-processing of FactoryBean's object failed", ex);
			}
		}
		return object;
	}
}

主要逻辑:
1)是单例且在 singletonObjects(以及缓存) 中存在
(1)尝试从 factoryBeanObjectCache 缓存中
(2)调用 doGetObjectFromFactoryBean 获取实例
(3)调用 postProcessObjectFromFactoryBean 方法
(4)记录到缓存中去
2)不是单例
(1)调用 doGetObjectFromFactoryBean 获取实例

private Object doGetObjectFromFactoryBean(final FactoryBean<?> factory, final String beanName)
			throws BeanCreationException {

	Object object;
	try {
		//权限验证
		if (System.getSecurityManager() != null) {
			AccessControlContext acc = getAccessControlContext();
			try {
				object = AccessController.doPrivileged((PrivilegedExceptionAction<Object>) factory::getObject, acc);
			}
			catch (PrivilegedActionException pae) {
				throw pae.getException();
			}
		}
		else {
			//调用FactoryBean 的getObject 方法获取bean
			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;
}

(2)调用 postProcessObjectFromFactoryBean 方法(后处理器)

// AbstrctAutowireCapableBeanFactory.java
/**
 * 尽可能保证所有的bean 初始化后都会调用注册的 BeanPostProcessor 的
 * postProcessAfterInitialization 方法进行处理,在开发过程中,可以对此特性进行自己的业务逻辑
 */
@Override
protected Object postProcessObjectFromFactoryBean(Object object, String beanName) {
	return applyBeanPostProcessorsAfterInitialization(object, beanName);
}

**
 * Spring 中在bean初始化后尽量肯保证将注册的后处理器
 * 的 postProcessAfterInitialization 方法应用到该 bean 中
 */
@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
		throws BeansException {

	Object result = existingBean;
	for (BeanPostProcessor processor : getBeanPostProcessors()) {
		//
		Object current = processor.postProcessAfterInitialization(result, beanName);
		if (current == null) {
			return result;
		}
		result = current;
	}
	return result;
}

Spring 中在 bean 初始化后尽量肯保证将注册的后处理器的postProcessAfterInitialization方法应用到该 bean 中。在开发中可以通过实现 BeanPostProcessor,将其加入到 AbstractBeanFactory 的 beanPostProcessors 集合中,来实现 bean 初始化前后的自定义逻辑。

5 获取单例

如果从缓存中获取不到单例,那么就要调用重载方法 getSingleton 方法来获取单例。

// AbstractBeanFactory#getBean
//实例化依赖后,就可以实例化本身了
//singleton
if (mbd.isSingleton()) {
	//到这里,说明缓存中没有该实例, 在 getSingleton 方法中会记录 beanName 正在加载的状态
	//getSingleton(beanName, ObjectFactory)
	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;
		}
	});
	//返回对应的实例,有时候存在诸如 FactoryBean#getObject 的情况并不是直接返回实例本身而是返回指定方法返回的实例
	bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}

调用 getSingleton(String beanName, ObjectFactory<?> singletonFactory)

/**
 * 缓存中没有的话,就执行该方法获取单例
 *
 * 使用了回调方法,是的程序可以在单例的创建前后做一些准备及处理
 * 操作,真正的获取单例bean的方法是在 singletonFactory 的 getObject 中实现
 *
 * 操作步骤
 * 1. 检查缓存中是否已经加载过
 * 2. 若没有加载,则记录beanName 的正在加载状态
 * 3. 加载单例前记录加载状态
 *   * beforeSingletonCreation:记录记载状态,this.singletonsCurrentlyInCreation.add(beanName)
 * 4. 通过调用参数传入的 ObjectFactory 的 getObject 方法实例化bean
 * 5. 加载单例后的处理方法调用
 * 	 * afterSingletonCreation:当bean记载结束后需要移除缓存中该bean的正在加载状态的记录 this.singletonsCurrentlyInCreation.remove(beanName)
 * 6. 将结果记录至缓存并删除加载bean过程中所记录的各种辅助状态
 * 	 addSingleton:
 * 	 	this.singletonObjects.put(beanName, singletonObject);
 * 	 	this.singletonFactories.remove(beanName);
 * 	 	this.earlySingletonObjects.remove(beanName);
 * 	 	this.registeredSingletons.add(beanName);
 * 7. 返回处理结果
 * 	 实际创建bean:createBean(beanName, mbd, args);
 */
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
	Assert.notNull(beanName, "Bean name must not be null");
	//全局变量同步操作
	synchronized (this.singletonObjects) {
		//首先检查对应的 bean 是否已经加载过,因为singleton模式
		//就是复用用以创建的bean,所以这一步是必须的
		Object singletonObject = this.singletonObjects.get(beanName);
		//如果为空就可以进行singleton的实例化
		if (singletonObject == null) {
			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 + "'");
			}
			//1. 记录该 beanName 正在加载的状态
			beforeSingletonCreation(beanName);
			boolean newSingleton = false;
			boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
			if (recordSuppressedExceptions) {
				this.suppressedExceptions = new LinkedHashSet<>();
			}
			try {
				//实例化 AbstractAutowireCapableBeanFactory#createBean
				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;
				}
				//3. 移除该 beanName 正在加载的状态的记录
				afterSingletonCreation(beanName);
			}
			if (newSingleton) {
				//4. 加入到缓存中去
				addSingleton(beanName, singletonObject);
			}
		}
		return singletonObject;
	}
}

上述代码使用了回调方法,使得程序可以在单例创建前后做一些准备及处理操作,真正获取单例 bean 的方法是在 ObjectFactory 实例 singletonFactory 中实现的。上述主要逻辑如下:
1)检查缓存中是否以及加载过。
2)加载单例前记录加载状态,用于对循环依赖进行检测。

protected void beforeSingletonCreation(String beanName) {
	if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) {
		throw new BeanCurrentlyInCreationException(beanName);
	}
}

3)通过调用参数传入的 ObjectFactory 的 getObject 方法实例化 bean
4)记载单例后的方法调用

protected void afterSingletonCreation(String beanName) {
	if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.remove(beanName)) {
		throw new IllegalStateException("Singleton '" + beanName + "' isn't currently in creation");
	}
}

同步骤3的加载状态相似,当 bean 加载结束后需要移除缓存中对该 bean 的正在加载状态的记录。
5)将结果记录至缓存 singletonObjects 中,并移除加载 bean 过程中所记录的各种辅助状态

protected void addSingleton(String beanName, Object singletonObject) {
	synchronized (this.singletonObjects) {
		//一级缓存
		this.singletonObjects.put(beanName, singletonObject);
		//3级缓存
		this.singletonFactories.remove(beanName);
		//2级缓存
		this.earlySingletonObjects.remove(beanName);
		//以加载的缓存
		this.registeredSingletons.add(beanName);
	}
}

6)返回处理结果
bean 的加载逻辑其实是在传入的 ObjectFactory 类型的参数 singletonFactory 中定义的。

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;
	}
});

6 准备创建 bean

createBean 方法为创建实例做一些前期的准备,而真正的逻辑是在 doCreateBean 中实现的。

/**
 * 准备创建 bean
 * 1. 根据设置的 class 属性或者根据className 解析Class
 * 2. 对 override 属性进行标记
 * 	  对XML 配置中配置的 lookup-method 和 replace-method,而这两个
 * 	配置的加载是统一存放在 BeanDefinition 的 methodOverrides 属性中的,
 * 3. 应用初始化前的后处理器,解析指定 bean 是否存在初始化前的短路操作
 * 4. 创建 bean
 */
@Override
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;

	// 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.
	//  锁定class,根据设置的 class 属性或者 className 来解析class
	Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
	if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
		mbdToUse = new RootBeanDefinition(mbd);
		mbdToUse.setBeanClass(resolvedClass);
	}

	// Prepare method overrides.
	try {
		//验证及准备覆盖的方法,处理 override 属性,
		//look-method replace-method
		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.
		//给 BeanPostInstantiation 一个机会来返回代理来替代真正的实例,前置处理
		//AOP 是在这里判断的 InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation
		Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
		if (bean != null) {
			return bean;
		}
	}
	catch (Throwable ex) {
		throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
				"BeanPostProcessor before instantiation of bean failed", ex);
	}

	try {
		//真正创建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);
	}
}

上述代码主要逻辑
1)根据设置的 class 属性或者根据 className 来解析 class。
2)对 overrive(look-method, replace-method) 属性进行标记及验证。来自 lookup-method,replace-method 的属性,存储在 BeanDefinition 的 methodOverrides 属性里。
3)应用初始化前的后处理器,解析指定 bean 是否存在初始化前的短路操作。
4)创建bean。

6.1 处理 override 属性

调用 AbstractBeanDefinition 的 prepareMethodOverrides 方法

public void prepareMethodOverrides() throws BeanDefinitionValidationException {
	// Check that lookup methods exist and determine their overloaded status.
	//如果由 override 属性
	if (hasMethodOverrides()) {
		//循环调用 prepareMethodOverride 方法处理每一个属性
		getMethodOverrides().getOverrides().forEach(this::prepareMethodOverride);
	}
}

/**
 * 在 bean 实例化时,如果检测到存在methodOverride 属性,
 * 会动态的为当前 bean 生成代理并使用对应的拦截器为 bean 做增强处理
 * 相关的逻辑在 bean 的实例化时实现
 * 这个方法只是为做是否由重载方法的校验
 */
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);
	}
}

对于方法的匹配来讲,如果一个类中存在若干个重载方法,那么,在函数调用及增强的时候还需要根据参数类型进行匹配,来最终确认当前调用的到底是哪个函数。但是如果当前类中只有一个方法,那么就不需要进行方法的参数匹配验证了。

6.2 实例化的前置处理

在真正调用 doCreateBean 方法创建 bean 之前使用了Object bean = resolveBeforeInstantiation(beanName, mbdToUse);方法对 BeanDefinition 中的属性做一些前置处理。在函数中还提供了短路操作。

if (bean != null) {
	return bean;
}

当经过前置处理的后返回的结果如果不为空,那么会直接返回结果。AOP 功能的实现就是基于这里的判断。

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 实例化后都调用
					// BeanPostProcessor 的 postProcessAfterInitialization 方法
					bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
				}
			}
		}
		mbd.beforeInstantiationResolved = (bean != null);
	}
	return bean;
}

该方法其中 applyBeanPostProcessorsBeforeInstantiation 和 applyBeanPostProcessorsAfterInitialization 是主要的处理逻辑。这两个方法主要对后处理器中的所有 InstantiationAwareBeanPostProcessor 类型的后处理器进行 postProcessBeforeInstantiation 方法和所有 BeanPostProcessor 类型的后处理器进行 postProcessAfterInitialization 方法

1)实例化前的后处理器应用。
bean 的实例化前调用,也就是将 AbstractBeanDefinition 转换为BeanWrapper 前处理。给子类一个修改 BeanDefinition 的机会,即当程序经过这个方法后,bean 可能已经不是我们认为的 bean 了,可能成为了一个经过处理的代理 bean。

/**
 * bean 的实例化前调用,也就是将 AbstractBeanDefinition 转换为BeanWrapper 前处理。
 * 给子类一个修改 BeanDefinition 的机会,
 */
@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)实例化后的后处理器应用
Spring 的规则是在 bean 的初始化后尽可能保证将注册的后处理器的 postProcessAfterInitialization方法应用到该bean 上,因为如果返回的 bean 不为空,那么便不会再次经历 普通 bean 的创建过程,所以只能在这里应用后处理器的 postProcessAfterInitialization方法。

/**
 * Spring 中在bean初始化后尽量肯保证将注册的后处理器
 * 的 postProcessAfterInitialization 方法应用到该 bean 中
 */
@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
		throws BeansException {

	Object result = existingBean;
	for (BeanPostProcessor processor : getBeanPostProcessors()) {
		//
		Object current = processor.postProcessAfterInitialization(result, beanName);
		if (current == null) {
			return result;
		}
		result = current;
	}
	return result;
}

7 循环依赖

7.1 概念

循环依赖就是循环引用,就是两个或多个 bean 相互之间持有对方,比如 TestA 引用 TestB,TestB 引用 TestC,TestC 引用 TestA,则它们最终反映成为一个环。如下图。
在这里插入图片描述

7.2 Spring 如何解决循环依赖

Spring 容器循环依赖包括构造器循环依赖和 setter 循环依赖。Spring 容器是如何解决循环依赖的?首先定义下循环依赖类:

public class TestA {

    private TestB testB;

    public TestA(final TestB testB) {
        this.testB = testB;
    }

    public void a() {
        testB.b();
    }

    public TestB getTestB() {
        return testB;
    }

    public void setTestB(final TestB testB) {
        this.testB = testB;
    }
}

public class TestB {

    private TestC testC;

    public TestB(final TestC testC) {
        this.testC = testC;
    }

    public void b() {
        testC.c();
    }

    public TestC getTestC() {
        return testC;
    }

    public void setTestC(final TestC testC) {
        this.testC = testC;
    }
}

public class TestC {

    private TestA testA;

    public TestC(final TestA testA) {
        this.testA = testA;
    }

    public void c() {
        testA.a();
    }

    public TestA getTestA() {
        return testA;
    }

    public void setTestA(final TestA testA) {
        this.testA = testA;
    }
}

1)构造器依赖
表示通过构造器注入构成的循环依赖,此依赖是无法解决的,只能抛出 BeanCurrentlyInCreationException.

如在创 TestA 类时, 构造器需要 TestB 类,那将去创建 TestB,在创建 TestB 类时又发现需要 TestC 类, 又去创建 TestC,在创建 TestC 时发现又需要 TestA ,从而形成 个环,没办法创建。

Spring 将每一个正在创建的 bean 标识符放在一个**"当前创建 bean 池(singletonsCurrentlyInCreation)"中,该 bean
标识符在创建过程中将一直保持在这个池中,因此如果创建 bean 的过程中发现自己已经在该池中,会抛出
BeanCurrentlyInCreationException**表示循环依赖;对于创建完毕的 bean 将从该池中移除。

下述例子说明:

  1. 创建配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="testA" class="org.springframework.test.circledep.TestA">
        <constructor-arg index="0" ref="testB"/>
    </bean>

    <bean id="testB" class="org.springframework.test.circledep.TestB">
        <constructor-arg index="0" ref="testC"/>
    </bean>

	<bean id="testC" class="org.springframework.test.circledep.TestC">
		<constructor-arg index="0" ref="testA" />
	</bean>
</beans>
  1. 测试用例
public class Main {

    public static void main(String[] args) {
        new ClassPathXmlApplicationContext("test/circledep/CircleDepTest.xml");
    }
}

上述代码分析如下:

  • Spring 容器创建 “testA” bean,首先去 "当前创建 bean 池(singletonsCurrentlyInCreation)"查找是否当前 bean 正在创建,如果没有发现,则继续准备其需要的构造器参数 “testB”,并将 “testA” 标识符放到 “当前创建 bean 池(singletonsCurrentlyInCreation)” 中。
  • Spring 容器创建 “testB” bean,首先去 "当前创建 bean 池(singletonsCurrentlyInCreation)"查找是否当前 bean 正在创建,如果没有发现,则继续准备其需要的构造器参数 “testC”,并将 “testB” 标识符放到 “当前创建 bean 池(singletonsCurrentlyInCreation)” 中。
  • Spring 容器创建 “testC” bean,首先去 "当前创建 bean 池(singletonsCurrentlyInCreation)"查找是否当前 bean 正在创建,如果没有发现,则继续准备其需要的构造器参数 “testA”,并将 “testC” 标识符放到 “当前创建 bean 池(singletonsCurrentlyInCreation)” 中。
  • 到此,Spring 再去创建"testA" bean,发现该 bean 表示符以及在 “当前创建 bean 池(singletonsCurrentlyInCreation)” 中了,表示循环依赖,抛出 BeanCurrentlyInCreationException。

2)setter 循环依赖
表示通过 setter 注入方式构成的循环依赖。对于 setter 注入方式构成的循环依赖是通过 Spring 容器提前暴露刚完成构造器注入但未完成其他步骤(如 setter 注入)的 bean 来完成的,只能解决单例作用域的循环依赖。通过提前暴露一个单例工厂方法,从而使其他 bean 能引用到该 bean。

如下代码所示:

// AbstractAutowireCapableBeanFactory#doCreateBean

//是否需要提早曝光:单例&允许循环依赖&当前 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 再一次依赖引用,主要应用 SmartInstantiationAwareBeanPostProcessor#getEarlyBeanReference
	//其中我们熟知的 AOP  就是在这里将 advice 动态织入 bean 中,若没有则直接返回 bean,不做任何处理。
	addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}

具体步骤如下:

  • Spring 容器创建单例 “testA” bean,首先根据无参构造创建 bean,并暴露一个 ”ObjectFactory“ 用于返回一个提前暴露一个创建中的 bean,并将 “testA” 标识符放到 “当前创建 bean 池(singletonsCurrentlyInCreation)” 中,然后进行 setter 注入 ”testB“。
  • Spring 容器创建单例 “testB” bean,首先根据无参构造创建 bean,并暴露一个 ”ObjectFactory“ 用于返回一个提前暴露一个创建中的 bean,并将 “testB” 标识符放到 “当前创建 bean 池(singletonsCurrentlyInCreation)” 中,然后进行 setter 注入 ”testC“。
  • Spring 容器创建单例 “testC” bean,首先根据无参构造创建 bean,并暴露一个 ”ObjectFactory“ 用于返回一个提前暴露一个创建中的 bean,并将 “testC” 标识符放到 “当前创建 bean 池(singletonsCurrentlyInCreation)” 中,然后进行 setter 注入 ”testA“。进行注入 ”testsA“ 时由于提前暴露了"ObejctFactory",从而使用它返回提前暴露一个创建中的 bean。
  • 最后再 依赖注入 “testB” 和 “testA”,完成 setter 注入。

3)property 范围的依赖处理
对于 property 作用域的 bean,Spring 无法完成依赖注入,因为 Spring 容器不进行缓存 property 作用域的 bean,无法提前暴露一个创建中的 bean。 对于 singleton 的 bean 可以通过设置AbstractAutowireCapableBeanFactory#setAllowCircularReferences(false)来禁用循环依赖。

示例如下:

  1. 配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="testA" class="org.springframework.test.circledep.TestA" scope="prototype">
        <property name="testB" ref="testB" />
    </bean>

    <bean id="testB" class="org.springframework.test.circledep.TestB" scope="prototype">
        <property name="testC" ref="testC" />
    </bean>

	<bean id="testC" class="org.springframework.test.circledep.TestC" scope="prototype">
        <property name="testA" ref="testA" />
	</bean>
</beans>
  1. 测试用例
public class Main {

    public static void main(String[] args) {
        new ClassPathXmlApplicationContext("test/circledep/CircleDepTest.xml");
    }
}

8 创建 bean

当经过 resolveBeforeInstantiation 方法后,程序有两个选择,如果创建了代理或者说重写了 InstantiationAwareBeanPostProcessor 的 postProcessorBeforeInstantiation 方法并在该方法中改变了 bean,则直接返回,否则需要进行常规 bean 的创建,在 doCreateBean 中实现。

// AbstractAutowireCapableBeanFactory.java

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
	throws BeanCreationException {

	// Instantiate the bean.
	BeanWrapper instanceWrapper = null;
	if (mbd.isSingleton()) {
		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.isTraceEnabled()) {
			logger.trace("Eagerly caching bean '" + beanName +
					"' to allow for resolving potential circular references");
		}
		//为避免后期循环依赖,可以在 bean 初始化前将创建实例的 ObjectFactory 加入工厂。
		//getEarlyBeanReference:对 bean 再一次依赖引用,主要应用 SmartInstantiationAwareBeanPostProcessor#getEarlyBeanReference
		//其中我们熟知的 AOP  就是在这里将 advice 动态织入 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,实现了 InitializingBean 接口
		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) {
		//如果有依赖注入,会从缓存中获取,从 singletonFactories
		Object earlySingletonReference = getSingleton(beanName, false);
		//earlySingletonExposure 只有在检测到有循环依赖的情况下才会不为空
		// A -> B -> A
		// 当去 A 的时候不为空,说明 B 中已经取出 A 并设置到 B 中了
		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 {
		//根据 scope 注册 DestructionAwareBeanPostProcessor,注册销毁后的处理
		registerDisposableBeanIfNecessary(beanName, bean, mbd);
	}
	catch (BeanDefinitionValidationException ex) {
		throw new BeanCreationException(
				mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
	}

	return exposedObject;
}

主要逻辑:
1)如果是单例则首先需要清除缓存。
2)实例化 bean,将 BeanDefinition 转换为 BeanWrapper。
(1)如果存在工厂方法,则使用工厂方法进行初始化。
(2)如果一个类有多个构造函数,每个构造函数都有不同的参数,所以需要根据参数锁定构造函数并进行初始化。
(3)如果既不存在工厂方法也不存在带有参数的构造函数,则使用默认的构造函数进行 bean 的实例化。
3)MergedBeanDefinitionPostProcessor 的应用。
bean 合并后的处理,Autowired 注解正是通过此方法实现诸如类型的预解析。
4)依赖处理。
在 Spring 中会有循环依赖的情况,涉及到自动注入的步骤时,通过缓存中的 ObjectFactory 来创建实例。
5)属性填充。将所有属性填充到 bean 的实例中。
6)循环依赖检查。
在 Spring 解决循环依赖只对单例有效,而对于 prototype bean 会抛出异常,在这个步骤里面会检测已经加载的 bean 是否
已经出现了依赖循环,并判断是再需要抛出异常。
7)注册 DisposableBean。
如果配置了 destory-method,这里需要注册以便在销毁时使用。
8)完成创建并返回。

8.1 创建 BeanWrapper 实例

使用 instanceWrapper = createBeanInstance(beanName, mbd, args)方法。

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);

	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());
	}
	//使用回调函数创建,ApplicationContext
	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 {
			//使用默认构造函数构造 SimpleInstantiationStrategy#instantiateBean
			return instantiateBean(beanName, mbd);
		}
	}

	// Candidate constructors for autowiring?
	//根据参数解析构造函数
	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);
	}

	// No special handling: simply use no-arg constructor.
	//使用默认构造函数构造
	return instantiateBean(beanName, mbd);
}

主要逻辑:
1)如果 RootBeanDefinition 存在 Supplier 类型的属性 instanceSupplier,则使用obtainFromSupplier(Supplier<?> instanceSupplier, String beanName)方法。
2)如果在 RootBeanDefinition 中存在 factoryMethodName 属性,即配置了 factory-method,那么 Spring 会尝试使用instantiateUsingFactoryMethod(beanName, mbd, args) 方法根据 RootBeanDefinition 中的配置生成实例。

protected BeanWrapper instantiateUsingFactoryMethod(
		String beanName, RootBeanDefinition mbd, @Nullable Object[] explicitArgs) {

	return new ConstructorResolver(this).instantiateUsingFactoryMethod(beanName, mbd, explicitArgs);
}

3)解析构造函数并进行构造函数的实例化,Spring 根据参数的不同去判断最终使用哪个构造函数。判断过程中,会将解析的结果存放到缓存 resolvedConstructorOrFactoryMethod 中。就不需要重复解析。
4)如果只有无参构造则使用 ```instantiateBean(final String beanName, final RootBeanDefinition mbd)````方法实例化。

8.1.1 obtainFromSupplier

Spring5 在 AbstractBeandefinition 添加了 instanceSupplier 属性。提供了一个回调方法来实例化对象,这比反射实例对象更有效率。

使用示例:

 GenericBeanDefinition beanDefinition = new GenericBeanDefinition();
beanDefinition.setBeanClass(User.class);
beanDefinition.setInstanceSupplier(SupplierBean::createUser);
...

通过 obtainFromSupplier 创建:

protected BeanWrapper obtainFromSupplier(Supplier<?> instanceSupplier, String beanName) {
	Object instance;

	String outerBean = this.currentlyCreatedBean.get();
	this.currentlyCreatedBean.set(beanName);
	try {
		// 实例化
		instance = instanceSupplier.get();
	}
	finally {
		if (outerBean != null) {
			this.currentlyCreatedBean.set(outerBean);
		}
		else {
			this.currentlyCreatedBean.remove();
		}
	}

	if (instance == null) {
		instance = new NullBean();
	}
	BeanWrapper bw = new BeanWrapperImpl(instance);
	initBeanWrapper(bw);
	return bw;
}

8.1.2 instantiateUsingFactoryMethod

如果 factoryMethodName 属性非空,则调用 instantiateUsingFactoryMethod 方法。

protected BeanWrapper instantiateUsingFactoryMethod(
	String beanName, RootBeanDefinition mbd, @Nullable Object[] explicitArgs) {

	return new ConstructorResolver(this).instantiateUsingFactoryMethod(beanName, mbd, explicitArgs);
}

8.1.3 autowireConstructor

对于实例的创建,Spring 中分为两种情况,一种是通用的实例化,另一种是带有参数的实例化。带有参数的实例化过程比较复杂,因为存在不确定性,所以在判断上做了大量工作。

rotected BeanWrapper autowireConstructor(
		String beanName, RootBeanDefinition mbd, @Nullable Constructor<?>[] ctors, @Nullable Object[] explicitArgs) {

	return new ConstructorResolver(this).autowireConstructor(beanName, mbd, ctors, explicitArgs);
}

委托给 ConstructorResolver#autowireConstructor 方法。

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;

	//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, true);
		}
	}

	//没有被缓存
	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.
		// 有构造注入功能 autowire = ‘constructor’
		boolean autowiring = (chosenCtors != null ||
				mbd.getResolvedAutowireMode() == AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR);
		// 构造器参数列表
		ConstructorArgumentValues resolvedValues = null;

		//所有构造函数的参数列表最小值
		int minNrOfArgs;
		// 给定了参数
		if (explicitArgs != null) {
			minNrOfArgs = explicitArgs.length;
		}
		else {
			//提取配置文件中的构造函数参数,indexedArgumentValues, genericArgumentValues
			ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues();
			//用于承载解析后的构造函数参数
			resolvedValues = new ConstructorArgumentValues();
			//能解析到的参数个数,有索引和无索引的解析
			minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);
		}
		//排序给定的构造函数,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 != 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, 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 (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 != null) {
			//将解析的构造函数加入缓存
			argsHolderToUse.storeCache(mbd, constructorToUse);
		}
	}

	Assert.state(argsToUse != null, "Unresolved constructor arguments");
	//将构造的实例加入 BeanWrapper 中,调用 instantiate 进行实例化
	bw.setBeanInstance(instantiate(beanName, mbd, constructorToUse, argsToUse));
	return bw;
}

主要逻辑:
1)构造函数参数的确定。
(1)根据 explicitArgs 判断,如果传入的参数 explicitArgs 不为空,,那么就可以直接确定参数,因为 explicitArgs 可以在用户获取 bean 的时候进行指定。在 AbstractBeanFactroy 中存在方法:

@Override
public Object getBean(String name, Object... args) throws BeansException {
	return doGetBean(name, null, args, false);
}

在获取 bean 的时候,用户不但可以指定 bean 的名称还可以指定 bean 所对应类的构造函数参数或者工厂方法的方法参数,主要用于静态工厂方法的调用,这里需要给定完全匹配的构造函数参数。
(2)缓存中获取。
如果确定参数的方法之前已经分析过,就是说构造函数参数已经记录在缓存中,那么就可以直接使用。但是在缓存中的参数可能是最终类型也可能是初始类型。如构造函数参数是 int 类型的 1,但是原始类型可能是 “1”,那么需要经过类型转换器的过滤以保证构造函数参数的完全对应。
(3)配置文件中获取。
如果不能根据传入的参数 explicitArgs 确定构造函数的参数也无法从缓存中获取信息,只能开始新的解析。分析从获取配置文件中配置的构造函数信息开始,即通过 mbd.getConstructorArgumentValues() 获取 BeanDefintion 中的信息。有了配置文件中的信息便可以获取对应的参数值信息了,获取参数值的信息包括直接指定值,如:直接指定函数中某个值为原始类型 String,或者是一个对其他 bean 的引用,而这一处理过程委托给 resolveConstructorArguments 方法。

2)构造函数的确定
这一步根据获取的构造器函数参数在所有的构造函数中锁定对应的构造函数,根据参数个数来匹配,所以在匹配之前需要对构造函数按照 public 构造函数优先参数数量降序,非 public 构造函数参数数量降序。这样在遍历的情况下可以迅速判断排在后面的构造函数参数个数是否符合条件。

由于在配置文件中,并不是唯一限制使用参数位置索引的方式创建,还支持通过名称设定参数值,如如<constructor-arg name=” aa">,因此需要确定构造函数中的参数名称。

获取参数名称有两种方式,一种是通过注解的方式直接获取,一种是使用 Spring 中提供的 ParameterNameDiscoverer 来获取。构造函数,参数名称,参数类型,参数值都确定后就可以锁定构造函数以及转换对应的参数类型。

3)根据确定的构造函数转换对应的参数类型。
使用 Spring 中提供的类型转换器或用户提供的自定义类型转换器。

4)构造函数不确定性的验证。
有时候即使构造函数、参数名称、参数类型 、参数值都确定后也不一定会直接锁定构造函数,不同构造函数的参数为父子关系,所以 Spring 在最后又做了一次验证。

5)根据实例化策略以及得到的构造函数及参数实例化 Bean。

8.1.4 instantiateBean

无参构造函数的实例化。

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 {
			//调用实例化策略进行实例化  SimpleInstantiationStrategy
			beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
		}
		BeanWrapper bw = new BeanWrapperImpl(beanInstance);
		//这里进行编辑器的注入 ResourceEditorRegistrar
		initBeanWrapper(bw);
		return bw;
	}
	catch (Throwable ex) {
		throw new BeanCreationException(
				mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
	}
}

无参的实例化主要是调用不同的实例化策略进行。

// SimpleInstantiationStrategy
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.
		//使用 cglib 动态代理
		return instantiateWithMethodInjection(bd, beanName, owner);
	}
}

主要逻辑:
1)首先判断 bd.hasMethodOverrides(),如果用户没有使用 look-method 和 replace-method,则直接使用反射实例化。
2)如果有,则需要将这两个配置提供的功能切入,所以需要使用动态代理将包含两个特性所对应的的逻辑的拦截器设置进去,返回包含拦截器的代理实例。

// CglibSubclassingInstantiationStrategy
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);
}

// CglibSubclassCreator
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;
}

private Class<?> createEnhancedSubclass(RootBeanDefinition beanDefinition) {
	Enhancer enhancer = new Enhancer();
	enhancer.setSuperclass(beanDefinition.getBeanClass());
	enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
	if (this.owner instanceof ConfigurableBeanFactory) {
		ClassLoader cl = ((ConfigurableBeanFactory) this.owner).getBeanClassLoader();
		enhancer.setStrategy(new ClassLoaderAwareGeneratorStrategy(cl));
	}
	enhancer.setCallbackFilter(new MethodOverrideCallbackFilter(beanDefinition));
	enhancer.setCallbackTypes(CALLBACK_TYPES);
	return enhancer.createClass();
}

8.2 记录创建 bean 的 ObjectFactory

在 doCreateBean 中有下述代码:

//是否需要提早曝光:单例&允许循环依赖&当前 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 再一次依赖引用,主要应用 SmartInstantiationAwareBeanPostProcessor#getEarlyBeanReference
	//其中我们熟知的 AOP  就是在这里将 advice 动态织入 bean 中,若没有则直接返回 bean,不做任何处理。
	addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}

这段代码主要是解决循环依赖的。

  • earlySingletonExposure:提早曝光的单例。
  • mbd.isSingleton():是否是单例。
  • this.allowCircularReferences:是否允许循环依赖,在 AbstractRefreshableApplicationContext 中提供了设置函数,可以提供硬编码设置或自定义命名空间进行配置。
  • isSingletonCurrentlyInCreation(beanName):是否在创建中,在 DefaultSingletonBeanRegistry 中有一个 singletonsCurrentlyInCreation 缓存来记录 bean 的加载状态。在 singleton 中,该记录的添加和删除是在 DefaultSingletonBeanRegistry 中 getSingleton(String beanName, ObjectFactory<?> singletonFactory) 方法中,由 beforeSingletonCreation(beanName) 方法记录,afterSingletonCreation(beanName) 方法移除。

变量 earlySingletonExposure 是是否是单例,是否允许循环依赖,是否对应的 bean 正在创建的条件的综合,当这些条件都满足时会执行 addSingletonFactory 操作。addSingletonFactory 的作用是什么?以 AB 循环依赖为例。
在这里插入图片描述
上图展示了 beanA 的流程,在创建 A 的时候首先会记录类对应 beanName,并将 beanA 的创建工厂加入缓存中,在对 A 属性填充就是调用 popelate 方法的时候又会再一次的对 B 进行递归创建。同样的,因为在 B 中同样存在 A 属性,因此在实例化 B 的 populate 方法中又会再次地初始化 A,也就是图形的最后,调用 getBean(A)。在这个函数中并不是直接去实例 A,而是先去检查缓存中是否有已经创建好的对应的 bean,或者是否已经建好的 ObjectFactory,而此时对于 A 的 ObjetFactory 早已经创建,所以便不会再去向后执行,而是直接调用 ObjectFactroy 去创建 A。 这里最关键的是 ObjectFactory 的实现。

addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));

getEarlyBeanReference 代码如下:

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;
}

在该方法中,除了后处理器的调用外基本没有别的逻辑。可以看到Spring解决循环依赖的方法是,在 B 中创建依赖 A 时提供 ObjectFactory 提供的实例化方法来中断 A 中的属性填充,使 B 中持有的 A 仅仅是刚刚初始化并没有填充任何属性的 A,而这正初始化的 A 的步骤还是在最开始创建 A 的时候进行的,但是由于 A 与 B 中的 A 所表示的属性地址是一样的,所以在 A 中填充属性也可以在 B 中的 A 获取到。

8.3 属性注入

属性的注入主要提供 populateBean(beanName, mbd, instanceWrapper);方法实现。

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,如:可以用来支持属性注入的类型
	if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
		for (BeanPostProcessor bp : getBeanPostProcessors()) {
			if (bp instanceof InstantiationAwareBeanPostProcessor) {
				InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
				//如果后处理器发出停止填充命令则终止后续的执行
				if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
					return;
				}
			}
		}
	}

	PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);

	int resolvedAutowireMode = mbd.getResolvedAutowireMode();
	// 需要自动注入 autowire='byName' or autowire='byType'
	if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
		MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
		// Add property values based on autowire by name if applicable.
		//根据名称字段注入
		if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
			autowireByName(beanName, mbd, bw, newPvs);
		}
		// Add property values based on autowire by type if applicable.
		//根据类型字段注入
		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);
					}
					//对所有需要依赖检查的属性进行后处理
					pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
					if (pvsToUse == null) {
						return;
					}
				}
				pvs = pvsToUse;
			}
		}
	}
	if (needsDepCheck) {
		if (filteredPds == null) {
			//依赖检查,对应 depends-on 属性,3.0已弃用
			filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
		}
		checkDependencies(beanName, mbd, filteredPds, pvs);
	}

	if (pvs != null) {
		//将属性应用到 bean 中
		applyPropertyValues(beanName, mbd, bw, pvs);
	}
}

主要逻辑:
1)InstantiationAwareBeanPostProcessors 处理器的 postProcessAfterInstantiation 方法的应用,可以来控制程序是否继续进行属性填充。
2)根据注入类型(byName/byType),提取依赖的bean,并统一存入 PropertyValues。
3)应用 InstantiationAwareBeanPostProcessors 处理器的 postProcessPropertyValues 方法对属性获取完毕填前对属性的再次处理,典型应用是 RequiredAnnotationBeanPostProcessor 类中对属性的验证。
4)将所有 PropertyValues 中的属性填充值 BeanWrapper中。

8.3.1 autowireByName

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");
			}
		}
	}
}

protected String[] unsatisfiedNonSimpleProperties(AbstractBeanDefinition mbd, BeanWrapper bw) {
	Set<String> result = new TreeSet<>();
	PropertyValues pvs = mbd.getPropertyValues();
	PropertyDescriptor[] pds = bw.getPropertyDescriptors();
	for (PropertyDescriptor pd : pds) {
		// 有 setter 方法 & 可以被依赖 & pvs 不包含 & 不是简单类型(List<简单类型>...)
		if (pd.getWriteMethod() != null && !isExcludedFromDependencyCheck(pd) && !pvs.contains(pd.getName()) &&
				!BeanUtils.isSimpleProperty(pd.getPropertyType())) {
			//存入要解析的列表
			result.add(pd.getName());
		}
	}
	return StringUtils.toStringArray(result);
}

上述代码主要是从 BeanDefinition 的 propertyValues 属性中找出依赖的属性并递归实例化。

8.3.2 autowireByType

protected void autowireByType(
	String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
	// 类型转换器
	TypeConverter converter = getCustomTypeConverter();
	if (converter == null) {
		converter = bw;
	}

	//寻找 bw 中需要依赖注入的属性 - 集合注入的情况 - @Autowired private List<A> aList;
	Set<String> autowiredBeanNames = new LinkedHashSet<>(4);
	//取出不是 bean 类型的属性名
	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 的属性所匹配的值,并把解析到的属性名称
				//存储在 autowiredBeanName 中,当属性存在多个封装 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);
		}
	}
}

根据类型自动匹配的第一步是寻找 bw 中所需要依赖注入的属性,然后遍历这些属性并寻找类型匹配的 bean,其中难点是寻找类型匹配的 bean。同时 Spring 支持集合类型的注入支持,如使用注解方式:

@Autowired 
private List<A> aList;

Spring 会所有与 A 匹配的类型找出并注入到 aList 中,因此在 autowireByType 方法中使用 autowiredBeanNames 变量来存储所有依赖的 bean,如果只是对非集合类的属性注入来说,此属性并无用处。

对于类型的匹配逻辑实现封装到了 resolveDependency 方法中。

// DefaultListableBeanFactory.java
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()) {
		// Optional 类注入的特殊处理
		return createOptionalDependency(descriptor, requestingBeanName);
	}
	else if (ObjectFactory.class == descriptor.getDependencyType() ||
			ObjectProvider.class == descriptor.getDependencyType()) {
		//ObjectFactory 类注入的特殊处理
		return new DependencyObjectProvider(descriptor, requestingBeanName);
	}
	else if (javaxInjectProviderClass == descriptor.getDependencyType()) {
		//javaxInjectProviderClass 类注入的特殊处理
		return new Jsr330Factory().createDependencyProvider(descriptor, requestingBeanName);
	}
	else {
		//通用处理逻辑 默认 SimpleAutowireCandidateResolver
		// ApplicationContext QualifierAnnotationAutowireCandidateResolver
		Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(
				descriptor, requestingBeanName);
		if (result == null) {
			// 真正的解析
			result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
		}
		return result;
	}
}

// doResolveDependency
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) {
			//value不为空,则 TypeConverter 将value 转换成相应的类型后返回
			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;
		}

		//如果不是集合就找出所有满足要求的 bean,进一步进行处理
		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;

		//当出现多了 bean 匹配的情况
		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 进行实例化
			//AbstractBeanFactory#getBean -> AbstractBeanFactory#doGetBean -> DefaultSingletonBeanRegistry#getSingleton
			// -> AbstractAutowireCapableBeanFactory#createBean
			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);
	}
}

集合类型的解析:

// DefaultListableBeanFactory.java
private Object resolveMultipleBeans(DependencyDescriptor descriptor, @Nullable String beanName,
	@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) {

	// 属性的类型
	final 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();
		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());
		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;
	}
	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) {
			Comparator<Object> comparator = adaptDependencyComparator(matchingBeans);
			if (comparator != null) {
				((List<?>) result).sort(comparator);
			}
		}
		return result;
	}
	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;
	}
}

8.3.3 applyPropertyValues

到这里程序完成对所有注入的属性的获取,但获取的属性还是以 PropertyValues 的形式存在,需要通过 applyPropertyValues 方法将其应用到实例化的 bean 中。

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();
			// 进行值的解析 可能会有 SpEL 的解析 BeanDefinitionValueResolver#resolveValueIfNecessary
			// StandardBeanExpressionResolver
			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);
	}
}

8.4 初始化 bean

init-method 属性的作用是在 bean 实例化前调用指定的方法来根据业务进行相应的实例化。bean 经过实例化和属性的填充后会调用用户设定的初始化方法。

//调用初始化方法,如 init-method,实现了 InitializingBean 接口
exposedObject = initializeBean(beanName, exposedObject, mbd);

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,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,BeanFactoryAware, ApplicationContextAware, ResourceLoaderAware, ServletContextAware 等,实现这些接口的 bean 在初始化后,可以获取一些相对应的资源,BeanFactory,ApplicationContext 等。

private void invokeAwareMethods(final String beanName, final 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)处理器应用 BeanPostProcessor 可以让用户去更改或扩展 Spring,在调用用户自定义初始化方法前后分别执行 BeanPostProcessor 的 postProcessorsBeforeInitializationpostProcessorsAfterInitialization方法,让用户可以根据自己的业务需求进行响应的处理。

public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
	throws BeansException {

	Object result = existingBean;
	for (BeanPostProcessor processor : getBeanPostProcessors()) {
		Object current = processor.postProcessBeforeInitialization(result, beanName);
		if (current == null) {
			return result;
		}
		result = current;
	}
	return result;
}

public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
	throws BeansException {

	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 中实现自己的初始化业务逻辑。执行顺序 afterPropertiesSet > init-method。

protected void invokeInitMethods(String beanName, final Object bean, @Nullable RootBeanDefinition mbd)
	throws Throwable {

	//首先检查是否是 InitializingBean 类型
	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 {
			//属性初始化后调用 afterPropertiesSet 方法。
			((InitializingBean) bean).afterPropertiesSet();
		}
	}
	
	// init-method 属性
	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);
		}
	}
}

8.5 注册 DisposableBean

Spring 中不但提供了对于初始化方法的扩展入口,同样提供了销毁方法的扩展入口,对于提供销毁方法的扩展,除配置 destory-method 属性外,还可以注册后处理器 DestructionAwareBeanPostProcessor 来统一处理 bean 的销毁方法。

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 使用 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));
		}
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值