08. Spring DI源码解析

08 Spring DI源码解析


目录

08 Spring DI源码解析

Pt1 DI核心类库

Pt1.1 FactoryBean

Pt1.2 ObjectFactory

Pt1.3 BeanWrapper

Pt1.4 BeanDefinition

BeanDefinition

AbstractBeanDefinition

RootBeanDefinition

ChildBeanDefinition

GenericBeanDefinition

Pt2 循环依赖

Pt2.1 什么是循环依赖

Pt2.2 Bean的初始化过程

Pt2.3 二级缓存

Pt2.4 三级缓存

Pt2.5 Prototype和构造器注入无法解决循环依赖

Pt3 DI初始化流程

Pt3.1 寻找DI入口

Pt3.2 Bean名称解析

Pt3.3 获取缓存的单例Bean

Pt3.4 从FactoryBean获取Bean对象

BeanFactoryUtils.isFactoryDereference

getCachedObjectForFactoryBean

getObjectFromFactoryBean

Pt3.5 检查容器中的BeanDefinition

Pt3.6 检查DependsOn关系

Pt3.7 创建单例Bean对象

Pt3.8 创建原型Bean对象

Pt3.9 创建其他Scope类型Bean对象

Pt3.10 Bean对象类型检查

Pt4 Bean的创建流程

Pt4.1 Bean创建入口

Pt4.2 获取BeanClass

Pt4.3 Override方法处理

Pt4.4 创建Bean对象

Pt4.5 缓存中获取BeanWrapper

Pt4.6 构造器实例化Bean对象

Pt4.7 生成代理对象放入三级缓存

Pt4.8 属性填充

Pt4.9 执行init处理

Pt4.10 循环依赖检查

Pt4.11 添加到一级缓存

Pt4.12 获取Bean对象

Pt5 源码分析

Pt5.1 单例模式双重检查

参考资料


当IoC容器I完成Bean资源的定位、载入和解析注册之后,IoC容器已经包含Bean定义的相关数据,但是此时容器中还没有Bean的实例化对象以及Bean之间依赖关系,这部分依赖关系的初始化主要依赖DI(依赖注入)来完成。

依赖注入会在以下两种场景下发生:

  • 用户第一次调用getBean()方法时,IoC容器触发以来注册;

  • 当用户配置了lazy-init=false时,即容器在解析注册Bean定义时进行预实例化,触发依赖注册。


让我们开始DI的旅程吧,这篇篇幅比较长,整理了好几天,阅读起来可能需要花点时间。

PS.万万没想到的是,在IoC、AOP、DI和MVC中,DI是最复杂的一块。感觉逻辑跳来跳去的,很容易不知道看到哪里去了。所以要抓住主干,不要被细节缠住,如果迷失了就看看手写源码部分DI的核心在哪里。

 

 


Pt1 DI核心类库

Pt1.1 FactoryBean

Spring中,BeanFactory和FactoryBean是很容易混淆的两个概念。

  • BeanFactory:Bean的工厂类,也可以理解为Spring的IoC容器。他的作用是管理Bean,包括Bean的定位、加载、实例化、配置、依赖注入等。

  • FactoryBean:工厂Bean,他只是一个Bean,作用是产生其他Bean实例。他提供一个工厂方法,用于产生真正有用的Bean。

 

FactoryBean接口使你可以自定义一个复杂的逻辑来生成Bean。它本质是一个Bean,但这个Bean不是用来注入到其它地方像Service、Dao一样使用的,它是用来生成其它Bean使用的。实现了这个接口后,Spring在容器初始化时,把实现这个接口的Bean取出来,使用接口的getObject()方法来生成我们要想的Bean。

直白点说,使用FactoryBean可以在Bean对象的实例化过程中添加自定义逻辑(通过BeanPostProcessor来实现功能增强),从而可以增强创建的对象。

 // 工厂Bean,用于产生其他Bean对象。
 public interface FactoryBean<T> {
 ​
    // 区分FactoryBean对象本身和其管理的Bean对象
    String OBJECT_TYPE_ATTRIBUTE = "factoryBeanObjectType";
 ​
    // 获取当前FactoryBean管理的Bean对象实例
    @Nullable
    T getObject() throws Exception;
 ​
    // 获取当前FactoryBean管理的Bean类型
    @Nullable
    Class<?> getObjectType();
 ​
    // 当前FactoryBean创建的Bean对象是否是单例模式。
    // 如果是则整个容器中只有一个实例对象,每次请求都返回同一个实例对象。
    default boolean isSingleton() {
       return true;
    }
 }

AbstractFactoryBean实现了FactoryBean的核心逻辑:

public abstract class AbstractFactoryBean<T>
		implements FactoryBean<T>, BeanClassLoaderAware, BeanFactoryAware, InitializingBean, DisposableBean {
	protected final Log logger = LogFactory.getLog(getClass());

	// 管理的Bean是否单例
	private boolean singleton = true;

	@Nullable
	private ClassLoader beanClassLoader = ClassUtils.getDefaultClassLoader();

	// IoC容器
	@Nullable
	private BeanFactory beanFactory;

	// 管理的Bean是否完成初始化,指完整的对象创建流程。
	private boolean initialized = false;

	// 成熟的Bean实例对象
	@Nullable
	private T singletonInstance;

	// 不成熟的Bean实例对象(未完成所有对象创建流程)
	@Nullable
	private T earlySingletonInstance;

	// 管理的Bean是否单例
	public void setSingleton(boolean singleton) {
		this.singleton = singleton;
	}
	@Override
	public boolean isSingleton() {
		return this.singleton;
	}

	@Override
	public void setBeanClassLoader(ClassLoader classLoader) {
		this.beanClassLoader = classLoader;
	}

	@Override
	public void setBeanFactory(@Nullable BeanFactory beanFactory) {
		this.beanFactory = beanFactory;
	}

	@Nullable
	protected BeanFactory getBeanFactory() {
		return this.beanFactory;
	}

	/**
	 * Obtain a bean type converter from the BeanFactory that this bean
	 * runs in. This is typically a fresh instance for each call,
	 * since TypeConverters are usually <i>not</i> thread-safe.
	 * <p>Falls back to a SimpleTypeConverter when not running in a BeanFactory.
	 * @see ConfigurableBeanFactory#getTypeConverter()
	 * @see org.springframework.beans.SimpleTypeConverter
	 */
	protected TypeConverter getBeanTypeConverter() {
		BeanFactory beanFactory = getBeanFactory();
		if (beanFactory instanceof ConfigurableBeanFactory) {
			return ((ConfigurableBeanFactory) beanFactory).getTypeConverter();
		}
		else {
			return new SimpleTypeConverter();
		}
	}

	// 执行FactoryBean初始化操作
	@Override
	public void afterPropertiesSet() throws Exception {
		// 如果是单例,则先创建对象(恶汉模式)
		if (isSingleton()) {
			this.initialized = true;
			this.singletonInstance = createInstance();
			this.earlySingletonInstance = null;
		}
	}

	// 获取当前FactoryBean管理的Bean对象实例
	@Override
	public final T getObject() throws Exception {
		// 如果是单例,判断是否已经有创建过的对象
		if (isSingleton()) {
			return (this.initialized ? this.singletonInstance : getEarlySingletonInstance());
		}
		else {
			return createInstance();
		}
	}

	// 创建一个早期Bean实例对象,解决循环依赖问题。
	@SuppressWarnings("unchecked")
	private T getEarlySingletonInstance() throws Exception {
		Class<?>[] ifcs = getEarlySingletonInterfaces();
		if (ifcs == null) {
			throw new FactoryBeanNotInitializedException(
					getClass().getName() + " does not support circular references");
		}
		if (this.earlySingletonInstance == null) {
			this.earlySingletonInstance = (T) Proxy.newProxyInstance(
					this.beanClassLoader, ifcs, new EarlySingletonInvocationHandler());
		}
		return this.earlySingletonInstance;
	}

	// 获取单例对象的Bean实例
	@Nullable
	private T getSingletonInstance() throws IllegalStateException {
		Assert.state(this.initialized, "Singleton instance not initialized yet");
		return this.singletonInstance;
	}

	// 销毁Bean
	@Override
	public void destroy() throws Exception {
		if (isSingleton()) {
			destroyInstance(this.singletonInstance);
		}
	}


	// 获取当前FactoryBean管理的Bean类型
	@Override
	@Nullable
	public abstract Class<?> getObjectType();

	// 创建Bean实例,子类实现逻辑。
	protected abstract T createInstance() throws Exception;

	/**
	 * Return an array of interfaces that a singleton object exposed by this
	 * FactoryBean is supposed to implement, for use with an 'early singleton
	 * proxy' that will be exposed in case of a circular reference.
	 * <p>The default implementation returns this FactoryBean's object type,
	 * provided that it is an interface, or {@code null} otherwise. The latter
	 * indicates that early singleton access is not supported by this FactoryBean.
	 * This will lead to a FactoryBeanNotInitializedException getting thrown.
	 * @return the interfaces to use for 'early singletons',
	 * or {@code null} to indicate a FactoryBeanNotInitializedException
	 * @see org.springframework.beans.factory.FactoryBeanNotInitializedException
	 */
	@Nullable
	protected Class<?>[] getEarlySingletonInterfaces() {
		Class<?> type = getObjectType();
		return (type != null && type.isInterface() ? new Class<?>[] {type} : null);
	}

	// 销毁Bean
	protected void destroyInstance(@Nullable T instance) throws Exception {
	}


	// 动态代理处理
	private class EarlySingletonInvocationHandler implements InvocationHandler {

		@Override
		public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
			if (ReflectionUtils.isEqualsMethod(method)) {
				// Only consider equal when proxies are identical.
				return (proxy == args[0]);
			}
			else if (ReflectionUtils.isHashCodeMethod(method)) {
				// Use hashCode of reference proxy.
				return System.identityHashCode(proxy);
			}
			else if (!initialized && ReflectionUtils.isToStringMethod(method)) {
				return "Early singleton proxy for interfaces " +
						ObjectUtils.nullSafeToString(getEarlySingletonInterfaces());
			}
			try {
				return method.invoke(getSingletonInstance(), args);
			}
			catch (InvocationTargetException ex) {
				throw ex.getTargetException();
			}
		}
	}
}

 

ObjectFactoryCreatingFactoryBean是实现类,不过生成的是ObjectFactory类型的Bean,也是用来管理Bean的工厂类。

// 生成一个管理指定BeanName的FactoryBean(ObjectFactory)
public class ObjectFactoryCreatingFactoryBean extends AbstractFactoryBean<ObjectFactory<Object>> {

   // ObjectFactory管理的Bean
   @Nullable
   private String targetBeanName;

   // 最终管理的目标Bean
   public void setTargetBeanName(String targetBeanName) {
      this.targetBeanName = targetBeanName;
   }

   @Override
   public void afterPropertiesSet() throws Exception {
      Assert.hasText(this.targetBeanName, "Property 'targetBeanName' is required");
      super.afterPropertiesSet();
   }


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

   // 创建当前FactoryBean管理的Bean实例
   @Override
   protected ObjectFactory<Object> createInstance() {
      BeanFactory beanFactory = getBeanFactory();
      Assert.state(beanFactory != null, "No BeanFactory available");
      Assert.state(this.targetBeanName != null, "No target bean name specified");
      return new TargetBeanObjectFactory(beanFactory, this.targetBeanName);
   }

   // 内部类,增加序列化能力
   @SuppressWarnings("serial")
   private static class TargetBeanObjectFactory implements ObjectFactory<Object>, Serializable {

      // IoC容器
      private final BeanFactory beanFactory;
      // 目标Bean名称
      private final String targetBeanName;

      public TargetBeanObjectFactory(BeanFactory beanFactory, String targetBeanName) {
         this.beanFactory = beanFactory;
         this.targetBeanName = targetBeanName;
      }

      @Override
      public Object getObject() throws BeansException {
         return this.beanFactory.getBean(this.targetBeanName);
      }
   }
}

 


Pt1.2 ObjectFactory

ObjectFactory也是一个工厂Bean,用来生成Object对象。这个接口一般被用来,包装一个Factory,通过这个Factory来管理一个Prototype类型的Bean。

这个接口和FactoryBean有点像,但FactoryBean的实现是被当做一个SPI(Service Provider Interface)实例来使用。ObjectFactory的实现一般被用来注入到其它Bean中,作为API来使用。就像ObjectFactoryCreatingFactoryBean的例子,它的返回值就是一个ObjectFactory,这个ObjectFactory被注入到了Bean中,在Bean通过这个接口的实例,来取得我们想要的Bean。

Service Provider Interface:SPI是一种API,这种API被第三方来实现或扩展。它可以被用来扩展框架或实现组件替换功能

 

总的来说,FactoryBean和ObjectFactory都是用来取得Bean,但使用的方法和地方不同,FactoryBean被配置好后,Spring调用getObject()方法来取得Bean,ObjectFactory配置好后,在Bean里面可以取得ObjectFactory实例,需要我们手动来调用getObject()来取得Bean。

@FunctionalInterface
public interface ObjectFactory<T> {

   // 获取管理的Bean实例
   T getObject() throws BeansException;
}

 


Pt1.3 BeanWrapper

BeanWrapper是对Bean的封装,包含了真正的bean对象和bean的class,以及PropertyDescriptor集合。

// BeanWrapper是对Bean的封装,包含了真正的bean对象和bean的class,以及PropertyDescriptor集合。
public interface BeanWrapper extends ConfigurablePropertyAccessor {

   // 指定数组和集合自动增长的限制。
   void setAutoGrowCollectionLimit(int autoGrowCollectionLimit);

   // 返回数组和集合自动增长的限制。
   int getAutoGrowCollectionLimit();

   // 获取包装的Bean对象
   Object getWrappedInstance();

   // 获取包装的Bean的class
   Class<?> getWrappedClass();

   // 获取所有属性的属性描述符
   PropertyDescriptor[] getPropertyDescriptors();

   // 获取指定属性的属性描述符
   PropertyDescriptor getPropertyDescriptor(String propertyName) throws InvalidPropertyException;
}

 


Pt1.4 BeanDefinition

BeanDefinition 用于保存 Bean 的相关信息,包括属性、构造方法参数、依赖的 Bean 名称及是否单例、延迟加载等,它是实例化 Bean 的原材料,Spring 就是根据 BeanDefinition 中的信息实例化 Bean。

 

常用BeanDefinition类如下:

  • BeanDefinition:顶层接口,描述了一个 Bean 实例,实例包含属性值、构造方法参数值以及更多实现信息。该 BeanDefinition 只是是一个最小的接口,主要目的是允许修改属性值和其他 Bean 元数据。

  • AbstractBeanDefinition:是 BeanDefinition 的子抽象类,也是其他 BeanDefinition 类型的基类,其实现了接口中定义的一系列操作方法,并定义了一系列的常量属性,这些常量会直接影响到 Spring 实例化 Bean 时的策略。

    AbstractBeanDefinition 直接实现类:RootBeanDefinition、GenericBeanDefinition、ChildBeanDefinition。

  • RootBeanDefinition:继承了 AbstractBeanDefinition,这是一个具体 BeanDefinition,有实际作用。一个 RootBeanDefinition 表示它是一个可合并的 BeanDefinition,会在 BeanFactory 解析的时候合成一个完整的 BeanDefinition。比如这个 Bean 继承了某个类或继承了某个 Bean,亦或是实现了某个接口。

  • ChildBeanDefinition:该类继承自 AbstractBeanDefinition。其相当于一个子类,不可以单独存在,必须依赖一个父 BeanDetintion(RootBeanDefinition类型),构造 ChildBeanDefinition 时,通过构造方法传入父 BeanDetintion 的名称或通过 setParentName 设置父名称。它可以从父类继承方法参数、属性值,并可以重写父类的方法,同时也可以增加新的属性或者方法。若重新定义 init 方法,destroy 方法或者静态工厂方法,ChildBeanDefinition 会重写父类的设置。

  • GenericBeanDefinition:是 Spring 2.5 以后新引入的 BeanDefinition,是 ChildBeanDefinition 更好的替代者,它同样可以通过 setParentName 方法设置父 BeanDefinition。

 

BeanDefinition的定义还是很复杂的,但是在IoC和DI的逻辑中,大量涉及到BeanDefinition的操作,如果不了解BeanDefinition的话,有些地方理解起来非常困难。先看看BeanDefinition的相关类的源码定义。

  • BeanDefinition

// Bean的定义用BeanDefinition对象来表示,包含以下元数据:
//   全限定类名, 通常是Bean的实际实现类;
//   Bean行为配置元素,它们说明Bean在容器中的行为(作用域、生命周期回调等等);
//   Bean执行工作所需要的的其他Bean的引用,这些Bean也称为协作者或依赖项;
//   其他配置信息,例如,管理连接池的bean中,限制池的大小或者使用的连接的数量。
public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement {

   // 单例、原型标识符
   String SCOPE_SINGLETON = ConfigurableBeanFactory.SCOPE_SINGLETON;
   String SCOPE_PROTOTYPE = ConfigurableBeanFactory.SCOPE_PROTOTYPE;

   // 标识 Bean 的类别,分别对应 用户定义的 Bean、来源于配置文件的 Bean、Spring 内部的 Bean
   int ROLE_APPLICATION = 0;
   int ROLE_SUPPORT = 1;
   int ROLE_INFRASTRUCTURE = 2;

   // 设置、返回 Bean 的父类名称
   void setParentName(@Nullable String parentName);
   @Nullable
   String getParentName();

   // 设置、返回 Bean 的 className
   void setBeanClassName(@Nullable String beanClassName);
   @Nullable
   String getBeanClassName();

   // 设置、返回 Bean 的作用域
   void setScope(@Nullable String scope);
   @Nullable
   String getScope();

   // 设置、返回 Bean 是否懒加载
   void setLazyInit(boolean lazyInit);
   boolean isLazyInit();

   // 设置、返回当前 Bean 所依赖的其它 Bean 名称。
   void setDependsOn(@Nullable String... dependsOn);
   @Nullable
   String[] getDependsOn();

   // 设置、返回 Bean 是否可以自动注入。只对 @Autowired 注解有效
   void setAutowireCandidate(boolean autowireCandidate);
   boolean isAutowireCandidate();

   // 设置、返回当前 Bean 是否为主要候选 Bean 。
   // 当同一个接口有多个实现类时,通过该属性来配置某个 Bean 为主候选 Bean。
   void setPrimary(boolean primary);
   boolean isPrimary();

   // 定义创建该Bean对象的工厂类
   void setFactoryBeanName(@Nullable String factoryBeanName);
   @Nullable
   String getFactoryBeanName();

   // 创建该Bean对象的工厂方法
   void setFactoryMethodName(@Nullable String factoryMethodName);
   @Nullable
   String getFactoryMethodName();

   // 返回此bean的构造函数参数值。
   ConstructorArgumentValues getConstructorArgumentValues();
   default boolean hasConstructorArgumentValues() {
      return !getConstructorArgumentValues().isEmpty();
   }

   // 获取普通属性集合
   MutablePropertyValues getPropertyValues();
   default boolean hasPropertyValues() {
      return !getPropertyValues().isEmpty();
   }

   // 定义初始化Bean的方法名称
   void setInitMethodName(@Nullable String initMethodName);
   @Nullable
   String getInitMethodName();

   // 定义销毁Bean的方法名称
   void setDestroyMethodName(@Nullable String destroyMethodName);
   @Nullable
   String getDestroyMethodName();

   // 设置和获取这个bean的应用
   void setRole(int role);
   int getRole();

   // 设置和获取对bean定义的可读描述。
   void setDescription(@Nullable String description);
   @Nullable
   String getDescription();


   // Read-only attributes

   // Bean类型
   ResolvableType getResolvableType();

   // 是否为单例、原型和抽象类
   boolean isSingleton();
   boolean isPrototype();
   boolean isAbstract();

   // 返回该bean定义来自的资源的描述(用于在出现错误时显示上下文)
   @Nullable
   String getResourceDescription();
   @Nullable
   BeanDefinition getOriginatingBeanDefinition();
}

 

  • AbstractBeanDefinition

// AbstractBeanDefinition 是 BeanDefinition 的直接实现类,从类名也知道,它是一个抽象的 BeanDefinition,还不够具体。
// AbstractBeanDefinition 已经对 BeanDefinition 方法有了基本实现逻辑,增加了许多新的属性(默认属性)。
// AbstractBeanDefinition 直接实现类:RootBeanDefinition、GenericBeanDefinition、ChildBeanDefinition。
@SuppressWarnings("serial")
public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccessor
      implements BeanDefinition, Cloneable {

   /** 常量的定义 */
   // 默认的SCOPE,默认是单例
   public static final String SCOPE_DEFAULT = "";

   // 不进行自动装配
   public static final int AUTOWIRE_NO = AutowireCapableBeanFactory.AUTOWIRE_NO;
   // 根据Bean的名字进行自动装配,即autowired属性的值为byname
   public static final int AUTOWIRE_BY_NAME = AutowireCapableBeanFactory.AUTOWIRE_BY_NAME;
   // 根据Bean的类型进行自动装配,调用setter函数装配属性,即autowired属性的值为byType
   public static final int AUTOWIRE_BY_TYPE = AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE;
   // 自动装配构造函数的形参,完成对应属性的自动装配,即autowired属性的值为byConstructor
   public static final int AUTOWIRE_CONSTRUCTOR = AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR;
   // 通过Bean的class推断适当的自动装配策略(autowired=autodetect),如果Bean定义有有参构造函数,则通过自动装配构造函数形参,
   // 完成对应属性的自动装配(AUTOWIRE_CONSTRUCTOR),否则,使用setter函数(AUTOWIRE_BY_TYPE)
   @Deprecated
   public static final int AUTOWIRE_AUTODETECT = AutowireCapableBeanFactory.AUTOWIRE_AUTODETECT;

   // 不进行依赖检查
   public static final int DEPENDENCY_CHECK_NONE = 0;
   // 如果依赖类型为对象引用,则需要检查
   public static final int DEPENDENCY_CHECK_OBJECTS = 1;
   // 对简单属性的依赖进行检查
   public static final int DEPENDENCY_CHECK_SIMPLE = 2;
   // 对所有属性的依赖进行检查
   public static final int DEPENDENCY_CHECK_ALL = 3;

   // 若Bean未指定销毁方法,容器应该尝试推断Bean的销毁方法的名字,目前来说,推断的销毁方法的名字一般为close或是shutdown
   // (即未指定Bean的销毁方法,但是内部定义了名为close或是shutdown的方法,则容器推断其为销毁方法)
   public static final String INFER_METHOD = "(inferred)";

   /** 定义的变量 */

   // Bean的class对象或是类的全限定名
   @Nullable
   private volatile Object beanClass;

   // 默认的scope是单例
   @Nullable
   private String scope = SCOPE_DEFAULT;

   // 默认不为抽象类
   private boolean abstractFlag = false;

   // 是否是懒加载
   @Nullable
   private Boolean lazyInit;

   // 默认不进行自动装配
   private int autowireMode = AUTOWIRE_NO;

   // 默认不进行依赖检查
   private int dependencyCheck = DEPENDENCY_CHECK_NONE;

   // 当前Bean依赖的Bean对象。是指使用@DependsOn标注,用来控制Bean初始化状态的注解,当前Bean必须等到所有dependsOn的Bean全部初始化之后才能进行初始化。
   // 这里只会存放<bean/>标签的depends-on属性或是@DependsOn注解的值
   @Nullable
   private String[] dependsOn;

   // 是自动装配的候选者,意味着可以自动装配到其他Bean的某个属性
   private boolean autowireCandidate = true;

   // 当某个Bean的某个属性自动装配有多个候选者(包括自己)时,是否优先注入,即@Primary注解
   private boolean primary = false;

   // Bean的限定符
   private final Map<String, AutowireCandidateQualifier> qualifiers = new LinkedHashMap<>();

   // 用于初始化Bean的回调函数,一旦指定,这个方法会覆盖工厂方法以及构造函数中的元数据
   @Nullable
   private Supplier<?> instanceSupplier;

   // 是否允许访问非public方法和属性,应用于构造函数、工厂方法、init、destroy方法的解析
   private boolean nonPublicAccessAllowed = true;

   // 指定解析构造函数的模式,是宽松还是严格
   private boolean lenientConstructorResolution = true;

   // 工厂类名
   @Nullable
   private String factoryBeanName;

   // 工厂方法名
   @Nullable
   private String factoryMethodName;

   // 存储构造函数形参的值
   @Nullable
   private ConstructorArgumentValues constructorArgumentValues;

   // Bean属性的名称以及对应的值,这里不会存放构造函数相关的参数值,只会存放通过setter注入的依赖。
   @Nullable
   private MutablePropertyValues propertyValues;

   // 存储被IOC容器覆盖的方法的相关信息(例如replace-method属性指定的函数)
   private MethodOverrides methodOverrides = new MethodOverrides();

   // init函数的名字
   @Nullable
   private String initMethodName;

   // destory函数的名字
   @Nullable
   private String destroyMethodName;

   private boolean enforceInitMethod = true;

   private boolean enforceDestroyMethod = true;

   // 是否是合成类(不是应用自定义的,例如生成AOP代理时,会用到某些辅助类,这些辅助类不是应用自定义的,这个就是合成类)
   private boolean synthetic = false;

   // Bean的角色,默认为用户自定义Bean
   private int role = BeanDefinition.ROLE_APPLICATION;

   // Bean的描述
   @Nullable
   private String description;

   @Nullable
   private Resource resource;

   // 构造器
   protected AbstractBeanDefinition() {
      this(null, null);
   }
   protected AbstractBeanDefinition(@Nullable ConstructorArgumentValues cargs, @Nullable MutablePropertyValues pvs) {
      this.constructorArgumentValues = cargs;
      this.propertyValues = pvs;
   }
   protected AbstractBeanDefinition(BeanDefinition original) {
      setParentName(original.getParentName());
      setBeanClassName(original.getBeanClassName());
      setScope(original.getScope());
      setAbstract(original.isAbstract());
      setFactoryBeanName(original.getFactoryBeanName());
      setFactoryMethodName(original.getFactoryMethodName());
      setRole(original.getRole());
      setSource(original.getSource());
      copyAttributesFrom(original);

      if (original instanceof AbstractBeanDefinition) {
         AbstractBeanDefinition originalAbd = (AbstractBeanDefinition) original;
         if (originalAbd.hasBeanClass()) {
            setBeanClass(originalAbd.getBeanClass());
         }
         if (originalAbd.hasConstructorArgumentValues()) {
            setConstructorArgumentValues(new ConstructorArgumentValues(original.getConstructorArgumentValues()));
         }
         if (originalAbd.hasPropertyValues()) {
            setPropertyValues(new MutablePropertyValues(original.getPropertyValues()));
         }
         if (originalAbd.hasMethodOverrides()) {
            setMethodOverrides(new MethodOverrides(originalAbd.getMethodOverrides()));
         }
         Boolean lazyInit = originalAbd.getLazyInit();
         if (lazyInit != null) {
            setLazyInit(lazyInit);
         }
         setAutowireMode(originalAbd.getAutowireMode());
         setDependencyCheck(originalAbd.getDependencyCheck());
         setDependsOn(originalAbd.getDependsOn());
         setAutowireCandidate(originalAbd.isAutowireCandidate());
         setPrimary(originalAbd.isPrimary());
         copyQualifiersFrom(originalAbd);
         setInstanceSupplier(originalAbd.getInstanceSupplier());
         setNonPublicAccessAllowed(originalAbd.isNonPublicAccessAllowed());
         setLenientConstructorResolution(originalAbd.isLenientConstructorResolution());
         setInitMethodName(originalAbd.getInitMethodName());
         setEnforceInitMethod(originalAbd.isEnforceInitMethod());
         setDestroyMethodName(originalAbd.getDestroyMethodName());
         setEnforceDestroyMethod(originalAbd.isEnforceDestroyMethod());
         setSynthetic(originalAbd.isSynthetic());
         setResource(originalAbd.getResource());
      }
      else {
         setConstructorArgumentValues(new ConstructorArgumentValues(original.getConstructorArgumentValues()));
         setPropertyValues(new MutablePropertyValues(original.getPropertyValues()));
         setLazyInit(original.isLazyInit());
         setResourceDescription(original.getResourceDescription());
      }
   }


   // 使用传参other覆盖bean定义
   public void overrideFrom(BeanDefinition other) {
      if (StringUtils.hasLength(other.getBeanClassName())) {
         setBeanClassName(other.getBeanClassName());
      }
      if (StringUtils.hasLength(other.getScope())) {
         setScope(other.getScope());
      }
      setAbstract(other.isAbstract());
      if (StringUtils.hasLength(other.getFactoryBeanName())) {
         setFactoryBeanName(other.getFactoryBeanName());
      }
      if (StringUtils.hasLength(other.getFactoryMethodName())) {
         setFactoryMethodName(other.getFactoryMethodName());
      }
      setRole(other.getRole());
      setSource(other.getSource());
      copyAttributesFrom(other);

      if (other instanceof AbstractBeanDefinition) {
         AbstractBeanDefinition otherAbd = (AbstractBeanDefinition) other;
         if (otherAbd.hasBeanClass()) {
            setBeanClass(otherAbd.getBeanClass());
         }
         if (otherAbd.hasConstructorArgumentValues()) {
            getConstructorArgumentValues().addArgumentValues(other.getConstructorArgumentValues());
         }
         if (otherAbd.hasPropertyValues()) {
            getPropertyValues().addPropertyValues(other.getPropertyValues());
         }
         if (otherAbd.hasMethodOverrides()) {
            getMethodOverrides().addOverrides(otherAbd.getMethodOverrides());
         }
         Boolean lazyInit = otherAbd.getLazyInit();
         if (lazyInit != null) {
            setLazyInit(lazyInit);
         }
         setAutowireMode(otherAbd.getAutowireMode());
         setDependencyCheck(otherAbd.getDependencyCheck());
         setDependsOn(otherAbd.getDependsOn());
         setAutowireCandidate(otherAbd.isAutowireCandidate());
         setPrimary(otherAbd.isPrimary());
         copyQualifiersFrom(otherAbd);
         setInstanceSupplier(otherAbd.getInstanceSupplier());
         setNonPublicAccessAllowed(otherAbd.isNonPublicAccessAllowed());
         setLenientConstructorResolution(otherAbd.isLenientConstructorResolution());
         if (otherAbd.getInitMethodName() != null) {
            setInitMethodName(otherAbd.getInitMethodName());
            setEnforceInitMethod(otherAbd.isEnforceInitMethod());
         }
         if (otherAbd.getDestroyMethodName() != null) {
            setDestroyMethodName(otherAbd.getDestroyMethodName());
            setEnforceDestroyMethod(otherAbd.isEnforceDestroyMethod());
         }
         setSynthetic(otherAbd.isSynthetic());
         setResource(otherAbd.getResource());
      }
      else {
         getConstructorArgumentValues().addArgumentValues(other.getConstructorArgumentValues());
         getPropertyValues().addPropertyValues(other.getPropertyValues());
         setLazyInit(other.isLazyInit());
         setResourceDescription(other.getResourceDescription());
      }
   }

   // 使用默认值
   public void applyDefaults(BeanDefinitionDefaults defaults) {
      Boolean lazyInit = defaults.getLazyInit();
      if (lazyInit != null) {
         setLazyInit(lazyInit);
      }
      setAutowireMode(defaults.getAutowireMode());
      setDependencyCheck(defaults.getDependencyCheck());
      setInitMethodName(defaults.getInitMethodName());
      setEnforceInitMethod(false);
      setDestroyMethodName(defaults.getDestroyMethodName());
      setEnforceDestroyMethod(false);
   }

   // Setter & Getter
   @Override
   public void setBeanClassName(@Nullable String beanClassName) {
      this.beanClass = beanClassName;
   }
   @Override
   @Nullable
   public String getBeanClassName() {
      Object beanClassObject = this.beanClass;
      if (beanClassObject instanceof Class) {
         return ((Class<?>) beanClassObject).getName();
      }
      else {
         return (String) beanClassObject;
      }
   }

   public void setBeanClass(@Nullable Class<?> beanClass) {
      this.beanClass = beanClass;
   }

   public Class<?> getBeanClass() throws IllegalStateException {
      Object beanClassObject = this.beanClass;
      if (beanClassObject == null) {
         throw new IllegalStateException("No bean class specified on bean definition");
      }
      if (!(beanClassObject instanceof Class)) {
         throw new IllegalStateException(
               "Bean class name [" + beanClassObject + "] has not been resolved into an actual Class");
      }
      return (Class<?>) beanClassObject;
   }

   // 返回此定义是否指定bean类
   public boolean hasBeanClass() {
      return (this.beanClass instanceof Class);
   }

   // 返回包装好的bean的类
   @Nullable
   public Class<?> resolveBeanClass(@Nullable ClassLoader classLoader) throws ClassNotFoundException {
      String className = getBeanClassName();
      if (className == null) {
         return null;
      }
      Class<?> resolvedClass = ClassUtils.forName(className, classLoader);
      this.beanClass = resolvedClass;
      return resolvedClass;
   }

   // 返回
   @Override
   public ResolvableType getResolvableType() {
      return (hasBeanClass() ? ResolvableType.forClass(getBeanClass()) : ResolvableType.NONE);
   }

   // Scope的setter&getter
   @Override
   public void setScope(@Nullable String scope) {
      this.scope = scope;
   }
   @Override
   @Nullable
   public String getScope() {
      return this.scope;
   }

   // 判断是否单例Bean
   @Override
   public boolean isSingleton() {
      return SCOPE_SINGLETON.equals(this.scope) || SCOPE_DEFAULT.equals(this.scope);
   }

   // 判断是否原型Bean
   @Override
   public boolean isPrototype() {
      return SCOPE_PROTOTYPE.equals(this.scope);
   }

   // abstractFlag的setter & getter
   public void setAbstract(boolean abstractFlag) {
      this.abstractFlag = abstractFlag;
   }
   @Override
   public boolean isAbstract() {
      return this.abstractFlag;
   }

   // 是否延迟加载setter & getter
   @Override
   public void setLazyInit(boolean lazyInit) {
      this.lazyInit = lazyInit;
   }
   @Override
   public boolean isLazyInit() {
      return (this.lazyInit != null && this.lazyInit.booleanValue());
   }
   @Nullable
   public Boolean getLazyInit() {
      return this.lazyInit;
   }

   // autowireMode的setter & getter
   public void setAutowireMode(int autowireMode) {
      this.autowireMode = autowireMode;
   }
   public int getAutowireMode() {
      return this.autowireMode;
   }

   // 获取自动注入的模式
   public int getResolvedAutowireMode() {
      if (this.autowireMode == AUTOWIRE_AUTODETECT) {
         // Work out whether to apply setter autowiring or constructor autowiring.
         // If it has a no-arg constructor it's deemed to be setter autowiring,
         // otherwise we'll try constructor autowiring.
         Constructor<?>[] constructors = getBeanClass().getConstructors();
         for (Constructor<?> constructor : constructors) {
            if (constructor.getParameterCount() == 0) {
               return AUTOWIRE_BY_TYPE;
            }
         }
         return AUTOWIRE_CONSTRUCTOR;
      }
      else {
         return this.autowireMode;
      }
   }

   // dependencyCheck的setter & getter
   public void setDependencyCheck(int dependencyCheck) {
      this.dependencyCheck = dependencyCheck;
   }
   public int getDependencyCheck() {
      return this.dependencyCheck;
   }

   // dependsOn的setter and getter
   @Override
   public void setDependsOn(@Nullable String... dependsOn) {
      this.dependsOn = dependsOn;
   }
   // 获取当前Bean依赖的所有Bean
   @Override
   @Nullable
   public String[] getDependsOn() {
      return this.dependsOn;
   }

   @Override
   public void setAutowireCandidate(boolean autowireCandidate) {
      this.autowireCandidate = autowireCandidate;
   }
   @Override
   public boolean isAutowireCandidate() {
      return this.autowireCandidate;
   }

   @Override
   public void setPrimary(boolean primary) {
      this.primary = primary;
   }
   @Override
   public boolean isPrimary() {
      return this.primary;
   }

   // 限定符处理
   public void addQualifier(AutowireCandidateQualifier qualifier) {
      this.qualifiers.put(qualifier.getTypeName(), qualifier);
   }
   public boolean hasQualifier(String typeName) {
      return this.qualifiers.containsKey(typeName);
   }
   @Nullable
   public AutowireCandidateQualifier getQualifier(String typeName) {
      return this.qualifiers.get(typeName);
   }
   public Set<AutowireCandidateQualifier> getQualifiers() {
      return new LinkedHashSet<>(this.qualifiers.values());
   }

   public void copyQualifiersFrom(AbstractBeanDefinition source) {
      Assert.notNull(source, "Source must not be null");
      this.qualifiers.putAll(source.qualifiers);
   }

   /**
    * Specify a callback for creating an instance of the bean,
    * as an alternative to a declaratively specified factory method.
    * <p>If such a callback is set, it will override any other constructor
    * or factory method metadata. However, bean property population and
    * potential annotation-driven injection will still apply as usual.
    * @since 5.0
    * @see #setConstructorArgumentValues(ConstructorArgumentValues)
    * @see #setPropertyValues(MutablePropertyValues)
    */
   public void setInstanceSupplier(@Nullable Supplier<?> instanceSupplier) {
      this.instanceSupplier = instanceSupplier;
   }

   /**
    * Return a callback for creating an instance of the bean, if any.
    * @since 5.0
    */
   @Nullable
   public Supplier<?> getInstanceSupplier() {
      return this.instanceSupplier;
   }

   /**
    * Specify whether to allow access to non-public constructors and methods,
    * for the case of externalized metadata pointing to those. The default is
    * {@code true}; switch this to {@code false} for public access only.
    * <p>This applies to constructor resolution, factory method resolution,
    * and also init/destroy methods. Bean property accessors have to be public
    * in any case and are not affected by this setting.
    * <p>Note that annotation-driven configuration will still access non-public
    * members as far as they have been annotated. This setting applies to
    * externalized metadata in this bean definition only.
    */
   public void setNonPublicAccessAllowed(boolean nonPublicAccessAllowed) {
      this.nonPublicAccessAllowed = nonPublicAccessAllowed;
   }

   /**
    * Return whether to allow access to non-public constructors and methods.
    */
   public boolean isNonPublicAccessAllowed() {
      return this.nonPublicAccessAllowed;
   }

   /**
    * Specify whether to resolve constructors in lenient mode ({@code true},
    * which is the default) or to switch to strict resolution (throwing an exception
    * in case of ambiguous constructors that all match when converting the arguments,
    * whereas lenient mode would use the one with the 'closest' type matches).
    */
   public void setLenientConstructorResolution(boolean lenientConstructorResolution) {
      this.lenientConstructorResolution = lenientConstructorResolution;
   }

   /**
    * Return whether to resolve constructors in lenient mode or in strict mode.
    */
   public boolean isLenientConstructorResolution() {
      return this.lenientConstructorResolution;
   }

   /**
    * Specify the factory bean to use, if any.
    * This the name of the bean to call the specified factory method on.
    * @see #setFactoryMethodName
    */
   @Override
   public void setFactoryBeanName(@Nullable String factoryBeanName) {
      this.factoryBeanName = factoryBeanName;
   }

   /**
    * Return the factory bean name, if any.
    */
   @Override
   @Nullable
   public String getFactoryBeanName() {
      return this.factoryBeanName;
   }

   /**
    * Specify a factory method, if any. This method will be invoked with
    * constructor arguments, or with no arguments if none are specified.
    * The method will be invoked on the specified factory bean, if any,
    * or otherwise as a static method on the local bean class.
    * @see #setFactoryBeanName
    * @see #setBeanClassName
    */
   @Override
   public void setFactoryMethodName(@Nullable String factoryMethodName) {
      this.factoryMethodName = factoryMethodName;
   }

   /**
    * Return a factory method, if any.
    */
   @Override
   @Nullable
   public String getFactoryMethodName() {
      return this.factoryMethodName;
   }

   /**
    * Specify constructor argument values for this bean.
    */
   public void setConstructorArgumentValues(ConstructorArgumentValues constructorArgumentValues) {
      this.constructorArgumentValues = constructorArgumentValues;
   }

   /**
    * Return constructor argument values for this bean (never {@code null}).
    */
   @Override
   public ConstructorArgumentValues getConstructorArgumentValues() {
      if (this.constructorArgumentValues == null) {
         this.constructorArgumentValues = new ConstructorArgumentValues();
      }
      return this.constructorArgumentValues;
   }

   /**
    * Return if there are constructor argument values defined for this bean.
    */
   @Override
   public boolean hasConstructorArgumentValues() {
      return (this.constructorArgumentValues != null && !this.constructorArgumentValues.isEmpty());
   }

   /**
    * Specify property values for this bean, if any.
    */
   public void setPropertyValues(MutablePropertyValues propertyValues) {
      this.propertyValues = propertyValues;
   }

   /**
    * Return property values for this bean (never {@code null}).
    */
   @Override
   public MutablePropertyValues getPropertyValues() {
      if (this.propertyValues == null) {
         this.propertyValues = new MutablePropertyValues();
      }
      return this.propertyValues;
   }

   /**
    * Return if there are property values values defined for this bean.
    * @since 5.0.2
    */
   @Override
   public boolean hasPropertyValues() {
      return (this.propertyValues != null && !this.propertyValues.isEmpty());
   }

   /**
    * Specify method overrides for the bean, if any.
    */
   public void setMethodOverrides(MethodOverrides methodOverrides) {
      this.methodOverrides = methodOverrides;
   }

   /**
    * Return information about methods to be overridden by the IoC
    * container. This will be empty if there are no method overrides.
    * <p>Never returns {@code null}.
    */
   public MethodOverrides getMethodOverrides() {
      return this.methodOverrides;
   }

   /**
    * Return if there are method overrides defined for this bean.
    * @since 5.0.2
    */
   public boolean hasMethodOverrides() {
      return !this.methodOverrides.isEmpty();
   }

   /**
    * Set the name of the initializer method.
    * <p>The default is {@code null} in which case there is no initializer method.
    */
   @Override
   public void setInitMethodName(@Nullable String initMethodName) {
      this.initMethodName = initMethodName;
   }

   /**
    * Return the name of the initializer method.
    */
   @Override
   @Nullable
   public String getInitMethodName() {
      return this.initMethodName;
   }

   /**
    * Specify whether or not the configured initializer method is the default.
    * <p>The default value is {@code true} for a locally specified init method
    * but switched to {@code false} for a shared setting in a defaults section
    * (e.g. {@code bean init-method} versus {@code beans default-init-method}
    * level in XML) which might not apply to all contained bean definitions.
    * @see #setInitMethodName
    * @see #applyDefaults
    */
   public void setEnforceInitMethod(boolean enforceInitMethod) {
      this.enforceInitMethod = enforceInitMethod;
   }

   /**
    * Indicate whether the configured initializer method is the default.
    * @see #getInitMethodName()
    */
   public boolean isEnforceInitMethod() {
      return this.enforceInitMethod;
   }

   /**
    * Set the name of the destroy method.
    * <p>The default is {@code null} in which case there is no destroy method.
    */
   @Override
   public void setDestroyMethodName(@Nullable String destroyMethodName) {
      this.destroyMethodName = destroyMethodName;
   }

   /**
    * Return the name of the destroy method.
    */
   @Override
   @Nullable
   public String getDestroyMethodName() {
      return this.destroyMethodName;
   }

   /**
    * Specify whether or not the configured destroy method is the default.
    * <p>The default value is {@code true} for a locally specified destroy method
    * but switched to {@code false} for a shared setting in a defaults section
    * (e.g. {@code bean destroy-method} versus {@code beans default-destroy-method}
    * level in XML) which might not apply to all contained bean definitions.
    * @see #setDestroyMethodName
    * @see #applyDefaults
    */
   public void setEnforceDestroyMethod(boolean enforceDestroyMethod) {
      this.enforceDestroyMethod = enforceDestroyMethod;
   }

   /**
    * Indicate whether the configured destroy method is the default.
    * @see #getDestroyMethodName()
    */
   public boolean isEnforceDestroyMethod() {
      return this.enforceDestroyMethod;
   }

   /**
    * Set whether this bean definition is 'synthetic', that is, not defined
    * by the application itself (for example, an infrastructure bean such
    * as a helper for auto-proxying, created through {@code <aop:config>}).
    */
   public void setSynthetic(boolean synthetic) {
      this.synthetic = synthetic;
   }

   /**
    * Return whether this bean definition is 'synthetic', that is,
    * not defined by the application itself.
    */
   public boolean isSynthetic() {
      return this.synthetic;
   }

   /**
    * Set the role hint for this {@code BeanDefinition}.
    */
   @Override
   public void setRole(int role) {
      this.role = role;
   }

   /**
    * Return the role hint for this {@code BeanDefinition}.
    */
   @Override
   public int getRole() {
      return this.role;
   }

   /**
    * Set a human-readable description of this bean definition.
    */
   @Override
   public void setDescription(@Nullable String description) {
      this.description = description;
   }

   /**
    * Return a human-readable description of this bean definition.
    */
   @Override
   @Nullable
   public String getDescription() {
      return this.description;
   }

   /**
    * Set the resource that this bean definition came from
    * (for the purpose of showing context in case of errors).
    */
   public void setResource(@Nullable Resource resource) {
      this.resource = resource;
   }

   /**
    * Return the resource that this bean definition came from.
    */
   @Nullable
   public Resource getResource() {
      return this.resource;
   }

   /**
    * Set a description of the resource that this bean definition
    * came from (for the purpose of showing context in case of errors).
    */
   public void setResourceDescription(@Nullable String resourceDescription) {
      this.resource = (resourceDescription != null ? new DescriptiveResource(resourceDescription) : null);
   }

   /**
    * Return a description of the resource that this bean definition
    * came from (for the purpose of showing context in case of errors).
    */
   @Override
   @Nullable
   public String getResourceDescription() {
      return (this.resource != null ? this.resource.getDescription() : null);
   }

   /**
    * Set the originating (e.g. decorated) BeanDefinition, if any.
    */
   public void setOriginatingBeanDefinition(BeanDefinition originatingBd) {
      this.resource = new BeanDefinitionResource(originatingBd);
   }

   /**
    * Return the originating BeanDefinition, or {@code null} if none.
    * Allows for retrieving the decorated bean definition, if any.
    * <p>Note that this method returns the immediate originator. Iterate through the
    * originator chain to find the original BeanDefinition as defined by the user.
    */
   @Override
   @Nullable
   public BeanDefinition getOriginatingBeanDefinition() {
      return (this.resource instanceof BeanDefinitionResource ?
            ((BeanDefinitionResource) this.resource).getBeanDefinition() : null);
   }

   // 验证当前Bean定义
   public void validate() throws BeanDefinitionValidationException {
      if (hasMethodOverrides() && getFactoryMethodName() != null) {
         throw new BeanDefinitionValidationException(
               "Cannot combine factory method with container-generated method overrides: " +
               "the factory method must create the concrete bean instance.");
      }
      if (hasBeanClass()) {
         prepareMethodOverrides();
      }
   }

   // 处理BeanDefinition中Override父类的方法。
   public void prepareMethodOverrides() throws BeanDefinitionValidationException {
      // BeanDefinition是否有Override父类的方法。
      if (hasMethodOverrides()) {
         // 循环处理所有的Override方法进行校验
         getMethodOverrides().getOverrides().forEach(this::prepareMethodOverride);
      }
   }

   // 验证并准备为此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.
         mo.setOverloaded(false);
      }
   }

   // 基于当前BeanDefinition克隆一个bean
   @Override
   public Object clone() {
      return cloneBeanDefinition();
   }

   // 基于当前BeanDefinition克隆一个bean
   public abstract AbstractBeanDefinition cloneBeanDefinition();

   @Override
   public boolean equals(@Nullable Object other) {
      if (this == other) {
         return true;
      }
      if (!(other instanceof AbstractBeanDefinition)) {
         return false;
      }
      AbstractBeanDefinition that = (AbstractBeanDefinition) other;
      return (ObjectUtils.nullSafeEquals(getBeanClassName(), that.getBeanClassName()) &&
            ObjectUtils.nullSafeEquals(this.scope, that.scope) &&
            this.abstractFlag == that.abstractFlag &&
            this.lazyInit == that.lazyInit &&
            this.autowireMode == that.autowireMode &&
            this.dependencyCheck == that.dependencyCheck &&
            Arrays.equals(this.dependsOn, that.dependsOn) &&
            this.autowireCandidate == that.autowireCandidate &&
            ObjectUtils.nullSafeEquals(this.qualifiers, that.qualifiers) &&
            this.primary == that.primary &&
            this.nonPublicAccessAllowed == that.nonPublicAccessAllowed &&
            this.lenientConstructorResolution == that.lenientConstructorResolution &&
            ObjectUtils.nullSafeEquals(this.constructorArgumentValues, that.constructorArgumentValues) &&
            ObjectUtils.nullSafeEquals(this.propertyValues, that.propertyValues) &&
            ObjectUtils.nullSafeEquals(this.methodOverrides, that.methodOverrides) &&
            ObjectUtils.nullSafeEquals(this.factoryBeanName, that.factoryBeanName) &&
            ObjectUtils.nullSafeEquals(this.factoryMethodName, that.factoryMethodName) &&
            ObjectUtils.nullSafeEquals(this.initMethodName, that.initMethodName) &&
            this.enforceInitMethod == that.enforceInitMethod &&
            ObjectUtils.nullSafeEquals(this.destroyMethodName, that.destroyMethodName) &&
            this.enforceDestroyMethod == that.enforceDestroyMethod &&
            this.synthetic == that.synthetic &&
            this.role == that.role &&
            super.equals(other));
   }

   @Override
   public int hashCode() {
      int hashCode = ObjectUtils.nullSafeHashCode(getBeanClassName());
      hashCode = 29 * hashCode + ObjectUtils.nullSafeHashCode(this.scope);
      hashCode = 29 * hashCode + ObjectUtils.nullSafeHashCode(this.constructorArgumentValues);
      hashCode = 29 * hashCode + ObjectUtils.nullSafeHashCode(this.propertyValues);
      hashCode = 29 * hashCode + ObjectUtils.nullSafeHashCode(this.factoryBeanName);
      hashCode = 29 * hashCode + ObjectUtils.nullSafeHashCode(this.factoryMethodName);
      hashCode = 29 * hashCode + super.hashCode();
      return hashCode;
   }

   @Override
   public String toString() {
      StringBuilder sb = new StringBuilder("class [");
      sb.append(getBeanClassName()).append("]");
      sb.append("; scope=").append(this.scope);
      sb.append("; abstract=").append(this.abstractFlag);
      sb.append("; lazyInit=").append(this.lazyInit);
      sb.append("; autowireMode=").append(this.autowireMode);
      sb.append("; dependencyCheck=").append(this.dependencyCheck);
      sb.append("; autowireCandidate=").append(this.autowireCandidate);
      sb.append("; primary=").append(this.primary);
      sb.append("; factoryBeanName=").append(this.factoryBeanName);
      sb.append("; factoryMethodName=").append(this.factoryMethodName);
      sb.append("; initMethodName=").append(this.initMethodName);
      sb.append("; destroyMethodName=").append(this.destroyMethodName);
      if (this.resource != null) {
         sb.append("; defined in ").append(this.resource.getDescription());
      }
      return sb.toString();
   }

}

 

  • RootBeanDefinition

// RootBeanDefinition 继承了 AbstractBeanDefinition,这是一个具体 BeanDefinition,有实际作用。
// 一个 RootBeanDefinition 表示它是一个可合并的 BeanDefinition,会在 BeanFactory 解析的时候合成一个完整的 BeanDefinition。比如
// 这个 Bean 继承了某个类或继承了某个 Bean,亦或是实现了某个接口。
@SuppressWarnings("serial")
public class RootBeanDefinition extends AbstractBeanDefinition {

   // BeanDefinitionHolder 封装了 Bean 的名称、别名、BeanDefinition
   @Nullable
   private BeanDefinitionHolder decoratedDefinition;

   // AnnotatedElement 是java反射包的接口,通过它可以查看 Bean 的注解信息
   @Nullable
   private AnnotatedElement qualifiedElement;

   /** Determines if the definition needs to be re-merged. */
   volatile boolean stale;

   // 是否允许缓存
   boolean allowCaching = true;

   // 工厂方法是否唯一
   boolean isFactoryMethodUnique;

   // 封装了 java.lang.reflect.Type,提供了泛型相关的操作
   @Nullable
   volatile ResolvableType targetType;

   // 缓存 Class,表示 RootBeanDefinition 存储哪个类的信息
   @Nullable
   volatile Class<?> resolvedTargetType;

   // 当前RootBeanDefinition是否是FactoryBean类型
   @Nullable
   volatile Boolean isFactoryBean;

   // 缓存工厂方法的返回类型
   @Nullable
   volatile ResolvableType factoryMethodReturnType;

   /** Package-visible field for caching a unique factory method candidate for introspection. */
   @Nullable
   volatile Method factoryMethodToIntrospect;

   // 这是以下四个构造方法字段的通用锁
   final Object constructorArgumentLock = new Object();

   // 用于缓存已解析的构造方法或工厂方法
   @Nullable
   Executable resolvedConstructorOrFactoryMethod;

   // 将构造方法参数标记为已解析
   boolean constructorArgumentsResolved = false;

   // 用于缓存完全解析的构造方法参数
   @Nullable
   Object[] resolvedConstructorArguments;

   // 缓存待解析的构造方法参数
   @Nullable
   Object[] preparedConstructorArguments;

   // 这是以下两个后处理字段的通用锁
   final Object postProcessingLock = new Object();

   // 表明是否被 MergedBeanDefinitionPostProcessor 处理过
   boolean postProcessed = false;

   // 在生成代理的时候会使用,表明是否已经生成代理
   @Nullable
   volatile Boolean beforeInstantiationResolved;

   // 实际缓存的类型是 Constructor、Field、Method 类型
   @Nullable
   private Set<Member> externallyManagedConfigMembers;

   // InitializingBean中 的 init 回调函数名,afterPropertiesSet 会在这里记录,以便进行生命周期回调
   @Nullable
   private Set<String> externallyManagedInitMethods;

   // DisposableBean 的 destroy 回调函数名,destroy 会在这里记录,以便进生命周期回调
   @Nullable
   private Set<String> externallyManagedDestroyMethods;

   // 以下是各种类型构造器的定义
   /**
    * Create a new RootBeanDefinition, to be configured through its bean
    * properties and configuration methods.
    * @see #setBeanClass
    * @see #setScope
    * @see #setConstructorArgumentValues
    * @see #setPropertyValues
    */
   public RootBeanDefinition() {
      super();
   }

   /**
    * Create a new RootBeanDefinition for a singleton.
    * @param beanClass the class of the bean to instantiate
    * @see #setBeanClass
    */
   public RootBeanDefinition(@Nullable Class<?> beanClass) {
      super();
      setBeanClass(beanClass);
   }

   /**
    * Create a new RootBeanDefinition for a singleton bean, constructing each instance
    * through calling the given supplier (possibly a lambda or method reference).
    * @param beanClass the class of the bean to instantiate
    * @param instanceSupplier the supplier to construct a bean instance,
    * as an alternative to a declaratively specified factory method
    * @since 5.0
    * @see #setInstanceSupplier
    */
   public <T> RootBeanDefinition(@Nullable Class<T> beanClass, @Nullable Supplier<T> instanceSupplier) {
      super();
      setBeanClass(beanClass);
      setInstanceSupplier(instanceSupplier);
   }

   /**
    * Create a new RootBeanDefinition for a scoped bean, constructing each instance
    * through calling the given supplier (possibly a lambda or method reference).
    * @param beanClass the class of the bean to instantiate
    * @param scope the name of the corresponding scope
    * @param instanceSupplier the supplier to construct a bean instance,
    * as an alternative to a declaratively specified factory method
    * @since 5.0
    * @see #setInstanceSupplier
    */
   public <T> RootBeanDefinition(@Nullable Class<T> beanClass, String scope, @Nullable Supplier<T> instanceSupplier) {
      super();
      setBeanClass(beanClass);
      setScope(scope);
      setInstanceSupplier(instanceSupplier);
   }

   /**
    * Create a new RootBeanDefinition for a singleton,
    * using the given autowire mode.
    * @param beanClass the class of the bean to instantiate
    * @param autowireMode by name or type, using the constants in this interface
    * @param dependencyCheck whether to perform a dependency check for objects
    * (not applicable to autowiring a constructor, thus ignored there)
    */
   public RootBeanDefinition(@Nullable Class<?> beanClass, int autowireMode, boolean dependencyCheck) {
      super();
      setBeanClass(beanClass);
      setAutowireMode(autowireMode);
      if (dependencyCheck && getResolvedAutowireMode() != AUTOWIRE_CONSTRUCTOR) {
         setDependencyCheck(DEPENDENCY_CHECK_OBJECTS);
      }
   }

   /**
    * Create a new RootBeanDefinition for a singleton,
    * providing constructor arguments and property values.
    * @param beanClass the class of the bean to instantiate
    * @param cargs the constructor argument values to apply
    * @param pvs the property values to apply
    */
   public RootBeanDefinition(@Nullable Class<?> beanClass, @Nullable ConstructorArgumentValues cargs,
         @Nullable MutablePropertyValues pvs) {

      super(cargs, pvs);
      setBeanClass(beanClass);
   }

   /**
    * Create a new RootBeanDefinition for a singleton,
    * providing constructor arguments and property values.
    * <p>Takes a bean class name to avoid eager loading of the bean class.
    * @param beanClassName the name of the class to instantiate
    */
   public RootBeanDefinition(String beanClassName) {
      setBeanClassName(beanClassName);
   }

   /**
    * Create a new RootBeanDefinition for a singleton,
    * providing constructor arguments and property values.
    * <p>Takes a bean class name to avoid eager loading of the bean class.
    * @param beanClassName the name of the class to instantiate
    * @param cargs the constructor argument values to apply
    * @param pvs the property values to apply
    */
   public RootBeanDefinition(String beanClassName, ConstructorArgumentValues cargs, MutablePropertyValues pvs) {
      super(cargs, pvs);
      setBeanClassName(beanClassName);
   }

   /**
    * Create a new RootBeanDefinition as deep copy of the given
    * bean definition.
    * @param original the original bean definition to copy from
    */
   public RootBeanDefinition(RootBeanDefinition original) {
      super(original);
      this.decoratedDefinition = original.decoratedDefinition;
      this.qualifiedElement = original.qualifiedElement;
      this.allowCaching = original.allowCaching;
      this.isFactoryMethodUnique = original.isFactoryMethodUnique;
      this.targetType = original.targetType;
      this.factoryMethodToIntrospect = original.factoryMethodToIntrospect;
   }

   /**
    * Create a new RootBeanDefinition as deep copy of the given
    * bean definition.
    * @param original the original bean definition to copy from
    */
   RootBeanDefinition(BeanDefinition original) {
      super(original);
   }

   // 以下是setter & getter定义
   @Override
   public String getParentName() {
      return null;
   }

   @Override
   public void setParentName(@Nullable String parentName) {
      if (parentName != null) {
         throw new IllegalArgumentException("Root bean cannot be changed into a child bean with parent reference");
      }
   }

   /**
    * Register a target definition that is being decorated by this bean definition.
    */
   public void setDecoratedDefinition(@Nullable BeanDefinitionHolder decoratedDefinition) {
      this.decoratedDefinition = decoratedDefinition;
   }

   /**
    * Return the target definition that is being decorated by this bean definition, if any.
    */
   @Nullable
   public BeanDefinitionHolder getDecoratedDefinition() {
      return this.decoratedDefinition;
   }

   /**
    * Specify the {@link AnnotatedElement} defining qualifiers,
    * to be used instead of the target class or factory method.
    * @since 4.3.3
    * @see #setTargetType(ResolvableType)
    * @see #getResolvedFactoryMethod()
    */
   public void setQualifiedElement(@Nullable AnnotatedElement qualifiedElement) {
      this.qualifiedElement = qualifiedElement;
   }

   /**
    * Return the {@link AnnotatedElement} defining qualifiers, if any.
    * Otherwise, the factory method and target class will be checked.
    * @since 4.3.3
    */
   @Nullable
   public AnnotatedElement getQualifiedElement() {
      return this.qualifiedElement;
   }

   /**
    * Specify a generics-containing target type of this bean definition, if known in advance.
    * @since 4.3.3
    */
   public void setTargetType(ResolvableType targetType) {
      this.targetType = targetType;
   }

   /**
    * Specify the target type of this bean definition, if known in advance.
    * @since 3.2.2
    */
   public void setTargetType(@Nullable Class<?> targetType) {
      this.targetType = (targetType != null ? ResolvableType.forClass(targetType) : null);
   }

   /**
    * Return the target type of this bean definition, if known
    * (either specified in advance or resolved on first instantiation).
    * @since 3.2.2
    */
   @Nullable
   public Class<?> getTargetType() {
      if (this.resolvedTargetType != null) {
         return this.resolvedTargetType;
      }
      ResolvableType targetType = this.targetType;
      return (targetType != null ? targetType.resolve() : null);
   }

   /**
    * Return a {@link ResolvableType} for this bean definition,
    * either from runtime-cached type information or from configuration-time
    * {@link #setTargetType(ResolvableType)} or {@link #setBeanClass(Class)},
    * also considering resolved factory method definitions.
    * @since 5.1
    * @see #setTargetType(ResolvableType)
    * @see #setBeanClass(Class)
    * @see #setResolvedFactoryMethod(Method)
    */
   @Override
   public ResolvableType getResolvableType() {
      ResolvableType targetType = this.targetType;
      if (targetType != null) {
         return targetType;
      }
      ResolvableType returnType = this.factoryMethodReturnType;
      if (returnType != null) {
         return returnType;
      }
      Method factoryMethod = this.factoryMethodToIntrospect;
      if (factoryMethod != null) {
         return ResolvableType.forMethodReturnType(factoryMethod);
      }
      return super.getResolvableType();
   }

   /**
    * Determine preferred constructors to use for default construction, if any.
    * Constructor arguments will be autowired if necessary.
    * @return one or more preferred constructors, or {@code null} if none
    * (in which case the regular no-arg default constructor will be called)
    * @since 5.1
    */
   @Nullable
   public Constructor<?>[] getPreferredConstructors() {
      return null;
   }

   /**
    * Specify a factory method name that refers to a non-overloaded method.
    */
   public void setUniqueFactoryMethodName(String name) {
      Assert.hasText(name, "Factory method name must not be empty");
      setFactoryMethodName(name);
      this.isFactoryMethodUnique = true;
   }

   /**
    * Specify a factory method name that refers to an overloaded method.
    * @since 5.2
    */
   public void setNonUniqueFactoryMethodName(String name) {
      Assert.hasText(name, "Factory method name must not be empty");
      setFactoryMethodName(name);
      this.isFactoryMethodUnique = false;
   }

   /**
    * Check whether the given candidate qualifies as a factory method.
    */
   public boolean isFactoryMethod(Method candidate) {
      return candidate.getName().equals(getFactoryMethodName());
   }

   /**
    * Set a resolved Java Method for the factory method on this bean definition.
    * @param method the resolved factory method, or {@code null} to reset it
    * @since 5.2
    */
   public void setResolvedFactoryMethod(@Nullable Method method) {
      this.factoryMethodToIntrospect = method;
   }

   /**
    * Return the resolved factory method as a Java Method object, if available.
    * @return the factory method, or {@code null} if not found or not resolved yet
    */
   @Nullable
   public Method getResolvedFactoryMethod() {
      return this.factoryMethodToIntrospect;
   }

   public void registerExternallyManagedConfigMember(Member configMember) {
      synchronized (this.postProcessingLock) {
         if (this.externallyManagedConfigMembers == null) {
            this.externallyManagedConfigMembers = new HashSet<>(1);
         }
         this.externallyManagedConfigMembers.add(configMember);
      }
   }

   public boolean isExternallyManagedConfigMember(Member configMember) {
      synchronized (this.postProcessingLock) {
         return (this.externallyManagedConfigMembers != null &&
               this.externallyManagedConfigMembers.contains(configMember));
      }
   }

   public void registerExternallyManagedInitMethod(String initMethod) {
      synchronized (this.postProcessingLock) {
         if (this.externallyManagedInitMethods == null) {
            this.externallyManagedInitMethods = new HashSet<>(1);
         }
         this.externallyManagedInitMethods.add(initMethod);
      }
   }

   public boolean isExternallyManagedInitMethod(String initMethod) {
      synchronized (this.postProcessingLock) {
         return (this.externallyManagedInitMethods != null &&
               this.externallyManagedInitMethods.contains(initMethod));
      }
   }

   public void registerExternallyManagedDestroyMethod(String destroyMethod) {
      synchronized (this.postProcessingLock) {
         if (this.externallyManagedDestroyMethods == null) {
            this.externallyManagedDestroyMethods = new HashSet<>(1);
         }
         this.externallyManagedDestroyMethods.add(destroyMethod);
      }
   }

   public boolean isExternallyManagedDestroyMethod(String destroyMethod) {
      synchronized (this.postProcessingLock) {
         return (this.externallyManagedDestroyMethods != null &&
               this.externallyManagedDestroyMethods.contains(destroyMethod));
      }
   }


   @Override
   public RootBeanDefinition cloneBeanDefinition() {
      return new RootBeanDefinition(this);
   }

   @Override
   public boolean equals(@Nullable Object other) {
      return (this == other || (other instanceof RootBeanDefinition && super.equals(other)));
   }

   @Override
   public String toString() {
      return "Root bean: " + super.toString();
   }

}

 

  • ChildBeanDefinition

// 该类继承自 AbstractBeanDefinition。其相当于一个子类,不可以单独存在,必须依赖一个父 BeanDetintion,构造 ChildBeanDefinition 时,
// 通过构造方法传入父 BeanDetintion 的名称或通过 setParentName 设置父名称。它可以从父类继承方法参数、属性值,并可以重写父类的方法,
// 同时也可以增加新的属性或者方法。若重新定义 init 方法,destroy 方法或者静态工厂方法,ChildBeanDefinition 会重写父类的设置。
@SuppressWarnings("serial")
public class ChildBeanDefinition extends AbstractBeanDefinition {

   // 父BeanDefinition名称
   @Nullable
   private String parentName;

   // 以下是构造器和setter getter方法

   /**
    * Create a new ChildBeanDefinition for the given parent, to be
    * configured through its bean properties and configuration methods.
    * @param parentName the name of the parent bean
    * @see #setBeanClass
    * @see #setScope
    * @see #setConstructorArgumentValues
    * @see #setPropertyValues
    */
   public ChildBeanDefinition(String parentName) {
      super();
      this.parentName = parentName;
   }

   /**
    * Create a new ChildBeanDefinition for the given parent.
    * @param parentName the name of the parent bean
    * @param pvs the additional property values of the child
    */
   public ChildBeanDefinition(String parentName, MutablePropertyValues pvs) {
      super(null, pvs);
      this.parentName = parentName;
   }

   /**
    * Create a new ChildBeanDefinition for the given parent.
    * @param parentName the name of the parent bean
    * @param cargs the constructor argument values to apply
    * @param pvs the additional property values of the child
    */
   public ChildBeanDefinition(
         String parentName, ConstructorArgumentValues cargs, MutablePropertyValues pvs) {

      super(cargs, pvs);
      this.parentName = parentName;
   }

   /**
    * Create a new ChildBeanDefinition for the given parent,
    * providing constructor arguments and property values.
    * @param parentName the name of the parent bean
    * @param beanClass the class of the bean to instantiate
    * @param cargs the constructor argument values to apply
    * @param pvs the property values to apply
    */
   public ChildBeanDefinition(
         String parentName, Class<?> beanClass, ConstructorArgumentValues cargs, MutablePropertyValues pvs) {

      super(cargs, pvs);
      this.parentName = parentName;
      setBeanClass(beanClass);
   }

   /**
    * Create a new ChildBeanDefinition for the given parent,
    * providing constructor arguments and property values.
    * Takes a bean class name to avoid eager loading of the bean class.
    * @param parentName the name of the parent bean
    * @param beanClassName the name of the class to instantiate
    * @param cargs the constructor argument values to apply
    * @param pvs the property values to apply
    */
   public ChildBeanDefinition(
         String parentName, String beanClassName, ConstructorArgumentValues cargs, MutablePropertyValues pvs) {

      super(cargs, pvs);
      this.parentName = parentName;
      setBeanClassName(beanClassName);
   }

   /**
    * Create a new ChildBeanDefinition as deep copy of the given
    * bean definition.
    * @param original the original bean definition to copy from
    */
   public ChildBeanDefinition(ChildBeanDefinition original) {
      super(original);
   }


   @Override
   public void setParentName(@Nullable String parentName) {
      this.parentName = parentName;
   }

   @Override
   @Nullable
   public String getParentName() {
      return this.parentName;
   }

   @Override
   public void validate() throws BeanDefinitionValidationException {
      super.validate();
      if (this.parentName == null) {
         throw new BeanDefinitionValidationException("'parentName' must be set in ChildBeanDefinition");
      }
   }


   @Override
   public AbstractBeanDefinition cloneBeanDefinition() {
      return new ChildBeanDefinition(this);
   }

   @Override
   public boolean equals(@Nullable Object other) {
      if (this == other) {
         return true;
      }
      if (!(other instanceof ChildBeanDefinition)) {
         return false;
      }
      ChildBeanDefinition that = (ChildBeanDefinition) other;
      return (ObjectUtils.nullSafeEquals(this.parentName, that.parentName) && super.equals(other));
   }

   @Override
   public int hashCode() {
      return ObjectUtils.nullSafeHashCode(this.parentName) * 29 + super.hashCode();
   }

   @Override
   public String toString() {
      return "Child bean with parent '" + this.parentName + "': " + super.toString();
   }

}

 

  • GenericBeanDefinition

// GenericBeanDefinition同样继承了 AbstractBeanDefinition。它用来表示一个普通的 Bean,没特别的作用。
// GenericBeanDefinition 是 Spring 2.5 以后新引入的 BeanDefinition,是 ChildBeanDefinition 更好的替代者,它同样可以
// 通过 setParentName 方法设置父 BeanDefinition。
// 和ChildBeanDefinition一样,他其相当于一个子类,不可以单独存在,必须依赖一个父 BeanDetintion,构造 ChildBeanDefinition 时,
// 通过构造方法传入父 BeanDetintion 的名称或通过 setParentName 设置父名称。
@SuppressWarnings("serial")
public class GenericBeanDefinition extends AbstractBeanDefinition {

   // 父BeanDefinition名称
   @Nullable
   private String parentName;

   // 以下是构造器和setter getter方法定义
   /**
    * Create a new GenericBeanDefinition, to be configured through its bean
    * properties and configuration methods.
    * @see #setBeanClass
    * @see #setScope
    * @see #setConstructorArgumentValues
    * @see #setPropertyValues
    */
   public GenericBeanDefinition() {
      super();
   }

   /**
    * Create a new GenericBeanDefinition as deep copy of the given
    * bean definition.
    * @param original the original bean definition to copy from
    */
   public GenericBeanDefinition(BeanDefinition original) {
      super(original);
   }

   @Override
   public void setParentName(@Nullable String parentName) {
      this.parentName = parentName;
   }

   @Override
   @Nullable
   public String getParentName() {
      return this.parentName;
   }

   @Override
   public AbstractBeanDefinition cloneBeanDefinition() {
      return new GenericBeanDefinition(this);
   }

   @Override
   public boolean equals(@Nullable Object other) {
      if (this == other) {
         return true;
      }
      if (!(other instanceof GenericBeanDefinition)) {
         return false;
      }
      GenericBeanDefinition that = (GenericBeanDefinition) other;
      return (ObjectUtils.nullSafeEquals(this.parentName, that.parentName) && super.equals(other));
   }

   @Override
   public String toString() {
      if (this.parentName != null) {
         return "Generic bean with parent '" + this.parentName + "': " + super.toString();
      }
      return "Generic bean: " + super.toString();
   }
}

 

 


Pt2 循环依赖

Pt2.1 什么是循环依赖

循环依赖是指,A 依赖 B,B 又依赖 A,它们之间形成了循环依赖。或者是 A 依赖 B,B 依赖 C,C 又依 赖 A。

它们之间的依赖关系如下:

伪代码形式如下:

public class ClassA  {
    // ClassA中依赖ClassB
    @Autowired
    private ClassB classB;  
}

public class ClassB  {
    // ClassB中依赖ClassA
    @Autowired
    private ClassA classA; 
}

 

这就像在并发中,两个线程都拿到了对方需要的锁,互相等待形成死循环是同样道理。死锁是在编码期通过代码申请来预防互相等待的场景,但是Bean的循环依赖确实不可避免的场景,不能因为已经有了A依赖B,就不允许B使用A对象。

那如何解决循环依赖的问题呢?我们从Bean对象的初始化过程开始分析。

 


Pt2.2 Bean的初始化过程

在解决Singleton Bean的循环依赖前,我们先来看看Singleton Bean的初始化过程。

 

通常单例Bean的初始化过程,可以分为三个步骤:

  1. createBeanInstance:实例化,也就是调用对象的构造器实例化对象。实例化就完成内存地址的分配,有了固定的“身份证”;

  2. populateBean:填充属性,这一步主要是多bean的依赖属性进行填充,也就是DI的核心;

  3. initializeBean:调用spring xml中的init 方法,也包括BeanPostProcessor中自定义的逻辑。

Bean的创建过程中,初始化完成才能被缓存到容器中,导致循环依赖无法解决。那如果提前暴露Bean对象呢?

 


Pt2.3 二级缓存

我们知道,对象间依赖是持有其它对象的内存地址,而当对象实例化完成(即第一步,完成构造器执行)后就获得了内存对象地址,并且在后续的创建过程中不会改变内存地址,那我们可以提前暴露对象(内存地址)到容器中,来解决循环依赖的死循环问题。

 

但是,此时的对象还没有完全完成创建过程,属于不完整的对象,无法像真正的对象一样执行相关逻辑,所以要有所区分,要用不同的容器来缓存两种对象。

// 一级缓存,缓存已经真正完成创建过程的单例对象,该缓存key = beanName, value = bean;
// 这里的bean是已经创建完成的,该bean经历过实例化->属性填充->初始化以及各类的后置处理。因此,一旦需要获取bean时,我们第一时间就会寻找一级缓存
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<String, Object>(256);

// 二级缓存,对象没有完成所有创建流程,可能只执行了构造器逻辑。被提前暴露是为了解决循环依赖问题。该缓存key = beanName, value = bean;
// 跟一级缓存的区别在于,该缓存所获取到的bean是提前曝光出来的,是还没创建完成的。也就是说获取到的bean只能确保已经进行了实例化,但是属性填充跟初始化肯定还没有做完,因此该bean还没创建完成,仅仅能作为指针提前曝光,被其他bean所引用
private final Map<String, Object> earlySingletonObjects = new HashMap<String, Object>(16);

 

二级缓存作用是:暴露早期对象,为了将成熟bean和纯净bean 分离。解决循环依赖问题,也防止多线程环境下,读取到了不完整的Bean去执行真正逻辑。

还有一点关于bean的Aop动态代理的问题,我们都知道Bean的aop动态代理创建是在初始化之后,但是循环依赖的Bean如果使用了AOP。 那无法等到解决完循环依赖再创建动态代理, 因为这个时候已经注入属性。 所以如果循环依赖的Bean使用了aop,需要提前创建aop。

  1. 如果没有循环依赖的话,在bean初始化完成后创建动态代理

  2. 如果有循环依赖,在bean实例化之后创建

 


Pt2.4 三级缓存

存在的意义?

有个很重要的问题是,既然二级缓存已经能够提交暴露Bean对象,用于解决循环依赖的问题,那为什么又衍生出三级缓存呢?意义在哪里呢?

 

在上面的介绍中,我们已经展示了两个对象之间互相依赖的场景的解决方案,但是忽略了Spring一个重要的特性——AOP。

A、B互相依赖,同时他们都有AOP配置,最终被容器管理的是Bean的AOP代理类对象,所以他们互相持有的也应该是对方的AOP代理类对象。假设没有三级缓存,A对象实例化,放入二级缓存,然后发现依赖B对象,触发B对象的创建流程。所以此时B对象也实例化,发现依赖A对象,从二级缓存中拿到A对象,但是此时拿到的是A的原生对象,而没有拿到AOP增强的A对象,在实际使用时丢失了AOP的能力。

那实例化之后直接生成AOP代理类不就好了吗?但是此时A对象只是实例化,并没有处理完后续的创建流程,还是不完整的对象,后面需要大量用到原生对象来完成创建过程。

所以就产生了矛盾,这也是三级缓存诞生的原因。我们既需要持有还在创建中的原生bean对象,又要拿到Bean对象被AOP增强的代理类对象。

 

这段描述非常拗口,我们知道,AOP代理类对象是在原生对象完成创建之后生成的。

 

再循环依赖的场景下,又必须要提前暴露还未完成创建的对象,如果有AOP,还需要暴露AOP增强的代理类对象。

 

来看看添加三级缓存的源码:

通过构造器完成Bean实例化之后,就需要判断是否需要将Bean添加到三级缓存中。

// org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean

// 5、添加Bean的三级缓存,用于处理循环依赖的场景。
// 如果当前bean是单例、支持循环依赖、且当前bean正在创建,通过往singletonFactories添加一个objectFactory(三级缓存)。
// 这个三级缓存的对象有两种情况:如果Bean有AOP处理则生成AOP代理类对象,如果Bean没有AOP代理则生成普通Bean对象。生成的对象会被包装秤
//    ObjectFactory对象类型放入三级缓存中,用于在循环依赖时提前暴露代理类对象。
// 这里最核心的还是要处理AOP代理类的情况,因为如果只是单纯的普通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");
   }
   // 1、获取需要暴露的Bean对象;
   // 2、将Bean对象包装成ObjectFactory形式;
   // 3、将ObjectFactory添加到三级缓存中;
   addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}

 

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

这段代码看似比较简单,但是却有三层逻辑。

1. getEarlyBeanReference(beanName, mbd, bean) 获取Bean对象

/**
 * 获取一个可以提前暴露的Bean对象,这里可能是原生bean对象,也可能是bean的代理类对象。
 *
 * @param beanName Bean对象名称
 * @param mbd Bean对象定义(合并的)
 * @param bean 原生的Bean对象
 * @return 提前暴露的 包装了原生Bean对象 ObjectFactory对象
 */
protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
   // 提前暴露(放入三级缓存)的对象exposedObject
   Object exposedObject = bean;

   // 如果有AOP配置,这里会生成Bean对象的AOP代理类对象,exposedObject = bean的AOP代理类对象
   if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
      for (SmartInstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().smartInstantiationAware) {
         exposedObject = bp.getEarlyBeanReference(exposedObject, beanName);
      }
   }

   // 否则exposedObject只是原生的bean对象
   return exposedObject;
}

生成AOP代理类部分暂时不细说,会在AOP部分有介绍,这里只要知道是创建bean的AOP增强代理类。

 

2. lambada表达式

一开始没有看到这个,不明白ObjectFactory的作用,其实这里就是使用无参构造器将获得的Bean对象或者AOP代理对象包装成ObjectFactory对象,然后暴露到三级缓存中。

ObjectFactory只是简单的工厂类,他是对bean对象(普通bean对象或者AOP增强代理对象)的一层代理,通过ObjectFactory可以拿到bean对象。

 

3. addSingletonFactory 添加缓存

// 缓存SingletonFactory信息
protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
   Assert.notNull(singletonFactory, "Singleton factory must not be null");
   synchronized (this.singletonObjects) {
      // 一级缓存不存在,说明没有被创建过
      if (!this.singletonObjects.containsKey(beanName)) {
         // 添加到三级缓存
         this.singletonFactories.put(beanName, singletonFactory);
         // 从二级缓存中移除
         this.earlySingletonObjects.remove(beanName);
         // 记录Bean注册顺序
         this.registeredSingletons.add(beanName);
      }
   }
}

此时我们已经将代理类加入到三级缓存中,别的对象在引用时,也是直接获取代理类的对象引用。

 

三级缓存分别是:

  1. singletonObject:一级缓存,该缓存key = beanName, value = bean;这里的bean是已经创建完成的,该bean经历过实例化->属性填充->初始化以及各类的后置处理。因此,一旦需要获取bean时,我们第一时间就会寻找一级缓存

  2. earlySingletonObjects:二级缓存,该缓存key = beanName, value = bean;这里跟一级缓存的区别在于,该缓存所获取到的bean是提前曝光出来的,是还没创建完成的。也就是说获取到的bean只能确保已经进行了实例化,但是属性填充跟初始化肯定还没有做完,因此该bean还没创建完成,仅仅能作为指针提前曝光,被其他bean所引用

  3. singletonFactories:三级缓存,不是用来存bean的实例,而是用来存函数接口、钩子函数的!该缓存key = beanName, value =beanFactory;在bean实例化完之后,属性填充以及初始化之前,如果允许提前曝光,spring会将实例化后的bean提前曝光,也就是把该bean转换成beanFactory并加入到三级缓存。在需要引用提前曝光对象时再通过singletonFactory.getObject()获取。

 


Pt2.5 Prototype和构造器注入无法解决循环依赖

单例Bean利用三级缓存来解决循环依赖的问题,有两个原因:

  • 一是因为Bean是单例的,只需要创建一次对象,后面就可以从缓存中取出来;

  • 二是字段注入(setter注入)的,可以将构造器执行和属性填充过程分开,以解决循环依赖的问题。

 

Prototype就意味着每次都要去创建对象,无法利用缓存,无法解决循环依赖。

构造器注入是在构造器执行时触发对象引用,无法将实例化和循环依赖的属性填充过程分开,无法解决循环依赖。

 

 


Pt3 DI初始化流程

Pt3.1 寻找DI入口

在开头已经说过,DI存在两个入口,其中一个入口就是getBean方法,我们先从getBean方法中寻找更进一步的入口。

在BeanFactory中定义了一堆getBean():

// Spring IoC容器管理Bean的工厂类
public interface BeanFactory {

	// 根据Bean的名字,获取在IoC容器中得到的Bean的实例。
	Object getBean(String name) throws BeansException;

	// 根据Bean的名字和Class类型,获取在IoC容器中得到的Bean的实例,增加了类型安全验证机制。
	<T> T getBean(String name, Class<T> requiredType) throws BeansException;

	// 根据Bean的名字和参数,获取在IoC容器中得到的Bean的实例。
	Object getBean(String name, Object... args) throws BeansException;

	// 根据Class类型获取IoC容器中的实例
	<T> T getBean(Class<T> requiredType) throws BeansException;

	// 根据Class类型和参数,获取在IoC容器中得到的Bean的实例。
	<T> T getBean(Class<T> requiredType, Object... args) throws BeansException;
    ......
}

 

核心实现在抽象子类中实现,其中doGetBean包含了完整的处理流程:

// org.springframework.beans.factory.support.AbstractBeanFactory#getBean(java.lang.String, java.lang.Object...)
// 获取IoC容器中指定名称和参数的Bean。
@Override
public Object getBean(String name, Object... args) throws BeansException {
   // 真正从IoC容器中获取被管理的Bean是通过doGetBean()来完成。
   return doGetBean(name, null, args, false);
}


// 完成从IoC容器获取Bean的功能,同时会触发DI(核心功能)
@SuppressWarnings("unchecked")
protected <T> T doGetBean(
    String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
    throws BeansException {

    // 1、根据输入参数的名称获取被管理的Bean名称,剥离指定名称中对容器的相关依赖。
    // 如果指定的是别名,将别名转换为规范的Bean名称。
    String beanName = transformedBeanName(name);

    // 返回的Bean实例
    Object bean;

    // 2、从缓存中读取是否已经有被创建过的单例模式的Bean。
    // 对于单例模式的Bean,整个IoC容器只会初始化一次,不需要重复创建。如果在容器中已有指定名称的单例模式的Bean被创建,直接返回已经创建的Bean。
    Object sharedInstance = getSingleton(beanName);
    // sharedInstance不为空表示容器中已经有名称为beanName的Singleton类型的Bean。
    if (sharedInstance != null && args == null) {
        if (logger.isTraceEnabled()) {
            // 指定名称的单例Bean已经存在,但未完全初始化完成。
            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 + "'");
            }
        }

        // 获取给定Bean的实例对象,完成FactoryBean的处理。
        // 注意的是,BeanFactory是管理Bean的工厂,FactoryBean是创建对象的工厂Bean,两者之间有区别。
        bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
    }

    // 到此为止,前面是尝试从缓存中获取已经存在的Singleton Bean,如果不满足条件,则尝试新建该Bean。

    // 3、缓存中没有正在创建的或者已经完成创建的单例模式的Bean
    // 包含两种情况:一种是单例Bean还还没启动创建流程,所以缓存中不存在;另一种是Bean非单例,需要执行创建过程。
    else {
        // 如果存在正在被创建的prototype类型的Bean,则停止本次处理,抛出异常。
        // 如果没有被创建的prototype bean,或者存在已经完成创建的prototype bean,则继续向下处理。
        // 只有存在正在创建的prototype bean才会终止操作,由于循环引用会导致这种情况。
        //
        // 举例来说,A、B互相引用,getBean(A)在进行A实例化过程中,会触发B的实例化操作(DI)。B引用了A,而此时A对象正在creating还
        //   没有结束(因为要完成B的初始化和注入操作),所以B实例化过程中再次调用getBean(A)获取注入属性时,便会触发此处的场景。
        if (isPrototypeCurrentlyInCreation(beanName)) {
            throw new BeanCurrentlyInCreationException(beanName);
        }

        // 4、对IoC容器中是否存在指定名称的BeanDefinition进行检查。
        // 首先检查是否能再当前容器中获取所需的Bean,如果不能则委托当前容器的父容器去查找,如果还是没有则一直沿着容器的继承体系继续查找下去。
        BeanFactory parentBeanFactory = getParentBeanFactory();
        // 当前容器中不存在指定名称的BeanDefinition,且当前容器存在父容器时
        if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
            // 解析指定Bean名称的原始名称
            String nameToLookup = originalBeanName(name);
            if (parentBeanFactory instanceof AbstractBeanFactory) {
                // 通过父容器递归调用doGetBean获取对象实例
                return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
                    nameToLookup, requiredType, args, typeCheckOnly);
            }
            // 委派父容器根据指定名称和参数进行查找
            else if (args != null) {
                // 通过父容器获取Bean实例
                return (T) parentBeanFactory.getBean(nameToLookup, args);
            }
            // 委派父容器根据指定名称和类型进行查找
            else if (requiredType != null) {
                // 通过父容器获取Bean实例
                return parentBeanFactory.getBean(nameToLookup, requiredType);
            }
            // 委派父容器根据指定名称进行查找
            else {
                return (T) parentBeanFactory.getBean(nameToLookup);
            }
        }

        // 如果当前容器中存在指定名称的BeanDefinition时,执行如下操作。
        // 创建的Bean是否需要进行类型验证
        if (!typeCheckOnly) {
            // 5、向容器标记指定的Bean已经被创建。
            markBeanAsCreated(beanName);
        }

        StartupStep beanCreation = this.applicationStartup.start("spring.beans.instantiate")
            .tag("beanName", name);
        try {
            if (requiredType != null) {
                beanCreation.tag("beanType", requiredType::toString);
            }

            // 根据指定Bean名称获取其父级Bean定义,主要解决Bean继承时子类和父类公共属性问题。
            RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
            checkMergedBeanDefinition(mbd, beanName, args);

            // 6、获取当前Bean所有依赖Bean的名称,并完成关系注册和依赖Bean的实例化。
            //    DependsOn是@DependsOn注解所标注的,当前Bean必须等到所有DependsOn Bean全部初始化之后才能初始化。
            String[] dependsOn = mbd.getDependsOn();
            if (dependsOn != null) {

                // 循环处理当前Bean依赖的Bean对象dep
                for (String dep : dependsOn) {
                    // dependsOnBean也依赖beanName,出现循环依赖则报错,相当于死循环。
                    if (isDependent(beanName, dep)) {
                        throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                                                        "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
                    }

                    // 注册两个Bean之间的依赖关系:BeanName依赖dep
                    registerDependentBean(dep, beanName);

                    try {
                        // 先实例化当前Bean的@DependsOn所标注的Bean
                        // 递归调用getBean()获取当前Bean的 依赖Bean的 实例化对象。
                        // 此时,只完成依赖Bean的实例化,还没有真正完成依赖注入。
                        getBean(dep);
                    }
                    catch (NoSuchBeanDefinitionException ex) {
                        throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                                                        "'" + beanName + "' depends on missing bean '" + dep + "'", ex);
                    }
                }
            }

            // 到此为止,Bean创建的准备工作已经完成了,现在执行具体的Bean创建操作。

            // 7、创建单例模式的Bean对象的场景。
            if (mbd.isSingleton()) {
                // 创建真正Bean实例对象
                sharedInstance = getSingleton(beanName, () -> {
                    try {
                        // 创建指定名称的Bean对象(核心逻辑)。
                        return createBean(beanName, mbd, args);
                    }
                    catch (BeansException ex) {
                        // 从IoC容器中清除单例模式的Bean对象
                        destroySingleton(beanName);
                        throw ex;
                    }
                });

                // 根据传参获取给定Bean的相关实例对象。
                bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
            }
            // 8、创建原型模式的Bean对象的场景。
            else if (mbd.isPrototype()) {
                // 原型模式每次都会创建一个新的对象
                Object prototypeInstance = null;
                try {
                    // 标记当前BeanName为创建中状态
                    beforePrototypeCreation(beanName);

                    // 创建指定Prototype类型Bean的实例对象
                    prototypeInstance = createBean(beanName, mbd, args);
                }
                finally {
                    // 将当前beanName从创建中列表中移除
                    afterPrototypeCreation(beanName);
                }

                // 根据传参获取给定Bean的相关实例对象。
                bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
            }
            // 9、要创建的Bean既不是单例模式,也不是原型模式,则根据Bean定义资源中
            else {
                // 获取配置的生命周期scope,选择实例化Bean的合适方法,这种方式在Web应用程序中比较常用,比如request、session、application等。
                String scopeName = mbd.getScope();
                if (!StringUtils.hasLength(scopeName)) {
                    throw new IllegalStateException("No scope name defined for bean ´" + beanName + "'");
                }

                // 如果Bean定义资源中没有配置生命周期范围,则Bean定义不合法。
                Scope scope = this.scopes.get(scopeName);
                if (scope == null) {
                    throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
                }
                try {
                    // 获取指定生命周期范围的Bean实例
                    Object scopedInstance = scope.get(beanName, () -> {
                        // 标记当前BeanName为创建中状态
                        beforePrototypeCreation(beanName);
                        try {
                            // 创建指定Bean的对象实例
                            return createBean(beanName, mbd, args);
                        }
                        finally {
                            // 将当前beanName从创建中列表中移除
                            afterPrototypeCreation(beanName);
                        }
                    });

                    // 获取指定Bean的实例对象
                    bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
                }
                catch (IllegalStateException ex) {
                    throw new ScopeNotActiveException(beanName, scopeName, ex);
                }
            }
        }
        catch (BeansException ex) {
            beanCreation.tag("exception", ex.getClass().toString());
            beanCreation.tag("message", String.valueOf(ex.getMessage()));
            cleanupAfterBeanCreationFailure(beanName);
            throw ex;
        }
        finally {
            beanCreation.end();
        }
    }

    // 至此,已经完成整个Bean对象的创建过程,包括实例化、属性设置和初始化(#init),也包括了FactoryBean的处理,获得了真正定义的Bean对象。

    // 10、对创建的Bean实例对象进行类型检查
    //     指定的Bean类型不为空,且和当前获得的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;
}

doGetBean就是完成DI核心逻辑的方法,里面包含了对多种场景的判断,接下来我们逐步分析doGetBean都在做些什么。

 


Pt3.2 Bean名称解析

分析的代码段:

// 1、根据输入参数的名称获取被管理的Bean名称,剥离指定名称中对容器的相关依赖。
// 如果指定的是别名,将别名转换为规范的Bean名称。
String beanName = transformedBeanName(name);

 

getBean()参数中传入的name可能不是标准的容器管理的Bean名称,也可能是定义的别名,需要解析出Bean在容器中被管理时所对应的规范的Bean名称。

// org.springframework.beans.factory.support.AbstractBeanFactory#transformedBeanName
// 根据指定的名称,转换为被IoC容器管理的Bean的名称,剥离指定名称中跟容器相关的前后缀依赖。
// 如果是别名,则转换为对应的Bean的名称。
protected String transformedBeanName(String name) {
   return canonicalName(BeanFactoryUtils.transformedBeanName(name));
}

 

去除FactoryBean前缀:

// org.springframework.beans.factory.BeanFactoryUtils#transformedBeanName
// 剥离Bean名称对容器的依赖,获取真正被管理的Bean名称
public static String transformedBeanName(String name) {
   Assert.notNull(name, "'name' must not be null");
   if (!name.startsWith(BeanFactory.FACTORY_BEAN_PREFIX)) {
      return name;
   }
   return transformedBeanNameCache.computeIfAbsent(name, beanName -> {
      do {
         beanName = beanName.substring(BeanFactory.FACTORY_BEAN_PREFIX.length());
      }
      while (beanName.startsWith(BeanFactory.FACTORY_BEAN_PREFIX));
      return beanName;
   });
}

 

Spring中可以为Bean定义别名,并且可以嵌套定义多层,比如下面的形式:

<bean id="aliasBean" name="aliasBean1,aliasBean2" class="AliasBean.AliasBean"/>
<alias name="aliasBean" alias="aliasBean1"/>
<alias name="aliasBean1" alias="aliasBean2"/>
<alias name="aliasBean2" alias="aliasBean3"/>

canonicalName的作用就是解析出别名对应的名称,并且能够嵌套处理:

// org.springframework.core.SimpleAliasRegistry#canonicalName
// 根据别名获取被管理的Bean名称
public String canonicalName(String name) {
   // 1、如果当前Bean名称就是标准名称,则不做任何处理。
   String canonicalName = name;

   // 2、根据传入name从别名映射缓存中查询标准名称。
   String resolvedName;
   do {
      resolvedName = this.aliasMap.get(canonicalName);
      if (resolvedName != null) {
         canonicalName = resolvedName;
      }
   } while (resolvedName != null);

   return canonicalName;
}

 


Pt3.3 获取缓存的单例Bean

分析的代码段:

// 2、从缓存中读取是否已经有被创建过的单例模式的Bean。
// 对于单例模式的Bean,整个IoC容器只会初始化一次,不需要重复创建。如果在容器中已有指定名称的单例模式的Bean被创建,直接返回已经创建的Bean。
Object sharedInstance = getSingleton(beanName);

 

IoC容器会缓存Singleton类型的Bean,防止重复构建的场景,prototype类型则不会。所以先从缓存中获取Bean对象,如果已经有创建好的或者创建中的对象,则可以直接拿来用(主要针对Singleton类型)而不用重复创建。

// org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#getSingleton(java.lang.String)

// 一级缓存
// 缓存已经真正完成创建过程的单例对象,该缓存key = beanName, value = bean;
// 这里的bean是已经创建完成的,该bean经历过实例化->属性填充->初始化以及各类的后置处理。
// 因此,一旦需要获取bean时,我们第一时间就会寻找一级缓存
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);

// 二级缓存
// 对象没有完成所有创建流程,可能只执行了构造器逻辑。被提前暴露是为了解决循环依赖问题。该缓存key = beanName, value = bean;
// 跟一级缓存的区别在于,该缓存所获取到的bean是提前曝光出来的,是还没创建完成的。也就是说获取到的bean只能确保已经进行了实例化,但是属性填充
// 跟初始化肯定还没有做完,因此该bean还没创建完成,仅仅能作为指针提前曝光,被其他bean所引用
private final Map<String, Object> earlySingletonObjects = new ConcurrentHashMap<>(16);

// 三级缓存
// 不是用来存bean的实例,而是用来存函数接口、钩子函数的!该缓存key = beanName, value =beanFactory;在bean实例化完
// 之后,属性填充以及初始化之前,如果允许提前曝光,spring会将实例化后的bean提前曝光,也就是把该bean转换成beanFactory并加入到三级缓存。
// 在需要引用提前曝光对象时再通过singletonFactory.getObject()获取。
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);

// 获取指定名称的单例Bean
@Override
@Nullable
public Object getSingleton(String beanName) {
   return getSingleton(beanName, true);
}

// 尝试从多级缓存中获取原生的单例Bean对象。
// allowEarlyReference:是否开启三级缓存
@Nullable
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
    // 1、尝试从一级缓存(已完成对象创建)获取singleton对象
    Object singletonObject = this.singletonObjects.get(beanName);

    // 2、单例对象创建中,但还未完成创建过程,尝试从二级缓存中获取对象。
    if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
        singletonObject = this.earlySingletonObjects.get(beanName);

        // 3、如果一级缓存和二级缓存都没有,并且启用了三级缓存,则从三级缓存获取。
        if (singletonObject == null && allowEarlyReference) {

            // 再次尝试从一级缓存和二级缓存获取,防止并发的情况。
            synchronized (this.singletonObjects) {
                singletonObject = this.singletonObjects.get(beanName);

                if (singletonObject == null) {
                    singletonObject = this.earlySingletonObjects.get(beanName);

                    // 4、 尝试从三级缓存获取对象。
                    if (singletonObject == null) {
                        ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
                        if (singletonFactory != null) {
                            singletonObject = singletonFactory.getObject();

                            // 5、将对象从三级缓存移除,并加入到二级缓存中。
                            this.earlySingletonObjects.put(beanName, singletonObject);
                            this.singletonFactories.remove(beanName);
                        }
                    }
                }
            }
        }
    }
    return singletonObject;
}

多级缓存在前面[循环依赖]部分介绍过。

 


Pt3.4 从FactoryBean获取Bean对象

分析的代码段:

// 获取给定Bean的实例对象,完成FactoryBean的处理。
// 注意的是,BeanFactory是管理Bean的工厂,FactoryBean是创建对象的工厂Bean,两者之间有区别。
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);

 

如果从缓存中获取了不为空的BeanInstance,则说明Singleton Bean已经被实例化处理过。此时需要根据getBean()传入name的类型,解析出客户端真正需要的目标类型的Bean对象。

// org.springframework.beans.factory.support.AbstractBeanFactory#getObjectForBeanInstance

// Spring管理的bean实例分为两类,一类是实现FactoryBean接口的Bean,一类是真正类型的Bean。容器已经得到Bean实例对象,
// 这个对象可能是普通Bean,也可能是FactoryBean。、
// #getObjectForBeanInstance()目的就是获得对应类型的Bean对象,可能是从FactoryBean解析出来的对象,也可能直接是真正的Bean类型。
//   beanInstance:已经获取的对象实例
//   name:客户端传入需要获取的Bean名称
//   beanName:根据name解析的规范化Bean名称
protected Object getObjectForBeanInstance(
      Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {

   // 1、希望获得FactoryBean类型对象的场景。
   // 如果指定name是FactoryBean类型,说明调用本身是想获得FactoryBean容器的引用,则只需要判断实例beanInstance是否是FactoryBean类型的对象,然后返回即可。
   if (BeanFactoryUtils.isFactoryDereference(name)) {
      if (beanInstance instanceof NullBean) {
         return beanInstance;
      }

      // 但获取的Bean实例不是FactoryBean类型则抛出异常。
      if (!(beanInstance instanceof FactoryBean)) {
         throw new BeanIsNotAFactoryException(beanName, beanInstance.getClass());
      }
      if (mbd != null) {
         mbd.isFactoryBean = true;
      }

      // 返回已经获得的FactoryBean类型的实例对象
      return beanInstance;
   }

   // 2、希望获得普通Bean对象的,且已经获得的场景。
   // 如果指定名称name不是FactoryBean的类型,说明调用是想获得真正的Bean实例对象,只需要判定实例beanInstance本身是否是普通Bean对象,然后返回即可。
   if (!(beanInstance instanceof FactoryBean)) {
      return beanInstance;
   }

   // 3、从FactoryBean获取普通Bean对象。
   // 指定名称name不是FactoryBean的类型,说明调用是想获得真正的Bean实例对象,而传入实例beanInstance本身又是FactoryBean类型对象,
   // 则需要从FactoryBean中获得真正的Bean对象。
   Object object = null;
   if (mbd != null) {
      mbd.isFactoryBean = true;
   }
   else {
      // 从BeanFactory缓存中获取指定名称的Bean实例对象
      object = getCachedObjectForFactoryBean(beanName);
   }

   // 4、基于FactoryBean生成普通Bean。
   // FactoryBean缓存中没有数据,表明还没有生成过的记录,则通过FactoryBean生成Bean实例。
   if (object == null) {
      // 将beanInstance转换为FactoryBean
      FactoryBean<?> factory = (FactoryBean<?>) beanInstance;

      // IoC容器中包含指定beanName的定义,则尝试获取该beanName的完整定义mbd(包含基类的属性)
      if (mbd == null && containsBeanDefinition(beanName)) {
         // 从容器中获取指定名称的Bean定义,如果继承了相关类,则合并基类属性
         mbd = getMergedLocalBeanDefinition(beanName);
      }

      // 如果从容器中得到了Bean定义信息,并且BeanDefinition不是虚构的,则让FactoryBean生成Bean实例对象
      // 关于synthetic的意义:是否是合成类(不是应用自定义的,例如生成AOP代理时,会用到某些辅助类,这些辅助类不是应用自定义的,这个就是合成类)。
      // 一般应用程序定义的Bean都是返回false,由Spring合成的返回true。
      // 下面代码:若取到的Bean是自定义的返回false,若是应用自己合成的返回true。
      boolean synthetic = (mbd != null && mbd.isSynthetic());

      // 基于FactoryBean生成Bean(核心逻辑)
      object = getObjectFromFactoryBean(factory, beanName, !synthetic);
   }
   return object;
}

其中涉及如下处理:

  • BeanFactoryUtils.isFactoryDereference:判断name对应的目标类型;

  • getCachedObjectForFactoryBean:从BeanFactory缓存中获取指定名称的Bean实例对象;

  • getObjectFromFactoryBean:基于FactoryBean生成Bean

 

BeanFactoryUtils.isFactoryDereference

判断客户端想要的目标类型

// 判读name是否是FactoryBean对象
public static boolean isFactoryDereference(@Nullable String name) {
   // FACTORY_BEAN_PREFIX开头说明是FactoryBean类型对象。
   return (name != null && name.startsWith(BeanFactory.FACTORY_BEAN_PREFIX));
}

 

getCachedObjectForFactoryBean

从BeanFactory缓存中获取指定名称的Bean实例对象

// org.springframework.beans.factory.support.FactoryBeanRegistrySupport#getCachedObjectForFactoryBean

// 缓存所有通过FactoryBean创建的Bean对象
//  Key:Bean对象的名称
//  Value:Bean对象实例
private final Map<String, Object> factoryBeanObjectCache = new ConcurrentHashMap<>(16);

// 从FactoryBean缓存中获取指定名称的Bean对象
@Nullable
protected Object getCachedObjectForFactoryBean(String beanName) {
	return this.factoryBeanObjectCache.get(beanName);
}

 

getObjectFromFactoryBean

基于FactoryBean实例生成对应的普通Bean对象

// org.springframework.beans.factory.support.FactoryBeanRegistrySupport#getObjectFromFactoryBean
// 基于FactoryBean实例生成对应的普通Bean对象
protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {

   // BeanFactory管理的是单例Bean,且一级缓存中已经包含对应beanName的实例对象。
   if (factory.isSingleton() && containsSingleton(beanName)) {
      // 多线程同步处理
      synchronized (getSingletonMutex()) {

         // 尝试直接从FactoryBean缓存中获取指定名称的Bean对象
         Object object = this.factoryBeanObjectCache.get(beanName);

         // 缓存中没有则生产该对象
         if (object == null) {

            // 通过调用FactoryBean获取对象的方法生成Bean对象
            object = doGetObjectFromFactoryBean(factory, beanName);

            // 有可能当执行doGetObjectFromFactoryBean函数时,别的线程已经正在创建Bean,所以再次从缓存中获取看看有没有其他线程创建的可用实例。
            Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
            // 如果有值,代表已经经过后处理了,可以直接使用
            if (alreadyThere != null) {
               object = alreadyThere;
            }
            else {
               // 没有经过后处理,首如果是用户自己创建的
               if (shouldPostProcess) {
                  // 如果对象还在创建中,没有完成初始化设置,则返回Bean对象,但是不缓存他。
                  if (isSingletonCurrentlyInCreation(beanName)) {
                     return object;
                  }

                  // 单例Bean创建前回调处理,标记为创建中
                  beforeSingletonCreation(beanName);

                  try {
                     // 执行Bean创建逻辑的后处理逻辑
                     object = postProcessObjectFromFactoryBean(object, beanName);
                  }
                  catch (Throwable ex) {
                     throw new BeanCreationException(beanName,
                           "Post-processing of FactoryBean's singleton object failed", ex);
                  }
                  finally {

                     // 单例Bean创建后回调处理,移除创建中状态
                     afterSingletonCreation(beanName);
                  }
               }

               // 如果是单例对象则添加到FactoryBean的缓存中。
               if (containsSingleton(beanName)) {
                  this.factoryBeanObjectCache.put(beanName, object);
               }
            }
         }
         return object;
      }
   }
   // 非单例对象,直接创建Bean实例
   else {
      // 从FactoryBean中生成Bean对象
      Object object = doGetObjectFromFactoryBean(factory, beanName);
      if (shouldPostProcess) {
         try {
            // 执行Bean创建的后置处理
            object = postProcessObjectFromFactoryBean(object, beanName);
         }
         catch (Throwable ex) {
            throw new BeanCreationException(beanName, "Post-processing of FactoryBean's object failed", ex);
         }
      }
      return object;
   }
}

 

1. doGetObjectFromFactoryBean通过FactoryBean获取管理的Bean对象实例

// org.springframework.beans.factory.support.FactoryBeanRegistrySupport#doGetObjectFromFactoryBean
// 通过FactoryBean获取管理的Bean对象实例
private Object doGetObjectFromFactoryBean(FactoryBean<?> factory, String beanName) throws BeanCreationException {
   Object object;
   try {
      if (System.getSecurityManager() != null) {
         AccessControlContext acc = getAccessControlContext();
         try {
            // 调用factory::getObject,生成被管理的Bean对象
            object = AccessController.doPrivileged((PrivilegedExceptionAction<Object>) factory::getObject, acc);
         }
         catch (PrivilegedActionException pae) {
            throw pae.getException();
         }
      }
      else {
         // 真正的获取bean实例对象的代码
         // 里面使用动态代理Proxy.newProxyInstance来进行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);
   }

   // 创建出来实例对象为null,也可能因为Singleton对象正在创建而返回null
   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. Bean创建状态管理

// org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#beforeSingletonCreation
// 单例对象创建前处理,将Bean加入到单例对象创建中的列表
protected void beforeSingletonCreation(String beanName) {
   // this.inCreationCheckExclusions.contains(beanName):beanName不需要检查是否创建中状态,说明不用考虑指定Beanname的创建状态。
   // this.singletonsCurrentlyInCreation.add(beanName):将beanName标记为正在创建中
   if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) {
      throw new BeanCurrentlyInCreationException(beanName);
   }
}

// 单例对象创建后处理, 将Bean从单例对象创建中的列表移除
protected void afterSingletonCreation(String beanName) {
   // this.inCreationCheckExclusions.contains(beanName):beanName不需要检查是否创建中状态,说明不用考虑指定Beanname的创建状态。
   // this.singletonsCurrentlyInCreation.remove(beanName):将BeanName移除创建中状态
   if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.remove(beanName)) {
      throw new IllegalStateException("Singleton '" + beanName + "' isn't currently in creation");
   }
}

 

3. 执行Bean创建的后置处理器

// org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#postProcessObjectFromFactoryBean
// 在完成Bean的初始化操作后,执行后置回调处理BeanPostProcessors。
@Override
protected Object postProcessObjectFromFactoryBean(Object object, String beanName) {
   return applyBeanPostProcessorsAfterInitialization(object, beanName);
}

// 调用BeanPostProcessor的回调方法,执行Bean初始化之后的操作。
@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
    throws BeansException {

    Object result = existingBean;
    // 遍历容器为所创建的Bean添加的所有BeanPostProcessor后置处理器。
    for (BeanPostProcessor processor : getBeanPostProcessors()) {
        // 调用Bean实例所有定义的BeanPostProcessor初始化之后回调操作,完成初始化后的自定义操作。
        Object current = processor.postProcessAfterInitialization(result, beanName);
        if (current == null) {
            return result;
        }
        result = current;
    }
    return result;
}

到此为止,前面是尝试从缓存中获取已经存在的Singleton Bean,如果不满足条件,下面的处理逻辑则尝试新建该Bean。

 


Pt3.5 检查容器中的BeanDefinition

如果没有从缓存中获取BeanInstance,则可能存在两种情况:

  • Bean非单例类型;

  • 单例Bean还未开始创建过程。

这两种情况都是需要执行Bean的创建过程:

  1. 检查负责创建Bean的容器。因为指定名称的Bean可能不是在当前容器中,而是在父容器或者父容器的父容器中,则需要将创建Bean的工作交给具体归属的容器。

  2. 标记Bean的创建状态。防止多线程并发或者循环依赖时多次创建Bean。

  3. 获取MergedBeanDefinition。

 

检查负责创建Bean的容器。因为指定名称的Bean可能不是在当前容器中,而是在父容器或者父容器的父容器中,则需要将创建Bean的工作交给具体归属的容器。

// org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean

// 4、对IoC容器中是否存在指定名称的BeanDefinition进行检查。
// 首先检查是否能再当前容器中获取所需的Bean,如果不能则委托当前容器的父容器去查找,如果还是没有则一直沿着容器的继承体系继续查找下去。
BeanFactory parentBeanFactory = getParentBeanFactory();
// 当前容器中不存在指定名称的BeanDefinition,且当前容器存在父容器时
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
   // 解析指定Bean名称的原始名称
   String nameToLookup = originalBeanName(name);
   if (parentBeanFactory instanceof AbstractBeanFactory) {
      // 通过父容器递归调用doGetBean获取对象实例
      return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
            nameToLookup, requiredType, args, typeCheckOnly);
   }
   // 委派父容器根据指定名称和参数进行查找
   else if (args != null) {
      // 通过父容器获取Bean实例
      return (T) parentBeanFactory.getBean(nameToLookup, args);
   }
   // 委派父容器根据指定名称和类型进行查找
   else if (requiredType != null) {
      // 通过父容器获取Bean实例
      return parentBeanFactory.getBean(nameToLookup, requiredType);
   }
   // 委派父容器根据指定名称进行查找
   else {
      return (T) parentBeanFactory.getBean(nameToLookup);
   }
}

 

标记Bean的创建状态。防止多线程并发或者循环依赖时多次创建Bean。

// org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean

// 缓存已经至少完成一次实例化的Bean名称
private final Set<String> alreadyCreated = Collections.newSetFromMap(new ConcurrentHashMap<>(256));

// 如果当前容器中存在指定名称的BeanDefinition时,执行如下操作。
// 创建的Bean是否需要进行类型验证
if (!typeCheckOnly) {
   // 5、向容器标记指定的Bean已经被创建。
   markBeanAsCreated(beanName);
}

// 将指定名称bean标记为已创建
protected void markBeanAsCreated(String beanName) {
    // 通过两次判断,既能够做到线程安全,又可以最大限度减少触发同步代码段执行锁,提升执行效率。
    if (!this.alreadyCreated.contains(beanName)) {
        synchronized (this.mergedBeanDefinitions) {
            if (!this.alreadyCreated.contains(beanName)) {
                // Let the bean definition get re-merged now that we're actually creating
                // the bean... just in case some of its metadata changed in the meantime.
                clearMergedBeanDefinition(beanName);
                this.alreadyCreated.add(beanName);
            }
        }
    }
}

 

获取MergedBeanDefinition。

// org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean

// 根据指定Bean名称获取其父级Bean定义,主要解决Bean继承时子类和父类公共属性问题。
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);

 


Pt3.6 检查DependsOn关系

分析的代码段:

// 6、 ,并完成关系注册和依赖Bean的实例化。
//    DependsOn是@DependsOn注解所标注的,当前Bean必须等到所有DependsOn Bean全部初始化之后才能初始化。
String[] dependsOn = mbd.getDependsOn();

 

目标Bean初始化之前,可能存在依赖的Bean,那需要找到依赖的Bean先进行初始化,并且记录两个Bean的依赖关系。

// org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean

// 6、 ,并完成关系注册和依赖Bean的实例化。
// DependsOn是@DependsOn注解所标注的,当前Bean必须等到所有DependsOn Bean全部初始化之后才能初始化。
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {

   // 循环处理当前Bean依赖的Bean对象dep
   for (String dep : dependsOn) {
      // dependsOnBean也依赖beanName,出现循环依赖则报错,相当于死循环。
      if (isDependent(beanName, dep)) {
         throw new BeanCreationException(mbd.getResourceDescription(), beanName,
               "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
      }

      // 注册两个Bean之间的依赖关系:BeanName依赖dep
      registerDependentBean(dep, beanName);

      try {
         // 先实例化当前Bean的@DependsOn所标注的Bean
         // 递归调用getBean()获取当前Bean的 依赖Bean的 实例化对象。
         // 此时,只完成依赖Bean的实例化,还没有真正完成依赖注入。
         getBean(dep);
      }
      catch (NoSuchBeanDefinitionException ex) {
         throw new BeanCreationException(mbd.getResourceDescription(), beanName,
               "'" + beanName + "' depends on missing bean '" + dep + "'", ex);
      }
   }
}

 

依赖关系判断:

// org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#isDependent(java.lang.String, java.lang.String)

// 指定的bean与目前已经注册的依赖这个指定的bean的所有bean的依赖关系的缓存(依赖我的)
// Key:当前Bean名称
// Value:依赖当前Bean的所有其他Bean名称集合
private final Map<String, Set<String>> dependentBeanMap = new ConcurrentHashMap<>(64);

// 判断dependentBeanName是否依赖beanName
protected boolean isDependent(String beanName, String dependentBeanName) {
   synchronized (this.dependentBeanMap) {
      return isDependent(beanName, dependentBeanName, null);
   }
}

 

注册两个Bean之间的依赖关系:

// 注册两个Bean之间的依赖关系
// beanName 被别人依赖的Bean名称
// dependentBeanName 依赖别人的Bean名称
public void registerDependentBean(String beanName, String dependentBeanName) {
   // 获取beanName对应的被容器管理的名称
   String canonicalName = canonicalName(beanName);

   // 将dependentBeanName标记为是依赖beanName的关系
   synchronized (this.dependentBeanMap) {
      Set<String> dependentBeans =
            this.dependentBeanMap.computeIfAbsent(canonicalName, k -> new LinkedHashSet<>(8));
      if (!dependentBeans.add(dependentBeanName)) {
         return;
      }
   }

   // 将beanName标记为是dependentBeanName依赖的关系
   synchronized (this.dependenciesForBeanMap) {
      Set<String> dependenciesForBean =
            this.dependenciesForBeanMap.computeIfAbsent(dependentBeanName, k -> new LinkedHashSet<>(8));
      dependenciesForBean.add(canonicalName);
   }
}

到此为止,Bean创建的准备工作已经完成了,下面执行具体的Bean创建操作。

 


Pt3.7 创建单例Bean对象

代码处理核心是createBean(),这部分逻辑非常复杂,后面会单独拿出来分析,这里主要是了解Singleton Bean的创建过程:

  1. 判断是否是Singleton Bean;

  2. 基于createBean逻辑生成BeanInstance;

  3. getSingleton从缓存中获取创建的BeanInstance;

  4. 如果发生异常则需要销毁Singleton。因为Singleton Bean在容器中是共享的,没有被完整创建的Bean如果被其他线程拿去操作会出问题;

  5. 从BeanInstance获取目标Bean对象;

 

源码如下:

// 7、创建单例模式的Bean对象的场景。
if (mbd.isSingleton()) {
   // 创建真正Bean实例对象
   sharedInstance = getSingleton(beanName, () -> {
      try {
         // 创建指定名称的Bean对象(核心逻辑)。
         return createBean(beanName, mbd, args);
      }
      catch (BeansException ex) {
         // 从IoC容器中清除单例模式的Bean对象
         destroySingleton(beanName);
         throw ex;
      }
   });

   // 根据传参获取给定Bean的相关实例对象。
   bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}

 

mbd.isSingleton():判断是否是单例Bean

没有指定scope或者scope=singleton时,当做单例Bean处理。

// org.springframework.beans.factory.support.AbstractBeanDefinition#isSingleton
public static final String SCOPE_DEFAULT = "";

@Override
public boolean isSingleton() {
   return SCOPE_SINGLETON.equals(this.scope) || SCOPE_DEFAULT.equals(this.scope);
}

 

createBean():创建Bean对象

后面会重点分析,这里只要知道createBean是完成创建Bean的核心逻辑。

 

getSingleton:获取Bean对象

// 从FactoryBean中获取普通Bean对象
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
   Assert.notNull(beanName, "Bean name must not be null");

   synchronized (this.singletonObjects) {
      // 1、先从一级缓存获取查找Bean对象
      Object singletonObject = this.singletonObjects.get(beanName);
      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 + "'");
         }

         // 2、标记当前Bean正在创建中
         beforeSingletonCreation(beanName);
         // newSingleton为true,会将当前Bean加入缓存中
         boolean newSingleton = false;
         // 记录被抑制的异常信息
         boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
         if (recordSuppressedExceptions) {
            this.suppressedExceptions = new LinkedHashSet<>();
         }

         try {
            // 通过FactoryBean创建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;
            }
            // 将Bean从单例对象创建中的列表移除
            afterSingletonCreation(beanName);
         }

         if (newSingleton) {
            // 将完成实例化的Bean加入到缓存中
            addSingleton(beanName, singletonObject);
         }
      }
      return singletonObject;
   }
}

 

获取指定名称的Bean对象,同时将获取的Bean对象添加到缓存中(只有Singleton 类型)。

// org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#addSingleton
// 将完成实例化的单例Bean加入到缓存中
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);
   }
}

 

getObjectForBeanInstance

getObjectForBeanInstance核心逻辑在[Pt3.4]中介绍过。

 


Pt3.8 创建原型Bean对象

原型Bean相对比单例要简单,不需要考虑缓存的问题,也是通过createBean完成Bean创建。

 

核心createBean会在后面介绍,getObjectForBeanInstance在[Pt3.4]已经介绍过。先来看看原型Bean创建过程:

// org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean
// 8、创建原型模式的Bean对象的场景。
else if (mbd.isPrototype()) {
   // 原型模式每次都会创建一个新的对象
   Object prototypeInstance = null;
   try {
      // 标记当前BeanName为创建中状态
      beforePrototypeCreation(beanName);

      // 创建指定Prototype类型Bean的实例对象
      prototypeInstance = createBean(beanName, mbd, args);
   }
   finally {
      // 将当前beanName从创建中列表中移除
      afterPrototypeCreation(beanName);
   }

   // 根据传参获取给定Bean的相关实例对象。
   bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}

 

// org.springframework.beans.factory.support.AbstractBeanFactory#beforePrototypeCreation

// 在Prototype类型Bean被创建前,将Bean标记为创建中
@SuppressWarnings("unchecked")
protected void beforePrototypeCreation(String beanName) {
   // 标记当前BeanName正在被创建
   Object curVal = this.prototypesCurrentlyInCreation.get();
   if (curVal == null) {
      this.prototypesCurrentlyInCreation.set(beanName);
   }
   // 将所有正在被创建的Prototype类型的BeanName拼接成Set对象缓存起来
   else if (curVal instanceof String) {
      Set<String> beanNameSet = new HashSet<>(2);
      beanNameSet.add((String) curVal);
      beanNameSet.add(beanName);
      this.prototypesCurrentlyInCreation.set(beanNameSet);
   }
   else {
      Set<String> beanNameSet = (Set<String>) curVal;
      beanNameSet.add(beanName);
   }
}

// 将当前beanName从创建中列表中移除
@SuppressWarnings("unchecked")
protected void afterPrototypeCreation(String beanName) {
    Object curVal = this.prototypesCurrentlyInCreation.get();
    if (curVal instanceof String) {
        this.prototypesCurrentlyInCreation.remove();
    }
    else if (curVal instanceof Set) {
        Set<String> beanNameSet = (Set<String>) curVal;
        beanNameSet.remove(beanName);
        if (beanNameSet.isEmpty()) {
            this.prototypesCurrentlyInCreation.remove();
        }
    }
}

 


Pt3.9 创建其他Scope类型Bean对象

和上面两个没有太大的区别,核心逻辑都是在createBean和getObjectForBeanInstance完成的。

// org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean

// 9、要创建的Bean既不是单例模式,也不是原型模式,则根据Bean定义资源中
// 获取配置的生命周期scope,选择实例化Bean的合适方法,这种方式在Web应用程序中比较常用,比如request、session、application等。
else {
    String scopeName = mbd.getScope();
    if (!StringUtils.hasLength(scopeName)) {
        throw new IllegalStateException("No scope name defined for bean ´" + beanName + "'");
    }

    // 如果Bean定义资源中没有配置生命周期范围,则Bean定义不合法。
    Scope scope = this.scopes.get(scopeName);
    if (scope == null) {
        throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
    }
    try {
        // 获取指定生命周期范围的Bean实例
        Object scopedInstance = scope.get(beanName, () -> {
            // 标记当前BeanName为创建中状态
            beforePrototypeCreation(beanName);
            try {
                // 创建指定Bean的对象实例
                return createBean(beanName, mbd, args);
            }
            finally {
                // 将当前beanName从创建中列表中移除
                afterPrototypeCreation(beanName);
            }
        });

        // 获取指定Bean的实例对象
        bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
    }
    catch (IllegalStateException ex) {
        throw new ScopeNotActiveException(beanName, scopeName, ex);
    }
}

 


Pt3.10 Bean对象类型检查

创建流程的最后一步是对Bean对象的类型进行检查,比较简单。

// 10、对创建的Bean实例对象进行类型检查
//     指定的Bean类型不为空,且和当前获得的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());
   }
}

到此为止,整个Bean对象的创建过程(创建对象、填充属性和对象初始化)都已经完成了,且根据不同类型Scope都有针对性的处理。

接下来回过头,从createBean()中分析Bean对象创建的过程。

 

 


Pt4 Bean的创建流程

Pt4.1 Bean创建入口

Bean真正创建的入口是从createBean开始的,直接看源码吧,还是比较清晰的。

// DI的核心方法,完成Bean对象创建的整个流程,包括实例化、属性设置、初始化(#init),返回完成可以被使用的对象。
// String beanName:要创建的Bean名称
// RootBeanDefinition mbd:合并基类属性后的Bean定义信息
// @Nullable Object[] args:Bean初始化参数设置
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
      throws BeanCreationException {

   // Debug日志处理,应用中可以参考这种模式,从而在异常时改变logger级别就可以输出更加详细的日志信息。
   if (logger.isTraceEnabled()) {
      logger.trace("Creating instance of bean '" + beanName + "'");
   }

   // mbd是合并了基类属性的完整BeanDefinition。
   // mbdToUse克隆mbd,因为mbd是共享的合并基类信息的BeanDefinition,为了防止程序中存在动态解析改变了原有共享的BeanDefinition。
   RootBeanDefinition mbdToUse = mbd;

   // 1、解析获得Bean对应的BeanClass和BeanDefinition。
   // BeanClass是在xml标签上定义<bean/>是标记的class属性,配置了类的包名和类名。
   Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
   if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
      mbdToUse = new RootBeanDefinition(mbd);
      mbdToUse.setBeanClass(resolvedClass);
   }

   // 2、验证以及准备BeanDefinition中需要覆盖的方法
   try {
      mbdToUse.prepareMethodOverrides();
   }
   catch (BeanDefinitionValidationException ex) {
      throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
            beanName, "Validation of method overrides failed", ex);
   }

   try {
      // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
      // 3、如果Bean配置了BeanPostProcessor处理器,则返回一个真实Bean对象的代理。
      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 {
      // 4、创建Bean的入口
      Object beanInstance = doCreateBean(beanName, mbdToUse, args);
      if (logger.isTraceEnabled()) {
         logger.trace("Finished creating instance of bean '" + beanName + "'");
      }
      return beanInstance;
   }
   catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
      // A previously detected exception with proper bean creation context already,
      // or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
      throw ex;
   }
   catch (Throwable ex) {
      throw new BeanCreationException(
            mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
   }
}

 


Pt4.2 获取BeanClass

从BeanDefinition中解析得到BeanClass。

// org.springframework.beans.factory.support.AbstractBeanFactory#resolveBeanClass

// 为指定的BeanDefinition解析获得BeanClass,将获得的BeanClass解析为Class引用。
// BeanClass是在xml标签上定义<bean/>是标记的class属性,配置了类的包名和类名。
@Nullable
protected Class<?> resolveBeanClass(RootBeanDefinition mbd, String beanName, Class<?>... typesToMatch)
      throws CannotLoadBeanClassException {

   try {
      // BeanDefinition制定了BeanClass类型,则直接返回。
      if (mbd.hasBeanClass()) {
         return mbd.getBeanClass();
      }

      if (System.getSecurityManager() != null) {
         return AccessController.doPrivileged((PrivilegedExceptionAction<Class<?>>)
               () -> doResolveBeanClass(mbd, typesToMatch), getAccessControlContext());
      }
      else {
         // 获取mbd配置的BeanClass,将BeanClass解析为Class对象,并将解析后的Class对象缓存在mdb中以备将来使用
         return doResolveBeanClass(mbd, typesToMatch);
      }
   }
   catch (PrivilegedActionException pae) {
      ClassNotFoundException ex = (ClassNotFoundException) pae.getException();
      throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), ex);
   }
   catch (ClassNotFoundException ex) {
      throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), ex);
   }
   catch (LinkageError err) {
      throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), err);
   }
}


// 获取mbd配置的BeanClass,将BeanClass解析为Class对象,并将解析后的Class对象缓存在mdb中以备将来使用
@Nullable
private Class<?> doResolveBeanClass(RootBeanDefinition mbd, Class<?>... typesToMatch)
      throws ClassNotFoundException {

   //获取该工厂的加载bean用的类加载器
   ClassLoader beanClassLoader = getBeanClassLoader();

   // 初始化动态类加载器为该工厂的加载bean用的类加载器,如果该工厂有临时类加载器器时,该动态类加载器就是该工厂的临时类加载器
   ClassLoader dynamicLoader = beanClassLoader;

   // 表示mdb的配置的bean类名需要重新被dynameicLoader加载的标记,默认不需要
   boolean freshResolve = false;

   //如果有传入要匹配的类型
   if (!ObjectUtils.isEmpty(typesToMatch)) {
      // When just doing type checks (i.e. not creating an actual instance yet),
      // use the specified temporary class loader (e.g. in a weaving scenario).
      ClassLoader tempClassLoader = getTempClassLoader();
      if (tempClassLoader != null) {
         dynamicLoader = tempClassLoader;
         freshResolve = true;
         if (tempClassLoader instanceof DecoratingClassLoader) {
            DecoratingClassLoader dcl = (DecoratingClassLoader) tempClassLoader;
            for (Class<?> typeToMatch : typesToMatch) {
               dcl.excludeClass(typeToMatch.getName());
            }
         }
      }
   }

   String className = mbd.getBeanClassName();
   if (className != null) {
      Object evaluated = evaluateBeanDefinitionString(className, mbd);
      if (!className.equals(evaluated)) {
         // A dynamically resolved expression, supported as of 4.2...
         if (evaluated instanceof Class) {
            return (Class<?>) evaluated;
         }
         else if (evaluated instanceof String) {
            className = (String) evaluated;
            freshResolve = true;
         }
         else {
            throw new IllegalStateException("Invalid class name expression result: " + evaluated);
         }
      }
      if (freshResolve) {
         // When resolving against a temporary class loader, exit early in order
         // to avoid storing the resolved Class in the bean definition.
         if (dynamicLoader != null) {
            try {
               return dynamicLoader.loadClass(className);
            }
            catch (ClassNotFoundException ex) {
               if (logger.isTraceEnabled()) {
                  logger.trace("Could not load class [" + className + "] from " + dynamicLoader + ": " + ex);
               }
            }
         }
         return ClassUtils.forName(className, dynamicLoader);
      }
   }

   // Resolve regularly, caching the result in the BeanDefinition...
   return mbd.resolveBeanClass(beanClassLoader);
}

 


Pt4.3 Override方法处理

mbdToUse.prepareMethodOverrides()

// org.springframework.beans.factory.support.AbstractBeanDefinition#prepareMethodOverrides

// 处理BeanDefinition中Override父类的方法。
public void prepareMethodOverrides() throws BeanDefinitionValidationException {
    // BeanDefinition是否有Override父类的方法。
    if (hasMethodOverrides()) {
        // 循环处理所有的Override方法进行校验
        getMethodOverrides().getOverrides().forEach(this::prepareMethodOverride);
    }
}

// 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.
        mo.setOverloaded(false);
    }
}

 


Pt4.4 创建Bean对象

分析的代码段:

Object beanInstance = doCreateBean(beanName, mbdToUse, args);

 

doCreateBean负责完成对象创建过程:

// 真正完成Bean对象创建的方法
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
      throws BeanCreationException {

   // 1、创建BeanWrapper对象,用于封装被创建的Bean对象。
   // BeanWrapper是对Bean的封装,包含了真正的bean对象和bean的class,以及PropertyDescriptor集合。
   BeanWrapper instanceWrapper = null;

   // 2、如果是单例对象,先查看缓存中是否已经有初始化中的对象信息。
   if (mbd.isSingleton()) {
      instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
   }

   // 3、缓存没有数据,直接创建新的BeanWrapper实例
   // 包装为BeanWrapper只是为了封装更多的信息,实际上这里的核心是利用带参或无参构造器创建Bean实例,这是Bean创建第一步。
   if (instanceWrapper == null) {
      instanceWrapper = createBeanInstance(beanName, mbd, args);
   }

   // 4、获取BeanWrapper中Bean的实例和BeanClass
   Object bean = instanceWrapper.getWrappedInstance();
   Class<?> beanType = instanceWrapper.getWrappedClass();
   // 如果不是NullBean,则将resolvedTargetType 属性设置为当前的WrappedClass
   if (beanType != NullBean.class) {
      mbd.resolvedTargetType = beanType;
   }

   // 执行后置处理器BeanPostProcessor
   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;
      }
   }

   // 5、添加Bean的三级缓存,用于处理循环依赖的场景。
   // 如果当前bean是单例、支持循环依赖、且当前bean正在创建,通过往singletonFactories添加一个objectFactory(三级缓存)。
   // 这样后期如果有其他bean依赖该bean 可以从singletonFactories获取到bean,getEarlyBeanReference可以对返回的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");
      }
      addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
   }



    // 需要注意的是,earlySingletonExposure为是在有循环依赖时为true,才会触发生成AOP代理类对象。如果没有循环依赖,或者不允许循环依赖时,
    // 不会走到这里的逻辑,exposedObject还只是原生的Bean对象。所以AOP代理类会在两个时机触发:
    // 1. 包含循环依赖时,会在Bean的构造器执行后触发;
    // 2. 不包含循环依赖时,会在bean执行完创建流程后触发;


   // 6、Bean的属性填充。
   // 这是Bean对象实例化第二步,也是DI的核心。
   Object exposedObject = bean;
   try {
      // 对Bean进行依赖注入
      populateBean(beanName, mbd, instanceWrapper);

      // 7、执行Bean对象的init方法,完成对象初始化。
      // 这是Bean对象实例化第三步,也是最后一步,执行Bean的init方法。
      // Bean实例对象依赖注入完成后,开始对Bean实例对象进行初始化(执行init方法),为Bean实例对象应用BeanPostProcessor后置回调处理
      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);
      }
   }

   // 8、循环依赖校验
   if (earlySingletonExposure) {
      // earlySingletonReference 只有在检测到有循环依赖的情况下才会非空
      Object earlySingletonReference = getSingleton(beanName, false);
      if (earlySingletonReference != null) {
         if (exposedObject == bean) {
            // 如果exposedObject 没有在初始化方法中被改变,也就是没有被增强
            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 {
      // 9、根据Scope注册bean
      registerDisposableBeanIfNecessary(beanName, bean, mbd);
   }
   catch (BeanDefinitionValidationException ex) {
      throw new BeanCreationException(
            mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
   }

   return exposedObject;
}

接下来具体分析里面的细节。

 


Pt4.5 缓存中获取BeanWrapper

首先还是要检查缓存中是否已经有创建好的BeanWrapper对象,如果有就不用重复创建了。

// org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean

// 1、创建BeanWrapper对象,用于封装被创建的Bean对象。
// BeanWrapper是对Bean的封装,包含了真正的bean对象和bean的class,以及PropertyDescriptor集合。
BeanWrapper instanceWrapper = null;

// 2、如果是单例对象,先查看缓存中是否已经有初始化中的对象信息。
if (mbd.isSingleton()) {
   instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}

 


Pt4.6 构造器实例化Bean对象

如果缓存中没有BeanWrapper,则通过构造器执行创建Bean操作,并封装成BeanWrapper对象。

// org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean

// 3、缓存没有数据,直接创建新的BeanWrapper实例
// 包装为BeanWrapper只是为了封装更多的信息,实际上这里的核心是利用带参或无参构造器创建Bean实例,这是Bean创建第一步。
if (instanceWrapper == null) {
   instanceWrapper = createBeanInstance(beanName, mbd, args);
}

// 4、获取BeanWrapper中Bean的实例和BeanClass
Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
// 如果不是NullBean,则将resolvedTargetType 属性设置为当前的WrappedClass
if (beanType != NullBean.class) {
   mbd.resolvedTargetType = beanType;
}

// 执行后置处理器BeanPostProcessor
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;
    }
}

 

createBeanInstance就是通过执行构造器生成Bean的类对象:

// 创建Bean实例BeanWrapper。
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {

   // 1、解析获取BeanClass,保证Bean已经真正被解析。
   Class<?> beanClass = resolveBeanClass(mbd, beanName);
   // 如果beanclass为空,且beanclass不是public 且没有权限访问构造函数和方法则抛出异常
   if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
      throw new BeanCreationException(mbd.getResourceDescription(), beanName,
            "Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
   }

   // 2、从BeanSupplier中获取Bean对象,并封装成BeanWrapper。
   // Supplier类似于factoryBean,从Supplier.get()获取bean的对象,并包装成BeanWrapper,然后初始化BeanWrapper。
   Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
   if (instanceSupplier != null) {
      return obtainFromSupplier(instanceSupplier, beanName);
   }

   // 3、如果工厂方法不为空,则通过工厂方法构建 bean 对象。
   // 通常是在 xml 中配置 bean 的 factory-method的场景,例如:
   // <bean id="staticStu" class="com.dragon.study.study20190618.spring.springFactoryMethod.StuFactory" factory-method="getStaticStu">
   if (mbd.getFactoryMethodName() != null) {
      return instantiateUsingFactoryMethod(beanName, mbd, args);
   }

   // 4、判断是否曾经解析过Bean的。
   // 这里是一个shortcut,当重复构建同一个Bean时,可以复用此处的处理结果。
   // resolved 和 mbd.constructorArgumentsResolved 将会在 bean 第一次实例化的过程中被设置
   boolean resolved = false;// Bean是否已经被解析过
   boolean autowireNecessary = false;// 如果autowireNecessary为true说明是采用构造器注入
   // 传入参数为空,说明使用默认无参构造器
   if (args == null) {
      synchronized (mbd.constructorArgumentLock) {
         // 说明曾经解析过构造函数或者factoryMethod
         if (mbd.resolvedConstructorOrFactoryMethod != null) {
            // 说明mbd已经被解析过
            resolved = true;
            // 如果已经解析了构造方法的参数,则必须要通过一个带参构造方法来实例
            autowireNecessary = mbd.constructorArgumentsResolved;
         }
      }
   }

   // 5、如果Bean已经被解析过,则按照原有逻辑进行解析。
   if (resolved) {
      // 通过构造方法自动装配的方式构造 bean 对象
      if (autowireNecessary) {
         return autowireConstructor(beanName, mbd, null, null);
      }
      // 通过默认的无参构造方法进行
      else {
         return instantiateBean(beanName, mbd);
      }
   }

   // 6、由后置处理器决定返回哪些构造方法, 当出现多个构造函数时, 返回为 null
   // 到此处说明是第一次创建该bean,根据SmartInstantiationAwareBeanPostProcessor获取构造函数。
   // 目前看基本上都是空的实现,除了AutowiredAnnotationBeanPostProcessor
   Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
   if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
         mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
      // 需要对构造函数的参数进行注入, 可以通过 ImportBeanDefinitionRegistrar 来修改 bd 的自动装配模式:
      return autowireConstructor(beanName, mbd, ctors, args);
   }

   // Preferred constructors for default construction?
   ctors = mbd.getPreferredConstructors();
   if (ctors != null) {
      return autowireConstructor(beanName, mbd, ctors, null);
   }

   // 使用默认的无参构造方法进行初始化
   return instantiateBean(beanName, mbd);
}

// 从Supplier实例中获取Bean对象,并包装成BeanWrapper返回。
protected BeanWrapper obtainFromSupplier(Supplier<?> instanceSupplier, String beanName) {
   Object instance;

   // 获得原当前线程正在创建的 Bean 的名称
   String outerBean = this.currentlyCreatedBean.get();

   // 设置当前线程正在创建的 Bean 的名称
   this.currentlyCreatedBean.set(beanName);
   try {
      // 调用 Supplier 的 get(),获得Bean的实例对象
      instance = instanceSupplier.get();
   }
   finally {
      // 恢复原有值
      if (outerBean != null) {
         this.currentlyCreatedBean.set(outerBean);
      }
      else {
         this.currentlyCreatedBean.remove();
      }
   }

   if (instance == null) {
      instance = new NullBean();
   }

   // 创建BeanWrapper,封装Bean对象
   BeanWrapper bw = new BeanWrapperImpl(instance);
   // 初始化BeanWrapper
   initBeanWrapper(bw);
   return bw;
}

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

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

 

instantiateBean是最常用的基于默认无参构造器的对象创建:

// 基于默认构造器创建Bean实例对象
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);
   }
}

 


Pt4.7 生成代理对象放入三级缓存

如果当前bean是单例、支持循环依赖、且当前bean正在创建,通过往singletonFactories添加一个objectFactory(三级缓存)。这样后期如果有其他bean依赖该bean 可以从singletonFactories获取到bean,getEarlyBeanReference可以对返回的bean进行修改。

// org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean

private boolean allowCircularReferences = true;

// 5、添加Bean的三级缓存,用于处理循环依赖的场景。
// 如果当前bean是单例、支持循环依赖、且当前bean正在创建,通过往singletonFactories添加一个objectFactory(三级缓存)。
// 这样后期如果有其他bean依赖该bean 可以从singletonFactories获取到bean,getEarlyBeanReference可以对返回的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");
   }
   addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}

 

getEarlyBeanReference判断是否需要生成AOP代理类:

/**
 * 获取一个可以提前暴露的Bean对象,这里可能是原生bean对象,也可能是bean的代理类对象。
 *
 * @param beanName Bean对象名称
 * @param mbd Bean对象定义(合并的)
 * @param bean 原生的Bean对象
 * @return 提前暴露的 包装了原生Bean对象 ObjectFactory对象
 */
protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
   // 提前暴露(放入三级缓存)的对象exposedObject
   Object exposedObject = bean;

   // 如果有AOP配置,这里会生成Bean对象的AOP代理类对象,exposedObject = bean的AOP代理类对象
   if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
      for (SmartInstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().smartInstantiationAware) {
         exposedObject = bp.getEarlyBeanReference(exposedObject, beanName);
      }
   }

   // 否则exposedObject只是原生的bean对象
   return exposedObject;
}

 

添加到三级缓存:

// org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean

// 缓存SingletonFactory信息
protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
   Assert.notNull(singletonFactory, "Singleton factory must not be null");
   synchronized (this.singletonObjects) {
      // 一级缓存不存在,说明没有被创建过
      if (!this.singletonObjects.containsKey(beanName)) {
         // 添加到三级缓存
         this.singletonFactories.put(beanName, singletonFactory);
         // 从二级缓存中移除
         this.earlySingletonObjects.remove(beanName);
         // 记录Bean注册顺序
         this.registeredSingletons.add(beanName);
      }
   }
}

 


Pt4.8 属性填充

然后就是最重要的属性填充,构造Bean对象之间的相互依赖关系。

// org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean

// 对Bean进行依赖注入
populateBean(beanName, mbd, instanceWrapper);

 

// DI核心: 为生成的Bean对象设置属性值
@SuppressWarnings("deprecation")  // for postProcessPropertyValues
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
   // 1、如果BeanWrapper实例为空,但BeanDefinition中的属性不为空,则抛出异常。
   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;
      }
   }

   // 2、执行Bean后置处理器BeanPostProcessor。
   // 根据InstantiationAwareBeanPostProcessor 判断是否继续给该bean配置属性
   if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
      for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
         if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
            return;
         }
      }
   }

   // 3、获取容器在解析Bean定义时获得的属性
   // propertyValues存放的是Bean属性的名称以及对应的值,这里不会存放构造函数相关的参数值,只会存放通过setter注入的依赖。
   PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);

   // 4、根据自动注入的类型,查找属性对应的容器中对象。
   // 如果对象不存在,则通过getBean创建对象。
   // 自动注入的模式是按照名称或者按照类型
   int resolvedAutowireMode = mbd.getResolvedAutowireMode();
   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 (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
         PropertyValues pvsToUse = bp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
         if (pvsToUse == null) {
            if (filteredPds == null) {
               filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
            }
            pvsToUse = bp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
            if (pvsToUse == null) {
               return;
            }
         }
         pvs = pvsToUse;
      }
   }
   if (needsDepCheck) {
      if (filteredPds == null) {
         filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
      }
      checkDependencies(beanName, mbd, filteredPds, pvs);
   }

   // 属性填充:使用已经获取的属性值,填充BeanWrapper中定义的依赖属性。
   if (pvs != null) {
      applyPropertyValues(beanName, mbd, bw, pvs);
   }
}

 

根据类型完成属性的自动注入,如果依赖的对象未创建,则会触发对象创建的过程getBean()。

// 根据Name完成自动注入
protected void autowireByName(
      String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {

   // 当前Bean定义的属性中 非基本类型的属性
   String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);

   // 处理属性对应的Bean实例
   for (String propertyName : propertyNames) {

      // 容器中是否存在属性名称对应的Bean定义
      if (containsBean(propertyName)) {
         // 获取属性名称对应的Bean对象,这里又会触发该对象的实例化过程
         Object bean = getBean(propertyName);
         // 已经获得属性对应的实例对象,后面主要看这个pvs怎么用
         pvs.add(propertyName, bean);

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

// 根据Type获取自动注入对象
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);

    // 当前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()) {
                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);
                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);
        }
    }
}

 

applyPropertyValues将解析的属性填充信息注册到BeanWrapper中。

// 属性填充:使用已经获取的属性值,填充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已经完成解析,直接注入,在方法解析后会缓存已经解析的PropertyValue
      if (mpvs.isConverted()) {
         // Shortcut: use the pre-converted values as-is.
         try {
            // 属性注入BeanWrapper中的Bean对象的属性
            bw.setPropertyValues(mpvs);
            return;
         }
         catch (BeansException ex) {
            throw new BeanCreationException(
                  mbd.getResourceDescription(), beanName, "Error setting property values", ex);
         }
      }

      // 获取Bean定义的属性列表
      original = mpvs.getPropertyValueList();
   }
   else {
      original = Arrays.asList(pvs.getPropertyValues());
   }

   // TypeConverter用于类型转换。
   TypeConverter converter = getCustomTypeConverter();
   if (converter == null) {
      converter = bw;
   }

   // BeanDefinitionValueResolver用于解析PropertyValue,如间接引用替换成直接对象
   BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter);

   // Create a deep copy, resolving any references for values.
   // 深拷贝的PropertyValue列表,用于存放完成解析的PropertyValue
   List<PropertyValue> deepCopy = new ArrayList<>(original.size());


   boolean resolveNecessary = false;

   // 逐个解析PropertyValue
   for (PropertyValue pv : original) {
      // 当前PropertyValue已经被解析,放入deepCopy
      if (pv.isConverted()) {
         deepCopy.add(pv);
      }
      // 否则,解析这个对象,然后再放入deepCopy
      else {
         String propertyName = pv.getName();// 属性的名称
         Object originalValue = pv.getValue();// 属性未经类型转换的值

         // AutowiredPropertyMarker.INSTANCE 类型表示使用 beanFactory#resolveDependency 进行依赖查找。
         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;

         // 属性可写 && 不是嵌套(如foo.bar,java中用getFoo().getBar()表示)或者索引(如person.addresses[0])属性
         boolean convertible = bw.isWritableProperty(propertyName) &&
               !PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName);
         // 用类型转换器进行转换
         if (convertible) {
            convertedValue = convertForProperty(resolvedValue, propertyName, bw, converter);
         }


         // 缓存处理结果,后续可复用。
         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));
         }
      }
   }

   // 标记mpvs已经完成解析,后续可直接使用。
   if (mpvs != null && !resolveNecessary) {
      mpvs.setConverted();
   }

   try {
      // 将解析后的属性值放入BeanWrapper中
      bw.setPropertyValues(new MutablePropertyValues(deepCopy));
   }
   catch (BeansException ex) {
      throw new BeanCreationException(
            mbd.getResourceDescription(), beanName, "Error setting property values", ex);
   }
}

 


Pt4.9 执行init处理

执行Bean对象的init方法,完成对象初始化。这是Bean对象实例化第三步,也是最后一步,执行Bean的init方法。

Bean实例对象依赖注入完成后,开始对Bean实例对象进行初始化(执行init方法),为Bean实例对象应用BeanPostProcessor后置回调处理

// 初始化容器创建的Bean实例对象,为其添加BeanPostProcessor后置处理器
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
   // JDK安全机制验证权限
   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()) {
      // 1、调用BeanPostProcessor的回调方法,执行Bean初始化之前的操作。
      wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
   }

   try {
      // 2、调用Bean的Init-Method方法,完成Bean的初始化操作。
      // 这个Bean的初始化方法是在Spring Bean定义配置文件中通过init-method属性指定的。
      // 这里不是新建Bean的实例操作,此时的Bean已经完成实例化处理,生成了Bean的实例对象,也完成了属性的设置。
      // 如果Bean定义中配置了init-method,这里将执行该方法完成Bean配置中所有init动作。
      invokeInitMethods(beanName, wrappedBean, mbd);
      // 到此为止,Bean实例的初始化操作已经完成,创建了Bean对象,完成了属性的依赖注入,执行了自定义的init-method方法。
   }
   catch (Throwable ex) {
      throw new BeanCreationException(
            (mbd != null ? mbd.getResourceDescription() : null),
            beanName, "Invocation of init method failed", ex);
   }
   if (mbd == null || !mbd.isSynthetic()) {
      // 3、调用BeanPostProcessor的回调方法,执行Bean初始化之后的操作。
      wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
   }

   return wrappedBean;
}

 

到此为止,就完成了对象创建的核心3个步骤:创建对象、填充属性和初始化方法。我们已经创建出完成的Bean对象,可以使用。

 


Pt4.10 循环依赖检查

// org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean

// 8、循环依赖校验
if (earlySingletonExposure) {
   // earlySingletonReference 只有在检测到有循环依赖的情况下才会非空
   // getSingleton会将bean对象从三级缓存移动到二级缓存
   Object earlySingletonReference = getSingleton(beanName, false);

 

在下面的代码,调用了getSingleton方法,这里会将Bean对象从二级缓存移动到一级缓存;

// 尝试从多级缓存中获取原生的单例Bean对象。
// allowEarlyReference:是否开启三级缓存
@Nullable
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
   // 1、尝试从一级缓存(已完成对象创建)获取singleton对象
   Object singletonObject = this.singletonObjects.get(beanName);

   // 2、单例对象创建中,但还未完成创建过程,尝试从二级缓存中获取对象。
   if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
      singletonObject = this.earlySingletonObjects.get(beanName);

      // 3、如果一级缓存和二级缓存都没有,并且启用了三级缓存,则从三级缓存获取。
      if (singletonObject == null && allowEarlyReference) {

         // 再次尝试从一级缓存和二级缓存获取,防止并发的情况。
         synchronized (this.singletonObjects) {
            singletonObject = this.singletonObjects.get(beanName);

            if (singletonObject == null) {
               singletonObject = this.earlySingletonObjects.get(beanName);

               // 4、 尝试从三级缓存获取对象。
               if (singletonObject == null) {
                  ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
                  if (singletonFactory != null) {
                     singletonObject = singletonFactory.getObject();

                     // 5、将对象从三级缓存移除,并加入到二级缓存中。
                     this.earlySingletonObjects.put(beanName, singletonObject);
                     this.singletonFactories.remove(beanName);
                  }
               }
            }
         }
      }
   }
   return singletonObject;
}

 


Pt4.11 添加到一级缓存

添加到一级缓存的对象,说明已经完成了整个对象创建过程,可以被应用程序所使用。

// 7、创建单例模式的Bean对象的场景。
if (mbd.isSingleton()) {
   // 创建真正Bean实例对象
   sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
      @Override
      public Object getObject() throws BeansException {
         try {
            // 创建指定名称的Bean对象(核心逻辑)。
            return AbstractBeanFactory.this.createBean(beanName, mbd, args);
         } catch (BeansException ex) {
            // 从IoC容器中清除单例模式的Bean对象
            AbstractBeanFactory.this.destroySingleton(beanName);
            throw ex;
         }
      }
   });

 

// 从FactoryBean中获取普通Bean对象
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
   Assert.notNull(beanName, "Bean name must not be null");

   synchronized (this.singletonObjects) {
      // 1、先从一级缓存获取查找Bean对象
      Object singletonObject = this.singletonObjects.get(beanName);
      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 + "'");
         }

         // 2、标记当前Bean正在创建中
         beforeSingletonCreation(beanName);
         // newSingleton为true,会将当前Bean加入缓存中
         boolean newSingleton = false;
         // 记录被抑制的异常信息
         boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
         if (recordSuppressedExceptions) {
            this.suppressedExceptions = new LinkedHashSet<>();
         }

         try {
            // 通过FactoryBean创建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;
            }
            // 将Bean从单例对象创建中的列表移除
            afterSingletonCreation(beanName);
         }

         if (newSingleton) {
            // 将完成实例化的Bean加入到缓存中
            addSingleton(beanName, singletonObject);
         }
      }
      return singletonObject;
   }
}

 

添加到一级缓存

// 将完成实例化的单例Bean加入到缓存中
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对象。

 


Pt4.12 获取Bean对象

实际上,这里还有一步,就是获取已经生成的Bean对象来使用。这就是Pt3.4部分的内容:从FactoryBean中获取Bean对象。

 

 


Pt5 源码分析

Pt5.1 单例模式双重检查

下面是我写得一个简单的代理对象,不知道大家看下来有没有什么问题。

public class Singleton {

    private static Singleton singleton = null;
    private Singleton(){}

    public static Singleton getInstance() {
        synchronized (Singleton.class) {
            if (singleton == null) {
                singleton = new Singleton();
                // TODO:单例创建过程逻辑
            }
        }
        return singleton;
    }
}

私有化属性和构造器,通过getInstance()暴露对象的获取路径,通过synchronized保证只有一个线程可以执行singleton初始化过程,好像没什么问题。

其实核心是TODO的部分,每次调用getInstance都有锁竞争,并发性能大大降低。

那怎么改?

 

非常简单,冗余一个判断。

public class Singleton {

    private static Singleton singleton = null;
    private Singleton(){}

    public static Singleton getInstance() {
        if (singleton == null) {
            synchronized (Singleton.class) {
                if (singleton == null) {
                    singleton = new Singleton();
                    // TODO:单例创建过程逻辑
                }
            }
        }
        return singleton;
    }
}

两次判空处理if (singleton == null),简单高效的提升了并发的性能。此类写法在Spring源码中大量存在,用来提升多线程并发的性能。

 


参考资料

参考学习资料和相关文章列表,请参照如下链接:

https://blog.csdn.net/moonlight821/article/details/116463513

 

 

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值