Spring 源码解析(四):bean的加载

 		//spring.xml 文件解析
        BeanFactory factory = new XmlBeanFactory(new ClassPathResource("spring.xml"));
        //bean 的加载
        MyTestBean bean =(MyTestBean) factory.getBean("myTestBean");

对于 bean 的加载,我们先看一下 Spring 代码是如何实现的:
跟踪:factory.getBean("myTestBean"); 进入AbstractBeanFactory

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

进入 bean 的加载入口 doGetBean

	/**
	 * bean 加载入口
	 * beanFactory.getBean("student");
	 * 		1、转换对应 beanName
	 * 		2、尝试从缓存中加载单例
	 * 		3、bean 的实例化
	 * 		4、原型模式的依赖检查
	 * 		5、检查 parentBeanFactory
	 * 		6、将储存 XML 配置文件的 GernericBeanDefinition 转换为 RootBeanDefinition
	 * 		7、寻找依赖
	 * 		8、争对不同的 scope 进行 bean 的创建
	 * 		9、类型转换
	 */
	@SuppressWarnings("unchecked")
	protected <T> T doGetBean(String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly) throws BeansException {
		//提取对应的 beanName
		String beanName = transformedBeanName(name);
		Object bean;

		/**
		 * 检查缓存中或者实例工厂中是否有对应的实例.
		 * 为什么会首先使用这段代码呢?
		 * 因为在创建单例 bean 的时候会存在依赖注入的情况,而在创建依赖的时候为了避免循环依赖.
		 * Spring 创建 bean 的原则是:不等 bean 创建完成,就会将创建 bean 的 ObjectFactory 提早曝光
		 * 也就是将 ObjectFactory 加入到缓存中,一旦下一个 bean 创建时候需要依赖上一个 bean 时,则直接使用 ObjectFactory.
		 */

		// Eagerly check singleton cache for manually registered singletons.
		/**
		 * 单例在 Spring 的同一个容器内只会被创建一次,后续再次获取 bean 直接从单例缓存中获取;
		 * 首先尝试从缓存中加载,然后再次尝试从 singletonFactories 加载;
		 * 因为在创建单例 bean 的时候会存在依赖注入的情况,而在创建依赖的时候为了避免循环依赖,Spring 创建 bean 的原则是:
		 * 不等 bean 创建完成,就会将创建 bean 的 ObjectFactory 提早曝光加入到缓存中,一旦下一个 bean 创建时需要依赖上一个 bean 时,则直接使用 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 + "'");
				}
			}
			//返回对应的实例,有时候存在诸如 BeanFactory 的情况并不是直接返回实例本身,而是返回指定方法返回的实例
			bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
		} else {
			/**
			 * 只有在单例情况下才会解决循环依赖。原型情况下,如果存在 A 中有 B 的属性,B 中有 A 的属性,
			 * 那么当依赖注入的时候,就会产生当 A 还未创建完的时候(因为对于 B 的创建再次返回创建 A )
			 * 造成循环依赖,也就是 isPrototypeCurrentlyInCreation(beanName) 为 true.
			 */

			// Fail if we're already creating this bean instance:
			// We're assumably within a circular reference.
			if (isPrototypeCurrentlyInCreation(beanName)) {
				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 转换为 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();
				//若存在依赖则需要递归实例化依赖的 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.
				//实例化依赖的 bean 后便可以实例化 mbd 本身了
				//singleton 模式的创建
				if (mbd.isSingleton()) {
					/**
					 * 获取单例 bean
					 * 		如果缓存中不存在已经加载的单例 bean ,就需要从头开始 bean 的加载过程
					 * 		而 Spring 中使用 getSingleton 的重载方法实现 bean 的加载过程.
					 */
					sharedInstance = getSingleton(beanName, () -> {
						try {
							/**
							 * 返回处理结果
							 * 		createBean 方法:准备创建 bean.
							 */
							return createBean(beanName, mbd, args);
						} catch (BeansException ex) {
							// Explicitly remove instance from singleton cache: It might have been put there
							// eagerly by the creation process, to allow for circular reference resolution.
							// Also remove any beans that received a temporary reference to the bean.
							destroySingleton(beanName);
							throw ex;
						}
					});
					bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
				}
				//prototype模式的创建(new)
				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);
				}
				//指定的 scope 上实例化 bean
				else {
					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;
			}
		}

		// 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.getQua,lifiedName(requiredType) + "'", ex);
				}
				throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
			}
		}
		return (T) bean;
	}

根据上面的代码,再结合部分注释,对于加载过程的步骤大致如下:

1、转换对应 beanName

为什么要转换 beanName????
其实这里传入的参数 name 可能是 别名,也可能是 FactoryBean,所以需要解析,这里的解析内容包含如下内容:

  1. 去除 FactoryBean 的修饰符,把 name="&aa" 转换为 name="aa"
  2. 取指定 alias 所表示最终的 beanName。如:
   <bean id="myTestBean" class="cn.lemon.demo.bean.MyTestBean"/>
   <alias name="myTestBean" alias="testBean"/>
   <alias name="testBean" alias="hello"/>

MyTestBean bean =(MyTestBean) factory.getBean("hello");
这段代码获取的最终bean

2、尝试从缓存中加载单例

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

3、bean 的实例化

如果从缓存中得到了 bean 的原始状态,则需要对 bean 进行实例化。
缓存中记录的只是最原始的 bean 状态,并不一定是我们想要的 bean ,我们真正需要的是工厂 bean 中定义的 factory-method 方法中返回的 bean,而 getObjectForBeanInstance 就是完成这个工作的。

4、原型模式的依赖检查

只有在单例情况下才会尝试解决循环依赖。
如果 A 中有 B 的属性,B 中有 A 的属性,那么当依赖注入的时候,就会产生当 A 还未创建完的时候因为对于 B 的创建再次返回创建 A ,造成循环依赖,也就是isPrototypeCurrentlyInCreation(beanName)true

5、检查 parentBeanFactory

从代码上看,如果缓存没有数据的话直接转到父类工厂上去加载了,这是为什么呢?????
代码中有这样一个判断条件:
parentBeanFactory != null && !containsBeanDefinition(beanName)
如果parentBeanFactory == null则其他一切都是浮云。
!containsBeanDefinition(beanName)这段代码就比较重要了,它是在检查如果当前加载的 XML 配置文件中不包含 beanName 所对应的配置,就只能到 parentBeanFactory 去尝试下了,然后再去递归的调用 getBean 方法。

6、将储存 XML 配置文件的 GernericBeanDefinition 转换为 RootBeanDefinition

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

7、寻找依赖

在 bean 初始化的过程中很可能用到某些属性,而某些属性可能是动态配置的,并且配置成依赖于其他的 bean ,那么这个时候就有必要先加载依赖的 bean 。
所以在 Spring 的加载顺序中,在初始化某个 bean 的时候首先会初始化这个 bean 所对应的依赖。

8、争对不同的 scope 进行 bean 的创建

在 Spring 中存在着不同的 scope ,其中默认的是 singleton,但是还有些其他的配置(如:prototype、request)。
在这个步骤中,Spring 会根据不同的配置进行不同的初始化策略。

9、类型转换

程序到这里返回 bean 后基本已经结束了,通常对该方法的调用参数 requiredType 是为空的。
但是可能会存在这样一种情况:返回的 bean 是一个 String,但是 requiredType 却传入 Integer 类型,那么这时候本步骤就起作用了,它的功能是将返回的 bean 转换为 requiredType 所指定的类型。当然,String 转换为 Integer 是最简单的转换,在 Spring 中提供了各种各样的转换器,用户可以扩展转换器来满足需求。

一、FactoryBean 的使用

一般情况下,Spring 通过反射机制利用 bean 的 class 属性指定实现类来实例化 bean 。在某些情况下,实例化 bean 比较复杂,如果按照传统方式,则需要在 <bean> 中提供大量的配置信息,配置方式的灵活性是受限的,这时采用编码的方式可能会得到一个简单的方案。Spring 为此提供了 org.springframework.beans.factory.FactoryBean 的工厂类接口,用户可以实现该接口定制实例化 bean 的逻辑。
Spring 自身就提供了 70 多个 FactoryBean 的实现。它们隐藏了实例化一些复杂 bean 的细节,给上层应用带来了便利。
从 Spring 3.0 开始,FactoryBean 支持泛型,也就是 FactoryBean<T>

package org.springframework.beans.factory;

import org.springframework.lang.Nullable;

public interface FactoryBean<T> {
	String OBJECT_TYPE_ATTRIBUTE = "factoryBeanObjectType";

	/**
	 * 返回有 FactoryBean 创建的 Bean 实例
	 * 如果 isSingleton() 返回 true ,则该实例会放到 Spring 容器中单实例缓存池中
	 */
	@Nullable
	T getObject() throws Exception;

	/**
	 * 返回由 FactoryBean 创建的 bean 类型
	 */
	@Nullable
	Class<?> getObjectType();
	
	/**
	 * 返回由 FactoryBean 创建的 bean 实例的作用域是 singleton(单例) 还是 prototype(原型).
	 */
	default boolean isSingleton() {
		return true;
	}
}

那我们先看一个示例,怎么使用 FactoryBean:

Car.java

package cn.lemon.demo.bean;

import lombok.Data;

@Data
public class Car {
    private int maxSpeed;
    private String brand;
    private double price;
}

CarFactoryBean.java

package cn.lemon.demo.bean;

import org.springframework.beans.factory.FactoryBean;

public class CarFactoryBean implements FactoryBean<Car> {
    private String carInfo;

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

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

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

    public String getCarInfo() {
        return carInfo;
    }

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

spring.xml

    <bean id="car" class="cn.lemon.demo.bean.CarFactoryBean">
        <property name="carInfo" value="布加迪,500,12000000"/>
    </bean>

测试:

		BeanFactory factory = new XmlBeanFactory(new ClassPathResource("spring.xml"));
        /**
         * 当调用 getBean("car") 时,Spring 通过反射机制发现 CarFactoryBean 实现了 FactoryBean 接口
         * 这时 Spring 容器就调用 CarFactoryBean 的 getObject 方法返回
         */
        Car car =(Car) factory.getBean("car");
        System.out.println(car.toString());//打印:Car(maxSpeed=500, brand=布加迪, price=1.2E7)

        /**
         * 如果想要获取 CarFactoryBean 的实例,则需要加上 & 前缀
         */
        CarFactoryBean bean = (CarFactoryBean) factory.getBean("&car");
        System.out.println(bean.getCarInfo() + "--" + bean.getObject());//打印:布加迪,500,12000000--Car(maxSpeed=500, brand=布加迪, price=1.2E7)

二、缓存中获取单例 bean

了解完 FactoryBean 的用法后,我们看一下 bean 的加载过程。
单例在 Spring 的同一个容器内只会被创建一次,后续获取 bean 直接从单例缓存中获取,当然这里只是尝试加载。然后再次尝试从 singletonFactories 中加载。
因为创建单例 bean 的时候会存在依赖注入的情况,而在创建依赖的时候避免依赖循环,Spring 创建 bean 的原则是 不等 bean 创建完成就会将创建 bean 的 ObjectFactory 提早曝光加入到缓存中,一旦下一个 bean 创建时需要依赖上一个 bean ,则直接使用 ObjectFactory。
那我们看一下 Spring 是如何从单例缓存中获取 bean 的
Object sharedInstance = getSingleton(beanName);

	@Override
	@Nullable
	public Object getSingleton(String beanName) {
		//参数 true 设置标识允许早期依赖
		return getSingleton(beanName, true);
	}
	/**
	 * 这个方法设计循环依赖的检查,及很多变量的存取
	 * 		1、尝试从 singletonObjects 获取实例;
	 * 		2、如果获取不到,再从 earlySingletonObjects 里面获取
	 * 		3、如果还是获取不到,再尝试从 singletonFactories 里获取 beanName 对应的 ObjectFactory
	 * 		4、然后调用 ObjectFactory 的 getObject 方法来创建 bean ,并放到 earlySingletonObjects 里面去
	 * 		5、从 singletonFactories 里 remove 掉 ObjectFactory.
	 * 	而对于后续内存的操作,都只是为了循环依赖检查的时候使用,也就是在 allowEarlyReference 为 true 的情况下才会使用.
	 */
	@Nullable
	protected Object getSingleton(String beanName, boolean allowEarlyReference) {
		//从 singletonObjects 里面获取 bean
		Object singletonObject = this.singletonObjects.get(beanName);
		/**
		 * isSingletonCurrentlyInCreation(beanName):
		 * 这段代码的意思是:单例 bean 当前是否正在创建中.
		 */
		if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
			//如果为空,则锁定全局变量并进行处理
			synchronized (this.singletonObjects) {
				//尝试从 earlySingletonObjects 里面获取 bean
				singletonObject = this.earlySingletonObjects.get(beanName);
				if (singletonObject == null && allowEarlyReference) {
					//当某些方法需要提前初始化的时候,则会调用 addSingletonFactory 方法将对应的 ObjectFactory 初始化策略存储在 singletonFactories
					ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
					if (singletonFactory != null) {
						//调用预先设定的 getObject() 方法
						singletonObject = singletonFactory.getObject();
						//记录缓存中 earlySingletonObjects 与 singletonFactories 互斥
						this.earlySingletonObjects.put(beanName, singletonObject);
						this.singletonFactories.remove(beanName);
					}
				}
			}
		}
		return singletonObject;
	}

在上面这段代码中,涉及用于存储 bean 的不同 map,简单解释一下:

  • singletonObjects:用于保存 beanName 和 创建 bean 实例 之间的关系。bean name -> bean instance
  • singletonFactories:用于保存 beanName 和 创建 bean 的工厂 之间的关系。bean name -> ObjectFactory
  • earlySingletonObjects:用于保存 beanName 和 创建 bean 实例 之间的关系。与 singletonObjects 的不同之处在于:当一个单例 bean 被放到这里面后,那么当 bean 还在创建过程中,就可以通过 getBean() 获取到了。其目的是用来检测循环引用的
  • registeredSingletons:用来保存当前已注册的 bean。

三、从 bean 的实例中获取对象

getObjectForBeanInstance(sharedInstance, name, beanName, null); 这个方法是一个高频率使用的方法,无论是从缓存中获得 bean 还是根据不同的 scope 策略加载 bean。
总之,我们得到 bean 的实例后要做的第一步就是调用这个方法检测一下正确性(检测当前 bean 是否是 FactoryBean 类型的 bean,如果是就调用该 bean 对应的 FactoryBean 实例中的 getObject 作为返回值)。
无论是从缓存中获取的 bean 还是通过不同的 scope 策略加载的 bean,都是最原始的 bean 状态,并不一定是我们最终相应的 bean。举个例子,假如我们需要对工厂 bean 进行处理,那么这里得到的其实是工厂 bean 的初始状态,但是我们真正需要的是工厂 bean 中定义的 factory-method 方法中返回的 bean ,而 getObjectForBeanInstance 就是完成这个工作的。

	/**
	 * 从 bean 的实例中获取对象
	 * 		1、对 FactoryBean 正确性的验证
	 * 		2、对非 FacotoryBean 类型抛异常
	 * 		3、对 bean 进行转换
	 * 		4、将从 Factory 解析 Bean 的工作委托给 getObjectFromFactoryBean
	 */
	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;
			}
			//beanInstance 不是 FactoryBean 类型,验证不通过
			if (!(beanInstance instanceof FactoryBean)) {
				throw new BeanIsNotAFactoryException(beanName, beanInstance.getClass());
			}
			if (mbd != null) {
				mbd.isFactoryBean = true;
			}
			return beanInstance;
		}

		// Now we have the bean instance, which may be a normal bean or a FactoryBean.
		// If it's a FactoryBean, we use it to create a bean instance, unless the
		// caller actually wants a reference to the factory.
		/**
		 * 现在我们有了bean实例,它可能是普通bean或FactoryBean.
		 * 如果它是FactoryBean,我们使用它来创建一个bean实例,除非调用方实际上想要一个对factory的引用.
		 */
		if (!(beanInstance instanceof FactoryBean)) {
			return beanInstance;
		}

		//加载 FactoryBean
		Object object = null;
		if (mbd != null) {
			mbd.isFactoryBean = true;
		}
		else {
			//尝试从缓存中加载 bean
			object = getCachedObjectForFactoryBean(beanName);
		}
		if (object == null) {
			// Return bean instance from factory.
			//到这里已经明确知道 beanInstance 一定是 FactoryBean 类型
			FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
			// Caches object obtained from FactoryBean if it is a singleton.
			//containsBeanDefinition 检测 beanDefinitionMap 中(也就是在所有已经加载的类中)检测是否定义 beanName.
			if (mbd == null && containsBeanDefinition(beanName)) {
				/**
				 * 将存储 XML 配置文件 GernericBeanDefinition 转换为 RootBeanDefinition
				 * 如果指定 BeanName 是子 Bean 的话,同时会合并父类的相关属性.
				 */
				mbd = getMergedLocalBeanDefinition(beanName);
			}
			//是否是用户定义的而不是应用程序本身定义的
			boolean synthetic = (mbd != null && mbd.isSynthetic());
			/**
			 * 核心代码
			 * 将从 Factory 中解析 bean 的工作委托给 getObjectFromFactoryBean.
			 */
			object = getObjectFromFactoryBean(factory, beanName, !synthetic);
		}
		return object;
	}

跟踪getObjectFromFactoryBean(factory, beanName, !synthetic);

	/**
	 * 从给定的FactoryBean获取要公开的对象
	 * 这个方法只做了一件事:
	 * 		返回的 bean 如果是单例的,那就必须保证全局唯一。
	 * 		同时,也因为是单例的,所以不必重复创建,可以使用缓存提高性能。
	 * 		也就是说,已经加载过就要记录下来以便于下次复用,否则的话就直接获取了
	 */
	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 的后处理器
					object = postProcessObjectFromFactoryBean(object, beanName);
				}
				catch (Throwable ex) {
					throw new BeanCreationException(beanName, "Post-processing of FactoryBean's object failed", ex);
				}
			}
			return object;
		}
	}

跟踪doGetObjectFromFactoryBean(factory, beanName);

	/**
	 * 从给定FactoryBean获取要曝光的对象.
	 */
	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) {
			if (isSingletonCurrentlyInCreation(beanName)) {
				throw new BeanCurrentlyInCreationException(beanName, "FactoryBean which is currently in creation returned null from getObject");
			}
			object = new NullBean();
		}
		return object;
	}

在上面这段代码中,我们终于看到了 object = factory.getObject(); 方法,根据我们讲述的 FactoryBean 的调用方法,如果 bean 声明为 FactoryBean 类型,则当提取 bean 时提取的并不是 FactoryBean,而是 FactoryBean.getObject() 方法返回的 bean ,而 doGetObjectFromFactoryBean 正是实现这个功能的。

四、获取单例

如果缓存中不存在已经加载的单例 bean ,就需要从头开始 bean 的加载过程了。
而 Spring 使用 getSingleton 的重置方法实现 bean 的加载过程。

	/**
	 * 获取单例 bean
	 * 		1、检查缓存是否已经加载过
	 * 		2、若没有加载,则记录 beanName 的正在加载状态
	 * 		3、加载单例前记录加载状态
	 * 		4、通过调用参数传入的 ObjectFactory 的个体 Object 方法实例化 bean
	 * 		5、加载单例后的处理方法调用
	 * 		6、将结果记录至缓存并删除加载 bean 过程中所记录的各种辅助状态
	 * 		7、返回处理结果
	 */
	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 bean 的初始化
			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 + "'");
				}
				//记录加载状态
				beforeSingletonCreation(beanName);
				boolean newSingleton = false;
				boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
				if (recordSuppressedExceptions) {
					this.suppressedExceptions = new LinkedHashSet<>();
				}
				try {
					//初始化 bean
					singletonObject = singletonFactory.getObject();
					newSingleton = true;
				}
				catch (IllegalStateException ex) {
					// Has the singleton object implicitly appeared in the meantime ->
					// if yes, proceed with it since the exception indicates that state.
					singletonObject = this.singletonObjects.get(beanName);
					if (singletonObject == null) {
						throw ex;
					}
				}
				catch (BeanCreationException ex) {
					if (recordSuppressedExceptions) {
						for (Exception suppressedException : this.suppressedExceptions) {
							ex.addRelatedCause(suppressedException);
						}
					}
					throw ex;
				}
				finally {
					if (recordSuppressedExceptions) {
						this.suppressedExceptions = null;
					}
					//加载单例后的处理方法调用
					afterSingletonCreation(beanName);
				}
				if (newSingleton) {
					//加入缓存
					addSingleton(beanName, singletonObject);
				}
			}
			return singletonObject;
		}
	}

步骤3中,加载单例前记录加载状态:beforeSingletonCreation(beanName);

	/**
	 * 创建单例之前的回调
	 * 		我们看到这个方法里面没有任何逻辑,其实这个方法做了一个很重要的操作:记录加载状态,
	 * 		也就是通过 this.singletonsCurrentlyInCreation.add(beanName) 将当前正在创建的 bean 记录
	 * 		在缓存中,这样便可以对循环依赖进行检测
	 */
	protected void beforeSingletonCreation(String beanName) {
		if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) {
			throw new BeanCurrentlyInCreationException(beanName);
		}
	}

步骤5中,加载单例后的处理方法调用 afterSingletonCreation(beanName);

	/**
	 * 创建单例之后的回调
	 * 		我们看到这个方法里面没有任何逻辑,其实这个方法做了一个很重要的操作:移除缓存中对该 bean 的正在加载状态的记录,
	 * 		也就是通过 this.singletonsCurrentlyInCreation.remove(beanName) 移除缓存中对该 bean 的正在加载状态的记录
	 */
	protected void afterSingletonCreation(String beanName) {
		if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.remove(beanName)) {
			throw new IllegalStateException("Singleton '" + beanName + "' isn't currently in creation");
		}
	}

步骤6中,将结果记录至缓存并删除加载 bean 过程中所记录的各种辅助状态 addSingleton(beanName, singletonObject);

	protected void addSingleton(String beanName, Object singletonObject) {
		synchronized (this.singletonObjects) {
			this.singletonObjects.put(beanName, singletonObject);
			this.singletonFactories.remove(beanName);
			this.earlySingletonObjects.remove(beanName);
			this.registeredSingletons.add(beanName);
		}
	}

五、准备创建 bean

我们再看一下获取单例 bean 的代码:

					sharedInstance = getSingleton(beanName, () -> {
						try {
							return createBean(beanName, mbd, args);
						} catch (BeansException ex) {
							destroySingleton(beanName);
							throw ex;
						}
					});

从上面的代码可以看出创建 bean 的核心代码是:createBean(beanName, mbd, args);

	/**
	 * 准备创建 Bean
	 * 		1、根据设置的 class 属性或者根据 className 来解析 Class
	 * 		2、对 override 属性进行标记及验证
	 * 		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 进行标记及验证
			 * 		Spring 中没有 override-method 这样的配置,但是在 Spring 配置中存在 lookup-method 和 replace-method,
			 * 		而这两个配置的加载就是将配置统一存放在 BeanDefinition 中的 methodOverrides 属性里面。
			 * 		而 prepareMethodOverrides() 这个方法就是争对这两个配置的.
			 */
			mbdToUse.prepareMethodOverrides();
		}
		catch (BeanDefinitionValidationException ex) {
			throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(), beanName, "Validation of method overrides failed", ex);
		}

		try {
			// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
			/**
			 * 实例化的前置处理
			 * 让 BeanPostProcessors 有机会返回代理,而不是目标bean实例.
			 */
			Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
			/**
			 * 下面这个短路判断很重要
			 * 		我们熟知的 AOP 就是基于这里的判断的.
			 */
			if (bean != null) {
				return bean;
			}
		}
		catch (Throwable ex) {
			throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "BeanPostProcessor before instantiation of bean failed", ex);
		}

		try {
			/**
			 * 执行创建 bean
			 */
			Object beanInstance = doCreateBean(beanName, mbdToUse, args);
			if (logger.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、处理 override 属性

根据上面代码的注释,处理 override 属性是在 prepareMethodOverrides(); 方法中进行的

	public void prepareMethodOverrides() throws BeanDefinitionValidationException {
		// Check that lookup methods exist and determine their overloaded status.
		if (hasMethodOverrides()) {
			getMethodOverrides().getOverrides().forEach(this::prepareMethodOverride);
		}
	}

跟踪 prepareMethodOverride

	/**
	 * 验证并准备给定的 method override。
	 * 检查是否存在具有指定名称的方法,如果未找到,则将其标记为未重载.
	 */
	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);
		}
	}

在 Spring 配置中存在 lookup-method 和 replace-method 两个配置功能,这两个配置的加载其实是将配置统一存放在 BeanDefinition 的 methodOverrides 属性里。
这两个功能的实现原理是:在 bean 实例化的时候如果检测到 methodOverrides 属性,会动态地为当前 bean 生成代理并使用对应的拦截器为 bean 做增强处理。

对于方法匹配来讲,如果一个类中存在若干个重载方法,那么在函数调用及增强的时候还需要根据参数类型进行匹配,来最终确认调用那个函数。但是,Spring 将一部分匹配工作在这里完成了,如果当前类中的方法只有一个,那么就设置重载该方法没有重载,这样在后续调用的时候便可以直接使用找到的方法,而不需要进行方法的匹配验证了,而且还可以提前对方法存在性进行验证。

2、实例化的前置处理

Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
对于这句代码,其实是对 BeanDefinition 中的属性做一些前置处理

	/**
	 * 在实例化后处理器之前应用,解决是否存在
	 * 在实例化指定bean的快捷方式之前
	 */
	@Nullable
	protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
		Object bean = null;
		//如果尚未被解析
		if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
			// Make sure bean class is actually resolved at this point.
			if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
				Class<?> targetType = determineTargetType(beanName, mbd);
				if (targetType != null) {
					//对后处理器中的所有 InstantiationAwareBeanPostProcessor 类型的后处理器进行 postProcessBeforeInstantiation 方法的调用
					bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
					if (bean != null) {
						//对后处理器中的所有 BeanPostProcessor 类型的后处理器进行 postProcessAfterInstantiation 方法的调用
						bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
					}
				}
			}
			mbd.beforeInstantiationResolved = (bean != null);
		}
		return bean;
	}

实例化前的后处理器应用 applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);

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

bean 的实例化前调用,也就是将 AbstractBeanDefinition 转换为 BeanWrapper 前的处理,给子类一个修改 BeanDefinition 的机会,也就是说当程序经过这个方法后,bean 可能已经不是我们认为的 bean 了,而是或许成为了一个经过处理的代理 bean ,可能是通过 cglib 生成的,也可能是通过其他技术生成的。

实例化后的后处理器应用 applyBeanPostProcessorsAfterInitialization(bean, beanName);

	@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 中,因为如果返回的 bean 不为空,那么便不会再次经历普通 bean 的创建过程,所以只能在这里应用后处理器的 postProcessAfterInitialization 方法。

六、循环依赖

实例化 bean 是一个非常复杂的过程,其中对循环依赖的解决是比较难以理解的。

1、什么是循环依赖

循环依赖就是循环引用,就是多个 bean 之间相互持有对方,则它们最终反映一个环。
此处不是循环调用,循环调用是方法之间的环调用。
环调用是无法解决的,除非有终结条件,否则就是死循环,最终导致内存溢出。
在这里插入图片描述

2、Spring 如何解决循环依赖

Spring 容器循环依赖有两种:

  1. 构造器循环依赖
  2. setter 循环依赖

那么,Spring 是如何解决循环依赖的呢?????
我们先定义循环引用类:TestA.java、TestB.java、TestC.java

package cn.lemon.demo.bean;

import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
public class TestA {
    private TestB testB;

    public void a(){
        testB.b();
    }
}
package cn.lemon.demo.bean;

import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
public class TestB {
    private TestC testC;

    public void b(){
        testC.c();
    }
}
package cn.lemon.demo.bean;

import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
public class TestC {
    private TestA testA;

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

2.1、构造器循环依赖

我们通过一个直观的用例来进行分析:
1、在上面三个类中各加上 @AllArgsConstructor 注解,创建构造器(带参数的构造方法)
2、创建配置文件 spring.xml

    <bean id="testA" class="cn.lemon.demo.bean.TestA">
        <constructor-arg index="0" ref="testB"/>
    </bean>
    <bean id="testB" class="cn.lemon.demo.bean.TestB">
        <constructor-arg index="0" ref="testC"/>
    </bean>
    <bean id="testC" class="cn.lemon.demo.bean.TestC">
        <constructor-arg index="0" ref="testA"/>
    </bean>

3、创建测试用例

    @Test(expected = BeanCurrentlyInCreationException.class)
    public void testCircleByConstructor() throws Throwable{
        try{
            ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
        }catch (Throwable e){
            System.out.println("异常了... ...");
            //因为要在创建 testC 时抛出
            Throwable throwable = e.getCause().getCause().getCause();
            throw throwable;
        }
    }

运行发现,通过构造器注入构成的循环依赖,此依赖无法解决,只能抛出org.springframework.beans.factory.BeanCurrentlyInCreationException

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

Spring 容器将每一个正在创建的 bean 标识符放在一个 “当前创建 bean 池” 中,bean 标识符在创建过程中将一直保持在这个池中,因此如果在创建 bean 过程中发现自己已经在 “当前创建 bean 池” 里时,将抛出 BeanCurrentlyInCreationException 异常表示循环依赖,而对于创建完毕的 bean 将从 “当前创建 bean 池” 里清除掉。

针对上面的代码分析如下:

  1. Spring 容器创建 “testA” bean,首先去 “当前创建 bean 池” 中查找当前 bean 是否正在被创建,如果没发现,则继续准备其需要的构造器参数 “testB”,并将 “testA” 标识符放到 “当前创建 bean 池”。
  2. Spring 容器创建 “testB” bean,首先去 “当前创建 bean 池” 中查找当前 bean 是否正在被创建,如果没发现,则继续准备其需要的构造器参数 “testC”,并将 “testB” 标识符放到 “当前创建 bean 池”。
  3. Spring 容器创建 “testC” bean,首先去 “当前创建 bean 池” 中查找当前 bean 是否正在被创建,如果没发现,则继续准备其需要的构造器参数 “testA”,并将 “testC” 标识符放到 “当前创建 bean 池”。
  4. 到此为止,Spring 容器要去创建 “testA” bean ,发现 “testA” bean 标识符在 “当前创建 bean 池” 中,因为表示循环依赖,抛出 BeanCurrentlyInCreationException

2.2、setter 循环依赖

我们通过一个直观的用例来进行分析:
1、在上面三个类中各加上 @NoArgsConstructor 注解,提供一个默认的无参构造器,(在没有其他带参构造函数的情况下,可省略)
2、创建配置文件 spring.xml

    <bean id="testA" class="cn.lemon.demo.bean.TestA">
        <property name="testB" ref="testB"/>
    </bean>
    <bean id="testB" class="cn.lemon.demo.bean.TestB">
        <property name="testC" ref="testC"/>
    </bean>
    <bean id="testC" class="cn.lemon.demo.bean.TestC">
        <property name="testA" ref="testA"/>
    </bean>

3、创建测试用例

        ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
        System.out.println(context.getBean("testA"));//输出:cn.lemon.demo.bean.TestA@dbd940d

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

		//为避免后期循环依赖,可以在 bean 初始化完成前 将创建的 ObjectFactory 加入工厂
		addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));

具体步骤如下:

  1. Spring 容器创建单例 “testA” bean,首先通过无参构造器创建 bean ,并暴露一个 “ObjectFactory”,用于返回一个提前暴露一个创建中的 bean,并将 “testA” 标识符放到 “当前创建 bean 池” ,然后进行 setter 注入 “testB”。
  2. Spring 容器创建单例 “testB” bean,首先通过无参构造器创建 bean,并暴露一个 “ObjectFactory”,用于返回一个提前暴露一个创建中的 bean,并将 “testB” 标识符放到 “当前创建 bean 池” ,然后进行 setter 注入 “testC”。
  3. Spring 容器创建单例 “testC” bean,首先通过无参构造器创建 bean,并暴露一个 “ObjectFactory”,用户返回一个提前暴露一个创建中的 bean,并将 “testC” 标识符放到 “当前创建 bean 池” ,然后进行 setter 注入 “testA” 。进行注入 “testA” 时由于提前暴露了 “ObjectFactory” 工厂,从而使它返回提前暴露一个创建中的 bean。
  4. 最后再依赖注入 “testB” 和 “testA”,完成 setter 注入。

2.3、prototype 范围的依赖处理

我们通过一个直观的用例来进行分析:
1、在上面三个类中各加上 @NoArgsConstructor 注解,提供一个默认的无参构造器,(在没有其他带参构造函数的情况下,可省略)
2、创建配置文件 spring.xml。(相对于 setter 依赖注入,bean 的作用域 为 prototype)

    <bean id="testA" class="cn.lemon.demo.bean.TestA" scope="prototype">
        <property name="testB" ref="testB"/>
    </bean>
    <bean id="testB" class="cn.lemon.demo.bean.TestB" scope="prototype">
        <property name="testC" ref="testC"/>
    </bean>
    <bean id="testC" class="cn.lemon.demo.bean.TestC" scope="prototype">
        <property name="testA" ref="testA"/>
    </bean>

3、创建测试用例

        ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
        System.out.println(context.getBean("testA"));//抛出:BeanCurrentlyInCreationException

对于 prototype 作用域的 bean ,Spring 容器无法完成依赖注入,因为 Spring 容器不进行缓存 prototype 作用域的 bean ,因此无法提前暴露一个创建中的 bean 。
对于 singleton 作用域的 bean ,(也就是上面 2.2小节的示例),可以通过 setAllowCircularReferences(false); 来禁用循环依赖。
为了更好的理解 Spring 循环依赖,可以参考:https://www.iflym.com/index.php/code/201208280001.html

七、创建 bean

我们继续第五节的内容,对于常规 bean 的创建是在 Object beanInstance = doCreateBean(beanName, mbdToUse, args); 这句代码中完成的。

	/**
	 * 创建指定的 bean ,此时已经进行了创建前处理,例如检查{@code postProcessBeforeInstantiation}回调
	 * 		1、如果是单例,需要首先清除缓存
	 * 		2、实例化 bean ,将 BeanDefinition 转换为 BeanWrapper
	 * 		3、MergedBeanDefinitionPostProcessor 的应用。(bean 合并后的处理,Autowired 注解正是通过此方法实现诸如类型的预解析)
	 * 		4、依赖处理
	 * 			在 Spring 中,会有循环依赖的情况,例如:当 A 中含有 B 的属性,而 B 中又含有 A 的属性。
	 * 			如果 A 和 B 都是单例的,那么 Spring 的处理方式就是:
	 * 			当创建 B 的时候,涉及自动注入 A 的步骤时,并不是直接去创建,而是通过放入缓存中的 ObjectFactory 来创建实例
	 * 		5、属性填充,将所有属性填充至 bean 实例中
	 * 		6、循环依赖检查。
	 * 			Spring 中解决循环依赖只对单例有效,而对于 prototype 的 bean Spring 做的就是抛异常
	 * 		7、注册 DisposableBean。
	 * 			如果配置了 destroy-method ,这里需要注册,以便于在销毁的时候调用
	 * 		8、完成创建并返回
	 */
	protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException {
		// Instantiate the bean.
		BeanWrapper instanceWrapper = null;
		if (mbd.isSingleton()) {
			//如果是单例,先清除缓存
			instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
		}
		if (instanceWrapper == null) {
			/**
			 * 实例化 bean,将 BeanDefinition 转换为 BeanWrapper
			 * 根据指定的 bean 使用对应的策略,创建新的实例,如:工厂方法、构造函数自动注入、简单初始化
			 * 		1、如果存在工厂方法则使用工厂方法进行初始化
			 * 		2、一个类有多个构造函数,每个构造函数都有不同的参数,所以需要根据参数锁定构造函数并进行初始化
			 * 		3、如果既不存在工厂方法也不存在带有参数的构造函数,则使用默认的构造函数进行 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 {
					/**
					 * 应用 MergedBeanDefinitionPostProcessor
					 * bean 合并后的处理,Autowired 注解正是通过此方法实现诸如类型的预解析.
					 */
					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 加入工厂
			addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
		}

		// Initialize the bean instance.
		Object exposedObject = bean;
		try {
			/**
			 * 对 bean 进行填充,将各个属性值注入。
			 * 其中,可能存在依赖于其他 bean 的属性则会递归初始依赖 bean.
			 */
			populateBean(beanName, mbd, instanceWrapper);
			//调用初始化方法,比如 init-method
			exposedObject = initializeBean(beanName, exposedObject, mbd);
		}
		catch (Throwable ex) {
			if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
				throw (BeanCreationException) ex;
			}
			else {
				throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
			}
		}

		if (earlySingletonExposure) {
			Object earlySingletonReference = getSingleton(beanName, false);
			//earlySingletonReference 只有在检测到有循环依赖的情况下才不为空
			if (earlySingletonReference != null) {
				//如果 exposedObject 没有在初始化方法中被改变,也就是没有被增强
				if (exposedObject == bean) {
					exposedObject = earlySingletonReference;
				}
				else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
					String[] dependentBeans = getDependentBeans(beanName);
					Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
					for (String dependentBean : dependentBeans) {
						//检测依赖
						if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
							actualDependentBeans.add(dependentBean);
						}
					}
					/**
					 * 因为 bean 创建后其所依赖的 bean 一定是已经创建的
					 * actualDependentBeans 不为空,则表示:当前 bean 创建后其依赖的 bean 却没有创建完,也就是存在循环依赖.
					 */
					if (!actualDependentBeans.isEmpty()) {
						throw new BeanCurrentlyInCreationException(beanName, "Bean with name '" + beanName + "' has been injected into other beans [" +
								StringUtils.collectionToCommaDelimitedString(actualDependentBeans) + "] in its raw version as part of a circular reference, but has eventually been " +
								"wrapped. This means that said other beans do not use the final version of the " + "bean. This is often the result of over-eager type matching - consider using " +
								"'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.");
					}
				}
			}
		}

		// Register bean as disposable.
		try {
			//根据 scope 注册 bean
			registerDisposableBeanIfNecessary(beanName, bean, mbd);
		}
		catch (BeanDefinitionValidationException ex) {
			throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
		}
		return exposedObject;
	}

1、创建 bean 的实例

在上面的代码中,创建 bean 实例的代码是: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());
		}

		Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
		if (instanceSupplier != null) {
			return obtainFromSupplier(instanceSupplier, beanName);
		}

		/**
		 * 如果工厂方法不为空,则使用工厂方法初始化策略
		 * 如果在 RootBeanDefinition 中存在 factoryMethodName 属性,或者说在配置文件中配置了 factory-method,
		 * 那么 Spring 会尝试使用 instantiateUsingFactoryMethod(beanName, mbd, args); 方法根据 RootBeanDefinition 中的配置生成 bean 的实例.
		 */
		if (mbd.getFactoryMethodName() != null) {
			return instantiateUsingFactoryMethod(beanName, mbd, args);
		}

		// Shortcut when re-creating the same bean...
		boolean resolved = false;
		boolean autowireNecessary = false;
		if (args == null) {
			synchronized (mbd.constructorArgumentLock) {
				/**
				 * 一个类有多个构造函数,每个构造函数都有不同的参数,
				 * 所以调用前需要先根据参数锁定构造函数或对应的工厂方法.
				 */
				if (mbd.resolvedConstructorOrFactoryMethod != null) {
					resolved = true;
					autowireNecessary = mbd.constructorArgumentsResolved;
				}
			}
		}
		//如果已经解析过,则使用已经解析好的构造函数方法不需要再次锁定.
		if (resolved) {
			if (autowireNecessary) {
				//构造函数自动注入
				return autowireConstructor(beanName, mbd, null, null);
			}
			else {
				//使用默认的构造函数构造
				return instantiateBean(beanName, mbd);
			}
		}

		// Candidate constructors for autowiring?
		/**
		 * 需要根据参数解析构造函数,并进行构造函数的实例化
		 * 因为一个 bean 对应的类中可能会有多个构造函数,而每个构造函数的参数不同,Spring 再根据参数及类型去判断最终会使用那个构造函数进行实例化。
		 * 但是判断过程是一个比较消耗性能的步骤,所以采用缓存机制。
		 * 如果已经解析过,直接从 RootBeanDefinition 中的属性 resolvedConstructorOrFactoryMethod 缓存的值去取,
		 * 否则需要再次解析,并将解析的结果添加至 RootBeanDefinition 中的属性 resolvedConstructorOrFactoryMethod 中.
		 */
		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.1、autowireConstructor

对于 实例的创建,Spring 分成了两种情况:

  • 通用实例化
  • 带有参数的实例化
	/**
	 * Spring 实例的创建分两种情况:
	 * 		1、通用的实例化
	 * 		2、带参数的实例化(过程复杂,因为存在着不确定性,所以在判断对应参数上做了大量工作).
	 *
	 * 构造函数自动注入:
	 * 		1、构造函数参数的确定
	 * 			1.1、根据 explicitArgs 参数判断
	 * 			1.2、缓存中获取
	 * 			1.3、配置文件获取
	 * 		2、构造函数的确定
	 * 		3、根据确定的构造函数转换对应的参数类型
	 * 		4、构造函数不确定性的验证
	 * 		5、根据实例化策略以及得到的构造函数 及 构造函数参数实例化 Bean
	 */
	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 {
			/**
			 * 如果传入的 explicitArgs 参数不为空,那便可以直接确定参数,因为 explicitArgs 参数是在调用 Bean 的时候用户指定的,在 BeanFactory 类中存在这样的方法:
			 * Object getBean(String name,Object... args) throws BeanException;
			 * 在获取 bean 的时候,用户不但可以指定 bean 的名称还可以指定 bean 所对应类的构造函数或者工厂方法的方法参数,主要用于静态工厂方法的调用,而这里是需要给定
			 * 完全匹配的参数的。所以如果传入的 explicitArgs 不为空,则可以确定构造函数参数就是它.
			 */
			//如果在 getBean 方法时候没有指定,则尝试从配置文件中解析
			Object[] argsToResolve = null;
			//尝试从缓存中获取
			synchronized (mbd.constructorArgumentLock) {
				constructorToUse = (Constructor<?>) mbd.resolvedConstructorOrFactoryMethod;
				if (constructorToUse != null && mbd.constructorArgumentsResolved) {
					// Found a cached constructor...
					/**
					 * 从缓存中取
					 * 除此之外,构造函数参数记录在缓存中,那便可以拿来直接用,这里要提到的是,在缓存中缓存的可能是参数的最终类型也可能是参数的初始类型。
					 * 例如:构造函数参数要求的是 int 类型,但原始的参数值可能是 String 类型的 "1",那么即使在缓存中得到了参数,也需要经过类型转换器的过滤
					 * 确保参数类型与对应的构造函数参数类型完全对应.
					 */
					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.
			boolean autowiring = (chosenCtors != null || mbd.getResolvedAutowireMode() == AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR);
			ConstructorArgumentValues resolvedValues = null;

			int minNrOfArgs;
			if (explicitArgs != null) {
				minNrOfArgs = explicitArgs.length;
			}
			else {
				/**
				 * 提前配置文件中配置的构造函数参数,也就是从配置文件中获取
				 * 如果不能根据传入的参数 explicitArgs 确定构造函数的参数也无法从缓存中得到相关信息,那么 Spring 就从配置文件中获取
				 * Spring 中配置文件中的信息经过转换都会通过 BeanDefinition 实例承载,可以通过调用 getConstructorArgumentValues 来获取配置的
				 * 构造函数信息。有了配置中的信息便可以获取对应的参数值信息了,获取参数值的信息包括直接指定值,
				 * 如:直接指定构造函数中某个值为原始类型 String 类型,或者是一个对其他 bean 的引用,而这一处理委托给了 resolveConstructorArguments 方法
				 * 并返回能解析到的参数的个数.
				 */
				ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues();
				//用于承载解析后的构造函数参数的值
				resolvedValues = new ConstructorArgumentValues();
				//能解析到的参数个数
				minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);
			}

			/**
			 * 构造函数的确定
			 * 当确定了构造函数的参数后,接下来就是根据构造函数参数在所有构造函数中锁定对应的构造函数,而匹配的方法就是根据参数的个数匹配,
			 * 在匹配之前需要先对构造函数排序(public 构造函数优先参数数量降序、非 public 构造函数参数数量降序),这样可以在遍历的情况下迅速判断
			 * 排在后面的构造函数参数个数是否符合条件。
			 * 由于配置文件中并不是唯一限制使用参数位置索引的方式去创建,同样还支持指定参数名称进行设定参数值的情况,
			 * 如:constructor-arg name="aa",那么这种情况就需要首先确定构造函数中的参数名称
			 * 获取参数名称有两种方式:
			 * 		1、通过注解的方式直接获取
			 * 		2、使用 Spring 中提供的工具类 ParameterNameDiscoverer 来获取
			 *
			 * 构造函数、参数名称、参数类型、参数值都确定后就可以锁定构造函数以及转换对应的参数类型了.
			 */
			//排序给定的构造函数,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) {
					// Already found greedy constructor that can be satisfied ->
					// do not look any further, there are only less greedy constructors left.
					/**
					 * 如果已经找到选用的构造函数或者需要的参数个数 小于 当前的构造函数参数个数,则终止
					 * 因为已经按照参数个数降序排序
					 */
					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);
							}
						}
						//根据名称和数据类型创建参数持有者
						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));
				// 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");
		bw.setBeanInstance(instantiate(beanName, mbd, constructorToUse, argsToUse));
		return bw;
	}

1.2、instantiateBean

不带参数的构造函数的实例化instantiateBean(beanName, mbd);

	/**
	 * 不带参数的构造函数 的实例化过程.
	 * 		直接调用实例化策略进行实例化 instantiate()
	 */
	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);
		}
	}

1.3、实例化策略

实例化策略getInstantiationStrategy().instantiate(mbd, beanName, this);

	/**
	 * 实例化策略
	 */
	@Override
	public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
		// Don't override the class with CGLIB if no overrides.
		/**
		 * 如果没有重写,不要用 CGLIB 重写类
		 *
		 * 如果有需要覆盖或者动态替换的方法 则当然需要使用 cglib 进行动态代理,因为可以在创建代理的同时
		 * 将动态方法织入类中。
		 * 但是如果没有需要动态改变得方法,为了方便直接反射就可以了.
		 */
		if (!bd.hasMethodOverrides()) {
			Constructor<?> constructorToUse;
			synchronized (bd.constructorArgumentLock) {
				constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;
				if (constructorToUse == null) {
					final Class<?> clazz = bd.getBeanClass();
					if (clazz.isInterface()) {
						throw new BeanInstantiationException(clazz, "Specified class is an interface");
					}
					try {
						if (System.getSecurityManager() != null) {
							constructorToUse = AccessController.doPrivileged((PrivilegedExceptionAction<Constructor<?>>) clazz::getDeclaredConstructor);
						}
						else {
							constructorToUse = clazz.getDeclaredConstructor();
						}
						bd.resolvedConstructorOrFactoryMethod = constructorToUse;
					}
					catch (Throwable ex) {
						throw new BeanInstantiationException(clazz, "No default constructor found", ex);
					}
				}
			}
			return BeanUtils.instantiateClass(constructorToUse);
		}
		else {
			// Must generate CGLIB subclass.
			return instantiateWithMethodInjection(bd, beanName, owner);
		}
	}

在上面的代码中,首先判断 RootBeanDefinition.hasMethodOverrides() == false,也就是用户没有使用 replace-method 或者 lookup-method 的配置,那么直接使用反射的方式,简单快捷。如果使用了这两个特性,在直接使用反射的方式创建实例就不妥了,因为需要将这两个配置提供的功能切入进去,所以就必须要使用动态代理的方式将包含两个特性所对应的逻辑的拦截增强器设置进去,这样才可以保证在调用方法的时候会被相应的拦截器增强,返回值为包含拦截器的代理实例。

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 加入工厂
			addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
		}

这段代码仅从此函数中去理解也很难弄懂其中的含义,我们要从全局的角度去思考 Spring 的依赖解决办法。
earlySingletonExposure:提早曝光的单例,那我们看一下有那些条件影响这个值。

  1. mbd.isSingleton():表示 RootBeanDefinition 是否是单例
  2. this.allowCircularReferences 表示是否允许循环依赖,这个配置是在 AbstractRefreshableApplicationContext 中提供了函数设置的,可以通过硬编码的方式进行设置或者可以通过自定义命名空间进行设置,硬编码方式如下:
       ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
       context.setAllowBeanDefinitionOverriding(false);
  1. isSingletonCurrentlyInCreation(beanName):表示该 bean 是否在创建中。在Spring 中,会有个专门的属性默认为 DefaultSingletonBeanRegistry 的 singletonCurrentlyInCreation 来记录 bean 的加载状态,在 bean 开始创建前会将 beanName 记录在属性中,在 bean 创建结束后从属性中移除。以 singleton 为例:在 DefaultSingletonBeanRegistry 类中 getSingleton 方法中的 beforeSingletonCreation(beanName);afterSingletonCreation(beanName);,在这两句代码中分别来进行状态的记录与移除。

当上面这三个条件(是单例、允许循环依赖、对应的 bean 正在创建中)都满足时,才会执行 addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));,那么加SingletonFactory 的作用是什么呢????
我们以简单的 A、B 循环为例,类 A 中含有类 B 的属性,类 B 中含有类 A 的属性,那么初始化类 A 的过程如下图:

在这里插入图片描述
从上图中我们可以看到,在创建 A 的时候首先会记录 A 所对应的 beanName,并将 beanA 的创建工厂加入缓存,而再对 A 的属性填充的时候(调用 populateBean 方法)再一次对 B 进行递归创建,同样的,因为在 B 中有 A 的属性,因此在实例化 B 的 populateBean 方法时,有会再次初始化 A ,也就是图形的最后,调用 getBean(A)。

关键在调用 getBean(A) 这个函数中,并不是直接去实例化 A ,而是先去检测缓存中是否有已经创建好的对应的 bean,或者是已经创建好的 ObjectFactory,而对于上面的逻辑,此时已经创建好 A 的 ObjectFactory,所以不必再向后执行,而是直接调用 ObjectFactory 去创建 A,这里关键是 ObjectFactory 的实现。

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

跟踪 getEarlyBeanReference

	/**
	 * 获取提前访问指定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;
	}

根据上面这段代码,基本上可以理清 Spring 处理循环依赖的解决办法:
在 B 中创建依赖 A 时,通过 ObjectFactory 提供的实例化方法来中断 A 中属性的填充,使 B 中持有的 A 仅仅是刚初始化并没有填充任何属性的 A ,而这正初始化 A 的步骤还是在最开始创建 A 的时候进行的,但是因为 A 与 B 中的 A 所表示的属性地址是一样的,所以在 A 中创建好的属性自然可以通过 B 中的 A 获取,这样就解决了循环依赖的问题。

3、属性注入

在了解循环依赖后,对于属性填充 populateBean(beanName, mbd, instanceWrapper); 这个函数,Spring 是如何实现填充的呢????

	/**
	 * 用bean定义中的属性值填充给定BeanRapper中的bean实例。
	 * 		1、InstantiationAwareBeanPostProcessor 处理器的 postProcessAfterInstantiation 函数的应用,此函数可以控制程序是否继续进行属性填充
	 * 		2、根据注入类型(autowireByName、autowireByType)提取依赖 Bean,并统一存入到 PropertyValues 中
	 * 		3、应用 InstantiationAwareBeanPostProcessor 处理器的 postProcessPropertyValues 方法,对属性获取完毕填充前对属性再次处理,
	 * 			典型应用是 RequiredAnnotationBeanPostProcessor 类中对属性的验证
	 * 		4、将所有 PropertyValues 中的属性填充至 BeanWrapper 中
	 */
	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();

		/**
		 * 根据注入类型(autowireByName、autowireByType)提取依赖 Bean,并统一存入到 PropertyValues 中.
		 */
		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();
			}
			/**
			 * 应用 InstantiationAwareBeanPostProcessor 处理器的 postProcessPropertyValues 方法,
			 * 对属性获取完毕前填充前 对属性再次处理.
			 */
			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) {
				filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
			}
			//依赖检查,对应 depend-on 属性,3.0已经弃用此属性
			checkDependencies(beanName, mbd, filteredPds, pvs);
		}

		if (pvs != null) {
			/**
			 * 将属性应用到 bean 中
			 * 将所有 PropertyValues 中的属性填充至 BeanWrapper.
			 */
			applyPropertyValues(beanName, mbd, bw, pvs);
		}
	}

3.1、autowireByName

根据注入类型 autowireByName 提取依赖的 bean

	/**
	 * 提取依赖 Bean,存入到 PropertyValues 中
	 */
	protected void autowireByName(String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
		//寻找 BeanWrapper 需要依赖注入的属性
		String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
		/**
		 * 在传入的参数 pvs 中找出已经加载的 bean,并递归实例化,进而加入到 pvs 中.
		 */
		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");
				}
			}
		}
	}

3.2、autowireByType

根据注入类型 autowireByType 提取依赖的 bean

	/**
	 * 提取依赖 Bean,存入到 PropertyValues 中.
	 * 		1、寻找 bw 中需要依赖注入的属性
	 * 		2、遍历这些属性并寻找类型匹配的 bean
	 * 		最为复杂的就是寻找类型匹配的 bean,实现逻辑封装在了 resolveDependency 方法中
	 */
	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);
		//寻找 BeanWrapper 中需要依赖注入的属性
		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<> 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);
			}
		}
	}

寻找类型匹配的 bean,跟踪 resolveDependency(desc, beanName, autowiredBeanNames, converter);

	/**
	 * 解析指定 beanName 的属性所匹配的值,并把解析到的属性名称存储在 autowiredBeanNames 中
	 */
	@Override
	@Nullable
	public Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName,
			@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {

		descriptor.initParameterNameDiscovery(getParameterNameDiscoverer());
		if (Optional.class == descriptor.getDependencyType()) {
			return createOptionalDependency(descriptor, requestingBeanName);
		}
		//ObjectFactory 类注入的特殊处理
		else if (ObjectFactory.class == descriptor.getDependencyType() || ObjectProvider.class == descriptor.getDependencyType()) {
			return new DependencyObjectProvider(descriptor, requestingBeanName);
		}
		//javaxInjectProviderClass 类注入的特殊处理
		else if (javaxInjectProviderClass == descriptor.getDependencyType()) {
			return new Jsr330Factory().createDependencyProvider(descriptor, requestingBeanName);
		}
		else {
			Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(descriptor, requestingBeanName);
			if (result == null) {
				//通用处理逻辑
				result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
			}
			return result;
		}
	}

跟踪通用处理逻辑 doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);

	@Nullable
	public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName,
			@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {

		InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor);
		try {
			Object shortcut = descriptor.resolveShortcut(this);
			if (shortcut != null) {
				return shortcut;
			}

			Class<?> type = descriptor.getDependencyType();
			//用于支持 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()));
				}
			}

			/**
			 * 解析多个 beans.
			 */
				Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
			if (multipleBeans != null) {
				return multipleBeans;
			}

			/**
			 * 根据属性类型找到 beanFactory 中所有类型的匹配 bean
			 * 返回值的构成为:
			 * 		key = 匹配的 beanName
			 * 		value = beanName 对应的实例化后的 bean (通过 getBean(beanName) 返回)
			 */
			Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
			if (matchingBeans.isEmpty()) {
				//如果 autowire 的 require 属性为 true,而找到的匹配项却为空,则只能抛出异常
				if (isRequired(descriptor)) {
					raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
				}
				return null;
			}

			String autowiredBeanName;
			Object instanceCandidate;

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

跟踪 resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);

	@Nullable
	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();
			ResolvableType resolvableType = descriptor.getResolvableType();
			Class<?> resolvedArrayType = resolvableType.resolve(type);
			if (resolvedArrayType != type) {
				componentType = resolvableType.getComponentType().resolve();
			}
			if (componentType == null) {
				return null;
			}
			/**
			 * 根据属性类型找到 beanFactory 中所有类型的匹配 bean,
			 * 返回值的构成为:
			 * 		key:匹配的beanName,value:beanName 对应实例化后的 bean (通过 getBean(beanName) 返回).
			 */
			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.3、applyPropertyValues

程序运行到这里,已经完成了对所有注入属性的获取,但是获取的属性是以 PropertyValues 形式存在的,还并没有应用到已经实例化的 bean 中,这一工作是在 applyPropertyValues 中

	/**
	 * 将属性应用到 bean 中
	 * 将所有 PropertyValues 中的属性填充至 BeanWrapper
	 */
	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);
				}
				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);
		}
	}

4、初始化 bean

在 bean 配置时,bean 中有个 init-method 属性,这个属性的作用是在 bean 实例化前调用 init-method 指定的方法来根据用户业务进行相应的实例化。
首先看一下这个方法的执行位置,Spring 中程序已经执行过 bean 的实例化,并且进行了属性的填充,而就在这时将会调用用户设定的初始化方法。
exposedObject = initializeBean(beanName, exposedObject, mbd);

	/**
	 * 初始化 Bean
	 * 进行客户设定的初始化方法的调用
	 */
	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 处理,
			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;
	}

4.1、激活 Aware 方法

在分析原理前,先了解一下 Aware 的使用。Spring 中提供了一些 Aware 相关接口,比如:BeanFactoryAwareApplicationContextAwareResourceLoaderAwareServletContextAware等,实现这些 Aware 接口的 bean 在被初始之后,可以取得一些相对应的资源。
例如,实现 BeanFactoryAware 的 bean 在初始之后,Spring 容器将会注入 BeanFactory 的实例。
实现 ApplicationContextAware 的 bean ,在被初始之后,将会被注入 ApplicationContext 的实例。

我们通过一个示例来了解一下 Aware 的使用:
1、定义普通 bean

package cn.lemon.demo.bean;

public class Hello {
    public void say(){
        System.out.println("This is Hello method");
    }
}

2、定义 BeanFactoryAware 类型的 bean

package cn.lemon.demo.bean;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;

public class Test implements BeanFactoryAware {
    private BeanFactory beanFactory;

    //声明 bean 的时候 Spring 会自动注入 BeanFactory
    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        this.beanFactory = beanFactory;
    }

    public void testAware(){
        //通过 Hello 这个 bean 的 id 从 beanFactory 获取实例
        Hello hello = (Hello) beanFactory.getBean("hello");
        hello.say();
    }
}

3、spring.xml

    <bean id="test" class="cn.lemon.demo.bean.Test"/>
    <bean id="hello" class="cn.lemon.demo.bean.Hello"/>

4、测试

        ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
        Test test = (Test) context.getBean("test");
        test.testAware();//输出:This is Hello method

按照上面的方法我们可以获取到 Spring 中 BeanFactory,并且可以根据 BeanFactory 获取所有 bean 以及相关设置。当然还有其他 Aware 的使用方法都大同小异。
来看一下 Spring 的实现方式:invokeAwareMethods(beanName, bean);

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

4.2、处理器的应用

BeanPostProcessor 处理器,这是 Spring 中开放式架构中一个必不可少的亮点,给用户充足的权限去更改或者扩展 Spring 。
而除了 BeanPostProcessor 外还有很多其他的 PostProcessor ,当然大部分都是以此为基础,继承 BeanPostProcessor 。
BeanPostProcessor 的使用位置就是这里,在调用客户自定义初始化方法前 及 调用客户自定义初始化方法后分别会调用 BeanPostProcessor 的 postProcessBeforeInitialization 和 postProcessAfterInitialization 方法,使用户可以根据自己的业务需求进行响应处理。

wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);

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

4.3、激活自定义的 init 方法

客户定制的初始化方法除了我们熟知的使用配置 init-method 外,还有使自定义的 bean 实现 InitializingBean 接口,并在 afterPropertiesSet 中实现自己的初始化业务逻辑。
init-method 与 afterPropertiesSet 都是在初始化 bean 时执行,执行顺序是 afterPropertiesSet 先执行,然后是 init-method。
在 invokeInitMethods 方法中就实现了这两个步骤的初始化方法的调用

	/**
	 * 激活自定义的 init 方法
	 */
	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、注册 DisposableBean

Spring 中不但提供了对于初始化方法的扩展入口,同样也提供了销毁方法的扩展入口。
对于销毁方法的扩展,除了我们熟悉的配置属性 destroy-method 方法外,用户还可以注册后处理器 DestructionAwareBeanPostPeocessor来统一处理 bean 的销毁方法,代码如下:

	/**
	 * 注册 DisposableBean
	 * 销毁方法的扩展入口
	 */
	protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) {
		AccessControlContext acc = (System.getSecurityManager() != null ? getAccessControlContext() : null);
		if (!mbd.isPrototype() && requiresDestruction(bean, mbd)) {
			if (mbd.isSingleton()) {
				// Register a DisposableBean implementation that performs all destruction
				// work for the given bean: DestructionAwareBeanPostProcessors,
				// DisposableBean interface, custom destroy method.
				/**
				 * 单例模式下注册需要销毁的 bean ,此方法中会处理实现 DisposableBean 的 bean,
				 * 并且对所有的 bean 使用 DestructionAwareBeanPostProcessors 处理
				 */
				registerDisposableBean(beanName, new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
			}
			else {
				// A bean with a custom scope...
				//自定义 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));
			}
		}
	}

在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值