《Spring源码深度解析》- 5BeanFactory的加载

5 BeanFactory的加载

org.springframework.beans.factory.support.AbstractBeanFactory#getBean(java.lang.String)java

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

	protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType, @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
		/* (一). 转换对应beanName 传入的参数name不必定就是beanName, 多是别名, 也多是FactoryBean, 因此须要一系列的解析, 这些解析内容包括以下内容: 1. 去除FactoryBean的修饰符, 也就是若是name="$aa", 那么会首先去除&而使name="aa". 2. 取指定alias所表示的最终beanName, 例如别名A指向名称为B的bean则返回B;若别名A只想别名B, 别名B又指向名称为C的bean则返回C. */
		final String beanName = transformedBeanName(name);
		Object bean;

		/* (二). 尝试从缓存中加载单例. 单例在Spring的同一个容器内只会被建立一次, 后续再获取bean, 就直接从单例缓存中获取了. 固然这里也只是尝试加载, 首先尝试从缓存中加载, 若是加载不成功则再次尝试从singleFactories中加载, 由于再建立单例bean的时候会存在依赖注入的状况,而在建立依赖的时候为了不循环依赖,再Spring中建立bean的原则是不等bean建立完成就会将建立bean的ObjectFactory提前曝光加入到缓存中, 一旦下一个bean建立时候须要依赖上一个bean则直接使用ObjectFactory */
		Object sharedInstance = getSingleton(beanName);
		if (sharedInstance != null && args == null) {
			if (logger.isTraceEnabled()) {
				if (isSingletonCurrentlyInCreation(beanName)) {
					logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +
							"' that is not fully initialized yet - a consequence of a circular reference");
				}
				else {
					logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
				}
			}
      /* (三). bean的实例化 若是从缓存中获得了bean的原始状态, 则须要对bean进行实例化.缓存中记录的只是最原始的bean状态, 并不必定是咱们最终想要的bean. 举个例子吗加入咱们须要对工厂bean进行处理, 那么这里获得的实际上是工厂bean的初始状态, 可是咱们真正须要的是工厂bean中定义的factory-method方法中返回的bean, 而getObjectForBeanInstance就是完成这个工做的. */
			bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
		}

		else {
      /* (四). 原型模式的依赖检查 只有在单例状况下才会尝试解决循环依赖, 原型模式状况下, 若是存在A中又B的属性, B中有A的属性, 那么当依赖注入的时候, 就会产生当A还未建立完的时候由于对于B的建立再次返回建立A, 形成循环依赖. 也就是isPrototypeCurrentlyInCreation(beanName)判断true */
			if (isPrototypeCurrentlyInCreation(beanName)) {
				throw new BeanCurrentlyInCreationException(beanName);
			}

			/* (五). 检查parentBeanFactory 从代码上看, 若是缓存没有数据的话直接转到父类工厂上去加载了, 这是为何呢? 可能读者忽略了一个很重要的判断条件: parentBeanFactory != null && !containsBeanDefinition(beanName). parentBeanFactory != null. parentBeanFactory若是为空, 则其余一切都是浮云, 这个没什么说的, 可是!containsBeanDefinition(beanName)就比较重要了, 它是在检测若是当前加载的XML配置文件中不包含beanName所对应的配置, 就只能到parentBeanFactory去尝试下了, 而后递归的调用getBean方法. */
			BeanFactory parentBeanFactory = getParentBeanFactory();
			if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
				// Not found -> check parent.
				String nameToLookup = originalBeanName(name);
				if (parentBeanFactory instanceof AbstractBeanFactory) {
					return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
							nameToLookup, requiredType, args, typeCheckOnly);
				}
				else if (args != null) {
					// Delegation to parent with explicit args.
					return (T) parentBeanFactory.getBean(nameToLookup, args);
				}
				else if (requiredType != null) {
					// No args -> delegate to standard getBean method.
					return parentBeanFactory.getBean(nameToLookup, requiredType);
				}
				else {
					return (T) parentBeanFactory.getBean(nameToLookup);
				}
			}

			if (!typeCheckOnly) {
				markBeanAsCreated(beanName);
			}

			try {
        /* (六). 将存储XML配置文件的GernericBeanDefinition转换为RootBeanDefinition. 由于从XML配置文件中读取到的Bean信息是存储在GernericBeanDefinition中的, 可是全部的Bean的后续处理都是针对于RootBeanDefinition的, 因此这里须要进行一个转换, 转换的同时若是父类bean不为空的话, 则会一并合并父类的属性. */
				final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
				checkMergedBeanDefinition(mbd, beanName, args);

				/* (七). 寻找依赖 由于bean的初始化过程极可能会用到某些属性, 而某些属性极可能是动态配置的, 而且配置成依赖与其余的bean, 那么这个时候就有必要先加载依赖的bean, 因此, 在Spring的加载顺序中, 在初始化某一个bean的时候首先会初始化这个bean所对应的依赖. */
				String[] dependsOn = mbd.getDependsOn();
				if (dependsOn != null) {
					for (String dep : dependsOn) {
						if (isDependent(beanName, dep)) {
							throw new BeanCreationException(mbd.getResourceDescription(), beanName,
									"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
						}
						registerDependentBean(dep, beanName);
						try {
							getBean(dep);
						}
						catch (NoSuchBeanDefinitionException ex) {
							throw new BeanCreationException(mbd.getResourceDescription(), beanName,
									"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
						}
					}
				}

				/* (八). 针对不一样的scope进行bean的建立 咱们都知道, 在Spring中存在不一样的scope, 其中默认的是singleton, 可是还有其余的配置诸如prototype, request之类的. 在这个步骤中, Spring会根据不一样的配置进行不一样的初始化策略. */
				if (mbd.isSingleton()) {
					sharedInstance = getSingleton(beanName, () -> {
						try {
							return createBean(beanName, mbd, args);
						}
						catch (BeansException ex) {
							// Explicitly remove instance from singleton cache: It might have been put there
							// eagerly by the creation process, to allow for circular reference resolution.
							// Also remove any beans that received a temporary reference to the bean.
							destroySingleton(beanName);
							throw ex;
						}
					});
					bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
				}

				else if (mbd.isPrototype()) {
					// It's a prototype -> create a new instance.
					Object prototypeInstance = null;
					try {
						beforePrototypeCreation(beanName);
						prototypeInstance = createBean(beanName, mbd, args);
					}
					finally {
						afterPrototypeCreation(beanName);
					}
					bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
				}

				else {
					String scopeName = mbd.getScope();
					final Scope scope = this.scopes.get(scopeName);
					if (scope == null) {
						throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
					}
					try {
						Object scopedInstance = scope.get(beanName, () -> {
							beforePrototypeCreation(beanName);
							try {
								return createBean(beanName, mbd, args);
							}
							finally {
								afterPrototypeCreation(beanName);
							}
						});
						bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
					}
					catch (IllegalStateException ex) {
						throw new BeanCreationException(beanName,
								"Scope '" + scopeName + "' is not active for the current thread; consider " +
								"defining a scoped proxy for this bean if you intend to refer to it from a singleton",
								ex);
					}
				}
			}
			catch (BeansException ex) {
				cleanupAfterBeanCreationFailure(beanName);
				throw ex;
			}
		}

		/* (九). 类型转换 程序到这里返回bean后基本结束了, 一般对该方法的调用参数requiredType是为空的, 可是可能会存在这样的状况, 返回的bean实际上是个String, 可是requiredType却传入Integer类型, 那么这时候本步骤就会起做用了, 它的功能是将返回的bean转换为requiredType所指定的类型.固然, String转换为Integer是最简单的一种转换, 在Spring中提供了各类各样的转换器, 用户也能够本身扩辗转换器来知足需求. 通过上面的步骤后bean的加载就结束了, 这个时候就能够返回咱们所须要的bean了, 其中最重要的步骤8, 针对不一样的scope进行bean的建立, 你会看到各类经常使用的Spring特性在这里的实现. */
		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;
	}

复制代码

5.1 FactoryBean的使用

通常状况下, Spring经过反射机制利用bean的class属性指定实现类来实例化bean. 在某些状况下, 实例化bean过程比较复杂, 若是按照传统的方式, 则须要在<bean>中提供大量的配置信息, 配置方式的灵活性是受限的, 这是采用编码的方式可能会获得一个简单的方案. Spring为此提供了一个 org.springframework.bean.factory.FactoryBean 的工厂类接口, 用户能够经过实现该接口定制实例化bean的逻辑.

FactoryBean接口对于Spring框架来讲占有重要的地位, Spring自己就提供了70多个FactoryBean的实现. 它们隐藏了实例化一些复杂bean的细节, 给上层应用带来了便利. 从Spring3.0开始, FactoryBean开始支持泛型, 即接口声明改成FactoryBean<T>的形式:
复制代码
public interface FactoryBean<T> {
    T getObject() throws Exception;
    Class<?> getObjectType();
    default boolean isSingleton() {
      return true;
    }
  }
复制代码

在该接口中还定义了3个方法:git

  • T getObject() : 返回由FactoryBean建立的bean的实例. 若是 isSingleton() 返回true, 则该实例会放到Spring容器中单实例缓存池中.
  • boolean isSingleton() : 返回由FactoryBean建立的bean的实例的做用域是singletion仍是prototype.
  • Class<?> getObjectType() : 返回FactoryBean建立的bean的类型.

当配置文件中的class属性配置的实现类是FactoryBean时, 经过getBean()方法返回的不是FactoryBean自己, 而是FactoryBean#getObject()方法所返回的对象, 至关于FactoryBean#getObject()代理了getBean()方法.spring

5.2 缓存中获取单例Bean

介绍过FactoryBean的用法后, 咱们就能够了解bean加载的过程了. 前面已经提到过, 单例在Spring的同一个容器内只会被建立一次, 后续再获取bena直接从单例缓存中获取, 固然这里也是只尝试加载, 首先尝试从缓存中加载, 而后再次尝试从singletonFactories中加载. 由于再建立单例bean的时候会存在依赖注入的状况, 而在建立依赖的时候为了不循环依赖, Spring建立bean的原则是不等bean建立完成就会将查u你感受爱你bean的ObjectFactory提前曝光加到缓存中, 一旦下一个bean建立时须要依赖上个bean, 则直接使用ObjectFactory.
复制代码
@Override
	public Object getSingleton(String beanName) {
    // 参数true设置标识容许早起依赖
		return getSingleton(beanName, true);
	}

	protected Object getSingleton(String beanName, boolean allowEarlyReference) {
    // 检查缓存中是否存在实例
		Object singletonObject = this.singletonObjects.get(beanName);
		if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
      // 若是为空, 则锁定全局变量并进行处理
			synchronized (this.singletonObjects) {
        // 若是此bean正在加载则不处理
				singletonObject = this.earlySingletonObjects.get(beanName);
				if (singletonObject == null && allowEarlyReference) {
          // 当某些方法须要提早初始化的时候则会调用addSingletonFactory方法将对应的ObjectFactory初始化策略存储在singletonFactories
					ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
					if (singletonFactory != null) {
            // 调用预先设定的getObject方法
						singletonObject = singletonFactory.getObject();
            // 记录再缓存中, earlySingletonObjects和singletonFactories互斥
						this.earlySingletonObjects.put(beanName, singletonObject);
						this.singletonFactories.remove(beanName);
					}
				}
			}
		}
		return singletonObject;
	}
复制代码

这个方法由于涉及循环依赖的检测, 以及涉及不少变量的记录存取, 因此让不少读者摸不着头脑. 这个方法首先尝试从singletonObjects里面获取实例, 若是获取不到, 在尝试从singletonFactories里面获取beanName对应的ObjectFactory, 而后调用这个ObjectFactory的getObject来建立bean, 并放到earlySingletonObjects里面去, 而且从singletonFactories里面remove掉这个ObjectFactory, 而对于后续的全部内存操做都只为了循环依赖检测时候使用, 也就是在allowEarlyReference为true的状况下才会使用.数组

这里涉及用户存储bean的不一样mao, 简单解释以下.缓存

  • singletonObjects: 用户保存BeanName和建立bean实例之间的关系, bean name —> bean instance.
  • singletonFactoriesL用于保存BeanName和建立bean的工厂之间的关系, bean name —> ObjectFactory.
  • earlySingletonObjects: 也是保存BeanName 和建立bean实例之间的关系, 与singletonObjects不一样之处在于, 当一个单例bean被放到这里面后, 那么当bean还在建立过程当中, 就能够经过getBean方法获取到了, 其目的是用来检测循环引用.
  • registeredSingletons: 用来保存当前全部已注册的bean.

5.3 从bean的实例中获取对象

在getBean方法中, getObejctForBeanInstance是个高频率使用的方法, 不管是从缓存中得到bean仍是根据不一样的scope策略加载bean. 总之, 咱们获得bean的实例后要作的第一步就是调用这个方法来检测一下正确性, 其实就是用于检测当前bean是不是FactoryBean类型的bean, 若是是, 那么须要调用该bean对应的FactoryBean实例中的getObject()做为返回值.

不管是从缓存中获取到的bean仍是经过不一样的scope策略加载的bean都只是最原始的bean状态, 并不必定是咱们最终想要的bean. 举个例子, 加入咱们须要对工厂bean进行处理, 那么这里获得的实际上是工厂bean的初始状态, 可是咱们真正须要的是工厂bean中定义的factory-method方法中返回的bean, 而getObjectForBeanInstance方法就是完成这个工做的.
复制代码

org.springframework.beans.factory.support.AbstractBeanFactory#getObjectForBeanInstancebash

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

		// 若是指定的name是工厂相关(以&为前缀)且beanInstance又不是FactoryBean类型则验证不经过
		if (BeanFactoryUtils.isFactoryDereference(name)) {
			if (beanInstance instanceof NullBean) {
				return beanInstance;
			}
			if (!(beanInstance instanceof FactoryBean)) {
				throw new BeanIsNotAFactoryException(transformedBeanName(name), beanInstance.getClass());
			}
		}

		// 如今咱们有了个bean的实例, 这个实例可能会是正常的bean或者是FactoryBean
    // 若是是FactoryBean咱们使用它建立实例, 可是若是用户想要直接获取工厂实例而不是工厂的getObject方法对应的实例那么传入的name应该加入前缀&
		if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {
			return beanInstance;
		}

    // 加载FactoryBean
		Object object = null;
		if (mbd == null) {
      // 尝试从缓存中加载bean
			object = getCachedObjectForFactoryBean(beanName);
		}
		if (object == null) {
			// 到这里已经明确知道beanInstance必定是FactoryBean类型
			FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
			// containsBeanDefinition检测beanDefinitionMap中也就是在全部已经加载的类中检测是否认义beanName
			if (mbd == null && containsBeanDefinition(beanName)) {
        // 将存储再XML配置文件的GenericBeanDefinition转换为RootBeanDefinition, 若是指定BeanName是子Bean的话同时会合并父类的相关属性
				mbd = getMergedLocalBeanDefinition(beanName);
			}
      // 是不是用户定义的而不是应用程序自己定义的
			boolean synthetic = (mbd != null && mbd.isSynthetic());
			object = getObjectFromFactoryBean(factory, beanName, !synthetic);
		}
		return object;
	}
复制代码

从上面代码来看, 其实这个方法并无什么重要的信息, 大可能是些辅助代码以及一些功能性的判断, 而真正的核心代码却委托给了getObjectFromFactoryBean, 咱们来看看getObjectFromBeanInstance中所作的工做.架构

  1. 对FactoryBean正确性的验证
  2. 对非FactoryBean不作任何处理
  3. 对bean进行转换
  4. 将从Factory中解析bean的工做委托给getObjectFromFactoryBean.

org.springframework.beans.factory.support.FactoryBeanRegistrySupport#getObjectFromFactoryBeanapp

protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {
		if (factory.isSingleton() && containsSingleton(beanName)) {
			synchronized (getSingletonMutex()) {
				Object object = this.factoryBeanObjectCache.get(beanName);
				if (object == null) {
					object = doGetObjectFromFactoryBean(factory, beanName);
					// Only post-process and store if not put there already during getObject() call above
					// (e.g. because of circular reference processing triggered by custom getBean calls)
					Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
					if (alreadyThere != null) {
						object = alreadyThere;
					}
					else {
						if (shouldPostProcess) {
							if (isSingletonCurrentlyInCreation(beanName)) {
								// Temporarily return non-post-processed object, not storing it yet..
								return object;
							}
							beforeSingletonCreation(beanName);
							try {
								object = postProcessObjectFromFactoryBean(object, beanName);
							}
							catch (Throwable ex) {
								throw new BeanCreationException(beanName,
										"Post-processing of FactoryBean's singleton object failed", ex);
							}
							finally {
								afterSingletonCreation(beanName);
							}
						}
						if (containsSingleton(beanName)) {
							this.factoryBeanObjectCache.put(beanName, object);
						}
					}
				}
				return object;
			}
		}
		else {
			Object object = doGetObjectFromFactoryBean(factory, beanName);
			if (shouldPostProcess) {
				try {
          // 调用ObjectFactory的后置处理器
					object = postProcessObjectFromFactoryBean(object, beanName);
				}
				catch (Throwable ex) {
					throw new BeanCreationException(beanName, "Post-processing of FactoryBean's object failed", ex);
				}
			}
			return object;
		}
	}


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

		Object object;
		try {
      // 须要权限验证
			if (System.getSecurityManager() != null) {
				AccessControlContext acc = getAccessControlContext();
				try {
					object = AccessController.doPrivileged((PrivilegedExceptionAction<Object>) factory::getObject, acc);
				}
				catch (PrivilegedActionException pae) {
					throw pae.getException();
				}
			}
			else {
        // 直接调用getObject方法
				object = factory.getObject();
			}
		}
		catch (FactoryBeanNotInitializedException ex) {
			throw new BeanCurrentlyInCreationException(beanName, ex.toString());
		}
		catch (Throwable ex) {
			throw new BeanCreationException(beanName, "FactoryBean threw exception on object creation", ex);
		}

		// Do not accept a null value for a FactoryBean that's not fully
		// initialized yet: Many FactoryBeans just return null then.
		if (object == null) {
			if (isSingletonCurrentlyInCreation(beanName)) {
				throw new BeanCurrentlyInCreationException(
						beanName, "FactoryBean which is currently in creation returned null from getObject");
			}
			object = new NullBean();
		}
		return object;
	}

复制代码

5.4 获取单例

若是缓存中不存在已经加载的单例bean就须要从头开始bean的加载过程了, 而Spring中使用了getSingleton的重载方法实现bean的加载过程.框架

org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#getSingleton(java.lang.String, org.springframework.beans.factory.ObjectFactory<?>)less

public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
		Assert.notNull(beanName, "'beanName' must not be null");
    // 全局变量须要同步
		synchronized (this.singletonObjects) {
      // 首先检查对应的bean是否已经加载过, 由于singleton模式其实就是复用以建立的bean, 因此这一步时必须的
			Object singletonObject = this.singletonObjects.get(beanName);
      // 若是为空才能够进行singleton的初始化
			if (singletonObject == null) {
				if (this.singletonsCurrentlyInDestruction) {
					throw new BeanCreationNotAllowedException(beanName,
							"Singleton bean creation not allowed while singletons of this factory are in destruction " +
							"(Do not request a bean from a BeanFactory in a destroy method implementation!)");
				}
				if (logger.isDebugEnabled()) {
					logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
				}
        // 记录加载状态, 也就是经过this.singletonsCurrentlyInCreation.add(beanName)将当前正要建立的bean记录在缓存中, 这样即可以对循环依赖进行检测.
				beforeSingletonCreation(beanName);
				boolean newSingleton = false;
				boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
				if (recordSuppressedExceptions) {
					this.suppressedExceptions = new LinkedHashSet<Exception>();
				}
				try {
          // 初始化bean
					singletonObject = singletonFactory.getObject();
					newSingleton = true;
				}
				catch (IllegalStateException ex) {
					// Has the singleton object implicitly appeared in the meantime ->
					// if yes, proceed with it since the exception indicates that state.
					singletonObject = this.singletonObjects.get(beanName);
					if (singletonObject == null) {
						throw ex;
					}
				}
				catch (BeanCreationException ex) {
					if (recordSuppressedExceptions) {
						for (Exception suppressedException : this.suppressedExceptions) {
							ex.addRelatedCause(suppressedException);
						}
					}
					throw ex;
				}
				finally {
					if (recordSuppressedExceptions) {
						this.suppressedExceptions = null;
					}
          // 
					afterSingletonCreation(beanName);
				}
				if (newSingleton) {
          // 加入缓存
					addSingleton(beanName, singletonObject);
				}
			}
			return (singletonObject != NULL_OBJECT ? singletonObject : null);
		}
	}

复制代码

上述代码中实际上是使用了回调方法, 使得程序能够在单例建立的先后作一些准备及处理操做, 而真正的获取单例的bean的方法其实并非在此方法中实现的, 其实现逻辑是在ObjectFactory类型的实例singletonFactory中实现的. 而这些准备及处理操做包括以下内容:

  1. 检查缓存是否已经加载过
  2. 若没有加载, 则记录beanName的正在加载状态
  3. 加载单例前记录加载状态

可能你会以为beforeSingletonCreation方法是个空实现, 里面没有任何逻辑, 但其实不是. 这个函数中作了一个很重要的操做: 记录加载状态, 也就是经过this.singletonsCurrentlyInCreation.add(beanName)将当前正要建立的bean记录在缓存中, 这样即可以对循环依赖进行检测.

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

复制代码
  1. 经过调用参数传入的ObjectFactory的个体Object方法实例化bean.
  2. 加载单例后的处理方法调用.

同步骤(3)的记录加载状态类似, 当bean加载结束后须要移除缓存中对该bean的正在加载状态的记录.

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

复制代码
  1. 将结果记录至缓存并删除加载bean过程当中所记录的各类辅助状态.

org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#addSingleton

protected void addSingleton(String beanName, Object singletonObject) {
		synchronized (this.singletonObjects) {
			this.singletonObjects.put(beanName, (singletonObject != null ? singletonObject : NULL_OBJECT));
			this.singletonFactories.remove(beanName);
			this.earlySingletonObjects.remove(beanName);
			this.registeredSingletons.add(beanName);
		}
	}

复制代码
  1. 返回处理结果

虽然咱们已经从外部了解了加载bean的逻辑架构, 但如今咱们尚未开始对bean加载功能的探索, 以前提到过, bena的加载逻辑实际上是在传入的ObjectFactory类型的参数singletonFatory中定义的, 咱们反推参数的获取, 获得以下代码

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

if (mbd.isSingleton()) {
					sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
						@Override
						public Object getObject() throws BeansException {
							try {
								return createBean(beanName, mbd, args);
							}
							catch (BeansException ex) {
								// Explicitly remove instance from singleton cache: It might have been put there
								// eagerly by the creation process, to allow for circular reference resolution.
								// Also remove any beans that received a temporary reference to the bean.
								destroySingleton(beanName);
								throw ex;
							}
						}
					});
					bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
				}

复制代码

ObjectFactory的核心部分其实只是调用了createBean的方法, 因此还须要到createBean方法中寻找.

5.5 准备建立Bean

咱们不可能期望在一个函数中完成一个复杂的逻辑, 并且咱们跟踪了这么多Spring代码, 经历了这么多函数, 或多或少也发现了一些规律: 一个真正干活的函数实际上是以do开头的, 好比doGetObjectFromFactoryBean; 而给咱们错觉的函数getObjectFromFactoryBean, 其实只是从全局角度去作些统筹的工做. 这个规则对于createBean也不例外, 那么咱们看看在createBean函数中作了那些准备工做.

org.springframework.beans.factory.support.AbstractBeanFactory#createBean

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBean(java.lang.String, org.springframework.beans.factory.support.RootBeanDefinition, java.lang.Object[])

@Override
	protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
		if (logger.isDebugEnabled()) {
			logger.debug("Creating instance of bean '" + beanName + "'");
		}
		RootBeanDefinition mbdToUse = mbd;

		// Make sure bean class is actually resolved at this point, and
		// clone the bean definition in case of a dynamically resolved Class
		// which cannot be stored in the shared merged bean definition.
    // 锁定class, 根据设置的class属性或者根据className来解析Class
		Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
		if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
			mbdToUse = new RootBeanDefinition(mbd);
			mbdToUse.setBeanClass(resolvedClass);
		}

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

		try {
			// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
      // 给BeanPostProcessors一个机会来返回代理来替代真正的实例
			Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
			if (bean != null) {
				return bean;
			}
		}
		catch (Throwable ex) {
			throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
					"BeanPostProcessor before instantiation of bean failed", ex);
		}

		Object beanInstance = doCreateBean(beanName, mbdToUse, args);
		if (logger.isDebugEnabled()) {
			logger.debug("Finished creating instance of bean '" + beanName + "'");
		}
		return beanInstance;
	}


复制代码

从代码中咱们能够总结出函数完成的具体步骤及功能.

  1. 根据设置的class属性或者根据className来解析Class.
  2. 对override属性进行标记及验证.

不少读者可能会不知道这个方法的做用, 由于再Spring的配置里面根本就没有诸如override-method之类的配置, 那么这个方法究竟是干什么用的呢?

其实在Spring中确实没有override-method这样的配置, 可是若是读过前面的部分, 可能会有所发现, 在Spring配置中存在lookup-method和replace-method的, 而这两个配置的加载其实就是将配置统一存放在BeanDefinition中methodOverrides属性里, 而这个函数的操做其实也就是针对于这两个配置的.

  1. 应用初始化前的后处理器, 解析指定bean是否存在初始化前的短路操做.
  2. 建立bean.

咱们首先查看下对override属性标记及验证的逻辑实现.

5.5.1 处理 override 属性

查看源码中 AbstractBeanDefinition 类的 prepareMethodOverrides 方法:

public void prepareMethodOverrides() throws BeanDefinitionValidationException {
		// Check that lookup methods exists.
		MethodOverrides methodOverrides = getMethodOverrides();
		if (!methodOverrides.isEmpty()) {
			Set<MethodOverride> overrides = methodOverrides.getOverrides();
			synchronized (overrides) {
				for (MethodOverride mo : overrides) {
					prepareMethodOverride(mo);
				}
			}
		}
	}

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

复制代码

以前反复提到过, 在Spring配置中存在 lookup-method 和 replace-method 两个配置功能, 而这两个配置的加载其实就是将配置统一存放在 BeanDefinition 中的 methodOverrides 属性里, 这两个功能实现原理实际上是在 bean 实例化的时候若是检测到存在 methodOverrides 属性, 会动态地为当前 bean 生成代理并使用对应的拦截器为 bean 作加强处理, 相关逻辑实如今 bean 的实例化部分详细介绍.

对于方法的匹配来说, 若是一个类总存在若干个重载方法, 那么在函数调用及加强的时候还须要根据参数类型进行匹配, 来最终确认当前调用的究竟是哪一个函数. 可是Spring将一部分匹配工做在这里完成了, 若是当前类中的方法只有一个, 那么就设置该方法没有被重载, 这样在后续调用的时候就能够直接使用找到的方法, 而不须要进行方法的参数匹配验证了, 并且还能够提早对方法存在性进行验证.

5.5.2 实例化的前置处理

在真正调用 doCreate 方法建立 bean 的实例前使用了这样一个方法 resolveBeforeInstantiation(beanName, mdb) 对 BeanDefinigiton 中的属性作些前置处理. 固然, 不管其中是否有相应的逻辑实现咱们均可以理解, 由于真正逻辑实现先后留有处理函数也是可扩展的一种提现, 可是, 这并非最重要的, 在函数中还提供了一个短路判断, 这才是最为关键的部分.

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

复制代码

当通过前置处理后返回的结果若是不为空, 那么会直接略事后续的 Bean 的建立而直接返回结果. 这一特性虽然很容易被忽略, 可是却起着相当重要的做用, 咱们熟知的AOP功能就是基于这里的判断的.

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#resolveBeforeInstantiation

protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
		Object bean = null;
		if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
			// 若是还没有被解析
			if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
				Class<?> targetType = determineTargetType(beanName, mbd);
				if (targetType != null) {
					bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
					if (bean != null) {
						bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
					}
				}
			}
			mbd.beforeInstantiationResolved = (bean != null);
		}
		return bean;
	}

复制代码

此方法中最吸引咱们的无疑是两个方法 applyBeanPostProcessorsBeforeInstantiation 以及 applyBeanPostProcessorsAfterInitialization . 两个方法实现的很是简单, 无非是对后处理器中的全部 InstantiationAwareBeanPostProcessor 类型的后处理器进行 postProcessAfterInstantiation 方法和 BeanPostProcessor 的 postProcessAfterInitialization 方法的调用.

  1. 实例化前的后处理器应用

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

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsBeforeInstantiation

protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
		for (BeanPostProcessor bp : getBeanPostProcessors()) {
			if (bp instanceof InstantiationAwareBeanPostProcessor) {
				InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
				Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
				if (result != null) {
					return result;
				}
			}
		}
		return null;
	}

复制代码
  1. 实例化后的后处理器应用

在讲解从缓存中获取单例 bean 的时候就提到过, Spring 中的规则是在 bean 的初始化后尽量保证将注册的后处理器的 postProcessAfterInstantiation 方法应用到该 bean 中, 由于若是返回的 bean 不为空, 那么便不会再次经理普通bean的建立过程, 因此只能在这里应用后处理器的 postProcessAfterInstantiation 方法.

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

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

复制代码

5.6 循环依赖

实例化bean是一个很是复杂的过程, 而其中最比较难以理解的就是对循环依赖的解决.

5.6.1 什么是循环依赖

循环依赖就是循环引用, 就是两个或多个 bean 相互之间持有对方, 好比 CircleA 引用 CricleB, CircleB 引用 CircleC, CricleC引用 CircleA, 则它们最终反应为一个环. 此处不是循环调用, 循环调用是方法之间的循环调用.

循环调用是没法解决的, 除非有终结条件, 不然就是死循环, 最终致使内存溢出错误.

5.6.2 Spring 如何解决循环依赖

Spring 容器循环依赖包括构造器循环依赖和setter循环依赖, 那Spring容器如何解决循环依赖呢?

在Spring中将循环依赖处理分红了3中状况.

  1. 构造器循环依赖

表示经过构造器注入构成的循环依赖, 此依赖时没法解决的, 只能抛出 BeanCurrentlyInCreationException 异常表示循环依赖.

如在建立 TestA 类时, 构造器须要 TestB 类, 那将去建立 TestB, 在建立 TestB 类时又发现须要 TestC 类, 则又去建立 TestC, 最终在建立 TestC 时发现有须要 TestA, 从而造成了一个环, 没办法建立.

Spring 容器将每个正在建立的 bean 标识符放在一个 "当前建立bean池" 中, bean 标识符在建立过程当中将一直保持在这个池中, 所以若是在建立 bean 过程当中发现本身已经在 "当前建立bean池" 里时, 将抛出 BeanCurrentlyInCreationException异常表示循环依赖; 而对于建立完毕的 bean 将从 "当前建立bean池" 里清楚掉.

  1. setter 循环依赖

表示经过setter注入方式构成循环依赖. 对于setter 注入形成的依赖是经过 Spring 容器提早暴露刚完成构造器注入但未完成其余步骤(如 setter 注入)的 bean 来完成的, 并且只能解决单例做用域的 bean 循环依赖. 经过提早暴露一个单例工厂方法, 从而使其余 bean 能引用到该 bean, 以下代码所示:

addSingletonFactory(beanName, new ObjectFactory() {
  public Object getObject() throws BeanException {
    return getEarlyBeanReference(beanName, mbd, bean);
  }
});

复制代码

​ 具体步骤以下.

​ (1). Spring 容器建立单例 "testA" bean, 首先根据无参构造器建立bean, 并暴露一个 "ObjectFactory" 用于返回一个提起暴露一个建立中的 bean, 并将 "testA" 标识符放到 "当前建立bena池" , 而后进行 setter 注入 "testB".

​ (2). Spring 容器建立单例 "testB" bean, 首先根据无参构造器建立bean, 并暴露一个 "ObjectFactory" 用于返回一个提起暴露一个建立中的 bean, 并将 "testB" 标识符放到 "当前建立bena池" , 而后进行 setter 注入 "testC".

​ (3). Spring 容器建立单例 "testC" bean, 首先根据无参构造器建立bean, 并暴露一个 "ObjectFactory" 用于返回一个提起暴露一个建立中的 bean, 并将 "testC" 标识符放到 "当前建立bena池" , 而后进行 setter 注入 "circle". 进行注入 "testA" 时因为提早暴露了 "ObjectFactory" 工厂, 从而使用它返回提早暴露一个建立中的 bean.

​ (4). 最后在依赖注入 "testB" 和 "testA", 完成 setter 注入

  1. prototype范围的依赖处理

对于 "prototype" 做用域 bean, Spring 容器没法完成依赖注入, 由于Spring 容器不进行缓存 "prototype" 做用域的 bean, 所以没法提早暴露一个建立中的 bean.

对于 "singleton" 做用域 bean, 能够经过 "setAllowCircularReferences(false)"; 来禁用循环引用.

5.7 建立 bean

介绍了循环依赖以及Spring中循环依赖的处理方式后, 继续4,5小节的内容. 当经历过 resolveBeforeInstantiation 方法后, 程序有两个选择, 若是建立了代理或者说重写了 InstantiationAwareBeanPostProcessor 的 postProcessBeforeInstantiation 方法并在方法 postProcessBeforeInstantiation 中改变了 bean, 则直接返回就能够了, 不然须要进行常规 bean 的建立. 而这常规 bean 的建立就是在 doCreateBean 中完成的.

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

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

		// Instantiate the bean.
		BeanWrapper instanceWrapper = null;
		if (mbd.isSingleton()) {
			instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
		}
		if (instanceWrapper == null) {
      // 根据指定 bean 使用对应的策略建立新的实例, 如: 工厂方法, 构造函数自动注入, 简单初始化
			instanceWrapper = createBeanInstance(beanName, mbd, args);
		}
		final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
		Class<?> beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);
		mbd.resolvedTargetType = beanType;

		// Allow post-processors to modify the merged bean definition.
		synchronized (mbd.postProcessingLock) {
			if (!mbd.postProcessed) {
				try {
          // 应用 MergedBeanDefinitionPostProcessor
					applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
				}
				catch (Throwable ex) {
					throw new BeanCreationException(mbd.getResourceDescription(), beanName,
							"Post-processing of merged bean definition failed", ex);
				}
				mbd.postProcessed = true;
			}
		}

		// Eagerly cache singletons to be able to resolve circular references
		// even when triggered by lifecycle interfaces like BeanFactoryAware.
    /* 是否须要提前曝光: 单例&容许循环依赖&当前bean正在建立中, 检测循环依赖 */
		boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
				isSingletonCurrentlyInCreation(beanName));
		if (earlySingletonExposure) {
			if (logger.isDebugEnabled()) {
				logger.debug("Eagerly caching bean '" + beanName +
						"' to allow for resolving potential circular references");
			}
      // 为避免后期循环依赖, 能够在bean初始化完成前将建立实例的ObjectFactory加入工厂
			addSingletonFactory(beanName, new ObjectFactory<Object>() {
				@Override
				public Object getObject() throws BeansException {
          // 对 bean 再一次依赖引用, 主要应用 SmartInstantiationAware BeanPostProcessor, 其中咱们熟悉的AOP就是在这里将advice动态织入bean中, 若没有则直接返回bean, 不作任何处理
					return getEarlyBeanReference(beanName, mbd, bean);
				}
			});
		}

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

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

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

		return exposedObject;
	}

复制代码

尽管日志与异常的内容很是重要, 可是在阅读源码的时候彷佛大部分人都会直接忽略掉. 在此不深刻探讨日志及异常的设计, 咱们看看整个函数的概要思路.

  1. 若是是单例则须要首先清除缓存.
  2. 实例化bean, 将 BeanDefinition 转换为 BeanWrapper.

转换是一个复杂的过程, 可是咱们能够尝试归纳大体的功能, 以下所示.

  • 若是存在工厂方法则使用工厂方法进行初始化
  • 一个类有多个构造函数, 每一个构造函数都有不一样的参数, 因此须要根据参数锁定构造函数并进行初始化.
  • 若是既不存在工厂方法也不存在带有参数的构造函数, 则使用默认的构造函数进行bean的实例化.
  1. MergedBeanDefinitionPostProcessor 的应用.

bean 合并后的处理, Autowired注解正式经过此方法实现注入类型的预解析.

  1. 依赖处理

在Spring 中会有循环依赖的状况, 例如, 当A中含有B的属性, 而B中又含有A的属性时就会构成一个循环依赖, 此时若是A和B都是单例, 那么在Spring中处理方式就是当建立B的时候, 实际自动注入A的步骤时, 并非直接去再次建立A, 而是经过放入缓存中的ObjectFactory来建立实例, 这样就解决了循环依赖的问题.

  1. 属性填充. 将全部属性填充至bean的实例中.
  2. 循环依赖检查

以前有提到过, 在Spring 中解决循环依赖只对单例有效, 而对于prototype的bean, Spring没有好的解决办法, 惟一要作的就是抛出异常. 在这个步骤里面会检测已经加载的bean是否已经出现了循环依赖, 并判断是否须要抛出异常/

  1. 注册DisposableBean

若是配置了destroy-method, 这里须要注册以便于在销毁时候调用.

  1. 完成建立并返回.

能够看到上面的步骤很是的繁琐, 每一步骤都使用了大量的代码来完成其功能, 最复杂也是最难以理解的当属循环依赖的处理, 在真正进入doCreateBean前咱们有必要先了解循环依赖.

5.7.1 建立Bean的实例

当咱们了解了循环以来之后就能够深刻分析建立bean的每一个步骤了, 首先咱们从createBeanInstance开始,

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBeanInstance

protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) {
		// Make sure bean class is actually resolved at this point.
    // 解析class
		Class<?> beanClass = resolveBeanClass(mbd, beanName);

		if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
			throw new BeanCreationException(mbd.getResourceDescription(), beanName,
					"Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
		}

    // 若是工厂方法不为空则使用工厂方法初始化策略
		if (mbd.getFactoryMethodName() != null)  {
			return instantiateUsingFactoryMethod(beanName, mbd, args);
		}

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

		// Need to determine the constructor...
    // 须要根据参数解析构造函数
		Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
		if (ctors != null ||
				mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||
				mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args))  {
      // 构造函数自动注入
			return autowireConstructor(beanName, mbd, ctors, args);
		}

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

复制代码

虽然代码中实例化的细节很是复杂, 可是在 createBeanIntance 方法中咱们仍是能够清晰的看到实例化的逻辑的.

  1. 若是在 RootBeanDefinition 中存在 factoryMethodName属性, 或者说在配置文件配置了 factory-method, 那么Spring 会尝试使用 instantiateUsingFactoryMethod(beanName, mbd, args) 方法根据 RootBeanDefinition 中的配置生成 bean 的实例.

  2. 解析构造函数并进行构造函数的实例化. 由于一个bean对应的类中可能会有多个构造函数, 而每一个构造函数的参数不一样, Spring 在根据参数及类型去判断最终会使用哪一个构造函数进行实例化. 可是判断的过程是个比较消耗性能的步骤, 因此采用缓存机制, 若是已经解析过则不须要重复解析而是直接从RootBeanDefinition 中的属性resolvedConstructorOrFactoryMethod 缓存的值去取, 不然须要再次解析, 并将解析的结果添加至 RootBeanDefinition 中的属性 resolvedConstructorOrFactoryMethod 中.

    • autowireConstructor

      对于实例的建立 Spring 中分红了两种状况, 一种是通用的实例化, 另外一种是带有参数的实例化. 带有参数的实例化过程至关复杂, 由于存在着不肯定性, 因此在判断对应参数上作了大量工做.

      org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#autowireConstructor

    protected BeanWrapper autowireConstructor( String beanName, RootBeanDefinition mbd, Constructor<?>[] ctors, Object[] explicitArgs) {
      		return new ConstructorResolver(this).autowireConstructor(beanName, mbd, ctors, explicitArgs);
      	}
    
    public BeanWrapper autowireConstructor(final String beanName, final RootBeanDefinition mbd, Constructor<?>[] chosenCtors, final Object[] explicitArgs) {
    
    BeanWrapperImpl bw = new BeanWrapperImpl();
    this.beanFactory.initBeanWrapper(bw);
    
    Constructor<?> constructorToUse = null;
    ArgumentsHolder argsHolderToUse = null;
    Object[] argsToUse = null;
    
      // explicitArgs 经过getBean方法传入
      // 若是getBean方法调用的时候指定方法参数那么直接使用
    if (explicitArgs != null) {
    	argsToUse = explicitArgs;
    }
    else {
    // 若是getBean方法调用的时候没有指定方法参数则尝试从配置文件中解析
    	Object[] argsToResolve = null;
    // 尝试从缓存中获取
    	synchronized (mbd.constructorArgumentLock) {
    		constructorToUse = (Constructor<?>) mbd.resolvedConstructorOrFactoryMethod;
    		if (constructorToUse != null && mbd.constructorArgumentsResolved) {
        // 从缓存中获取
    			argsToUse = mbd.resolvedConstructorArguments;
    			if (argsToUse == null) {
          // 配置的构造函数参数
    				argsToResolve = mbd.preparedConstructorArguments;
    			}
    		}
    	}
    // 若是缓存中存在
    	if (argsToResolve != null) {
      // 解析参数类型, 如给定方法的构造函数A(int, int) 则经过此方法后就会把配置中("1", "1")转换为 (1, 1)
      // 缓存中的值多是原始值也多是最终值
    		argsToUse = resolvePreparedArguments(beanName, mbd, bw, constructorToUse, argsToResolve);
    	}
    }
    
      // 没有被缓存
    if (constructorToUse == null) {
    	// Need to resolve the constructor.
    	boolean autowiring = (chosenCtors != null ||
    			mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR);
    	ConstructorArgumentValues resolvedValues = null;
    
    	int minNrOfArgs;
    	if (explicitArgs != null) {
    		minNrOfArgs = explicitArgs.length;
    	}
    	else {
      // 提取配置文件中的配置的构造函数参数
    		ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues();
      // 用于承载解析后的构造函数参数的值
    		resolvedValues = new ConstructorArgumentValues();
      // 能解析到的参数个数
    		minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);
    	}
    
    	// Take specified constructors, if any.
    	Constructor<?>[] candidates = chosenCtors;
    	if (candidates == null) {
    		Class<?> beanClass = mbd.getBeanClass();
    		try {
    			candidates = (mbd.isNonPublicAccessAllowed() ?
    					beanClass.getDeclaredConstructors() : beanClass.getConstructors());
    		}
    		catch (Throwable ex) {
    			throw new BeanCreationException(mbd.getResourceDescription(), beanName,
    					"Resolution of declared constructors on bean Class [" + beanClass.getName() +
    					"] from ClassLoader [" + beanClass.getClassLoader() + "] failed", ex);
    		}
    	}
    
    // 排序给定的构造函数, public构造函数优先参数数量降序, 非public构造函数参数数量降序
    	AutowireUtils.sortConstructors(candidates);
    	int minTypeDiffWeight = Integer.MAX_VALUE;
    	Set<Constructor<?>> ambiguousConstructors = null;
    	LinkedList<UnsatisfiedDependencyException> causes = null;
    
    	for (Constructor<?> candidate : candidates) {
    		Class<?>[] paramTypes = candidate.getParameterTypes();
    
      // 若是已经找到选用的构造函数或者须要的参数个数小于当前的构造函数参数个数则终止, 由于已经按照参数个数降序排列
    		if (constructorToUse != null && argsToUse.length > paramTypes.length) {
    			// Already found greedy constructor that can be satisfied ->
    			// do not look any further, there are only less greedy constructors left.
    			break;
    		}
    		if (paramTypes.length < minNrOfArgs) {
        // 参数个数不相等
    			continue;
    		}
    
    		ArgumentsHolder argsHolder;
    		if (resolvedValues != null) {
        // 有参数则根据值构造对应参数类型的参数
    			try {
          // 注释上获取参数名称
    				String[] paramNames = ConstructorPropertiesChecker.evaluate(candidate, paramTypes.length);
    				if (paramNames == null) {
            // 获取参数名称探索器
    					ParameterNameDiscoverer pnd = this.beanFactory.getParameterNameDiscoverer();
    					if (pnd != null) {
              // 获取指定构造函数的参数名称
    						paramNames = pnd.getParameterNames(candidate);
    					}
    				}
          // 根据名称和数据类型建立参数持有者
    				argsHolder = createArgumentArray(beanName, mbd, resolvedValues, bw, paramTypes, paramNames,
    						getUserDeclaredConstructor(candidate), autowiring);
    			}
    			catch (UnsatisfiedDependencyException ex) {
    				if (this.beanFactory.logger.isTraceEnabled()) {
    					this.beanFactory.logger.trace(
    							"Ignoring constructor [" + candidate + "] of bean '" + beanName + "': " + ex);
    				}
    				// Swallow and try next constructor.
    				if (causes == null) {
    					causes = new LinkedList<UnsatisfiedDependencyException>();
    				}
    				causes.add(ex);
    				continue;
    			}
    		}
    		else {
    			// Explicit arguments given -> arguments length must match exactly.
    			if (paramTypes.length != explicitArgs.length) {
    				continue;
    			}
        // 构造函数没有参数的状况
    			argsHolder = new ArgumentsHolder(explicitArgs);
    		}
    
      // 探测是否有不肯定性的构造函数存在, 例如不一样构造函数的参数为父子关系
    		int typeDiffWeight = (mbd.isLenientConstructorResolution() ?
    				argsHolder.getTypeDifferenceWeight(paramTypes) : argsHolder.getAssignabilityWeight(paramTypes));
    		// Choose this constructor if it represents the closest match.
      // 若是它表明着当前最接近的匹配则选择做为构造函数
    		if (typeDiffWeight < minTypeDiffWeight) {
    			constructorToUse = candidate;
    			argsHolderToUse = argsHolder;
    			argsToUse = argsHolder.arguments;
    			minTypeDiffWeight = typeDiffWeight;
    			ambiguousConstructors = null;
    		}
    		else if (constructorToUse != null && typeDiffWeight == minTypeDiffWeight) {
    			if (ambiguousConstructors == null) {
    				ambiguousConstructors = new LinkedHashSet<Constructor<?>>();
    				ambiguousConstructors.add(constructorToUse);
    			}
    			ambiguousConstructors.add(candidate);
    		}
    	}
    
    	if (constructorToUse == null) {
    		if (causes != null) {
    			UnsatisfiedDependencyException ex = causes.removeLast();
    			for (Exception cause : causes) {
    				this.beanFactory.onSuppressedException(cause);
    			}
    			throw ex;
    		}
    		throw new BeanCreationException(mbd.getResourceDescription(), beanName,
    				"Could not resolve matching constructor " +
    				"(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities)");
    	}
    	else if (ambiguousConstructors != null && !mbd.isLenientConstructorResolution()) {
    		throw new BeanCreationException(mbd.getResourceDescription(), beanName,
    				"Ambiguous constructor matches found in bean '" + beanName + "' " +
    				"(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities): " +
    				ambiguousConstructors);
    	}
    
    	if (explicitArgs == null) {
      // 将解析的构造函数加入缓存
    		argsHolderToUse.storeCache(mbd, constructorToUse);
    	}
    }
    
    try {
    	Object beanInstance;
    
    	if (System.getSecurityManager() != null) {
    		final Constructor<?> ctorToUse = constructorToUse;
    		final Object[] argumentsToUse = argsToUse;
    		beanInstance = AccessController.doPrivileged(new PrivilegedAction<Object>() {
    			@Override
    			public Object run() {
    				return beanFactory.getInstantiationStrategy().instantiate(
    						mbd, beanName, beanFactory, ctorToUse, argumentsToUse);
    			}
    		}, beanFactory.getAccessControlContext());
    	}
    	else {
    		beanInstance = this.beanFactory.getInstantiationStrategy().instantiate(
    				mbd, beanName, this.beanFactory, constructorToUse, argsToUse);
    	}
    
    // 将构建的实例加入BeanWrapper中
      			bw.setBeanInstance(beanInstance);
      			return bw;
      		}
      		catch (Throwable ex) {
      			throw new BeanCreationException(mbd.getResourceDescription(), beanName,
      					"Bean instantiation via constructor failed", ex);
      		}
      	}
    
    复制代码
    逻辑很复杂, 函数代码量很大, 咱们总览一下整个函数, 其实现的功能考虑了一下几个方面.
    
    1. 构造函数参数的肯定.
    
       - 根据 explicitArgs 参数判断
    
         若是传入的参数 explicitArgs 不为空, 那么能够直接肯定参数, 由于 explicitArgs 参数是在调用 Bean 的时候用户指定的, 在 BeanFactory 类中存在这样的方法:
    
         ```java
         Object getBean(String name, Object ... args) throws BeansException;
         ```
    
         在获取 bean 的时候, 用户不但能够指定 bean 的名称还能够指定 bean 所对应类的构造函数或者工厂方法的方法参数, 主要用于静态工厂方法的调用, 而这里是须要给定彻底匹配的参数的, 因此, 即可以判断, 若是传入参数 explicitArgs 不为空, 则能够肯定构造函数参数就是它.
    
       - 缓存中获取
    
         除此以外, 肯定参数的办法若是以前已经分析过, 也就是说构造函数参数已经记录在缓存中, 那么即可以直接拿来使用. 并且, 这里要提到的是, 在缓存中缓存的多是参数的最终类型也多是参数的初始类型, 例如: 构造函数参数要求的是int类型, 可是原始的参数值多是String 类型的 "1", 那么即便在缓存中获得了参数, 也须要通过类型转换器的过滤以确保参数类型与对应的构造函数参数类型彻底对应.
    
       - 配置文件中获取
    
         若是不能根据传入的参数 explicitArgs 肯定构造函数的参数也没法在缓存中达到相关信息, 那么只能开始新一轮的分析了.
    
         分析从获取配置文件中配置的构造函数信息开始, 通过以前的分析, 咱们知道, Spring中配置文件中的信息通过转化都会经过 BeanDefinition 实例承载, 也就是参数 mbd 中包含, 那么能够经过调用 mbd.getConstructorArgumentValues() 参数获取配置的构造函数信息. 有了配置中的信息即可以获取对应的参数值信息了, 获取参数值的信息包括直接指定值, 如: 直接指定构造函数中某个值为原始类型 String 类型, 或者是一个对其余 bean 的引用, 而这一处理委托给 resolveConstructorArguments 方法, 并返回能解析到的参数的个数.
    
    2. 构造函数的肯定
    
       通过了第一步后已经肯定了构造函数的参数, 接下来的任务就是根据构造函数参数在全部构造函数中锁定对应的构造函数, 而匹配的方法就是根据参数个数匹配, 因此在匹配以前须要先对构造函数按照 public 构造函数优先参数数量降序, 非public构造函数参数数量降序. 这样能够在便利的状况下迅速判断排在后面的构造函数参数个数是否符合条件.
    
       因为在配置文件中并非惟一限制使用参数位置索引的方式去建立, 一样还支持指定参数名称进行设定参数值的状况, 如<constructor-arg name="aa">, 那么这种状况就须要首先肯定构造函数中的参数名称.
    
       获取参数名称能够有两种方式, 一种时经过注解的方式直接获取, 另外一种就是使用Spirng中提供的工具类 ParameterNameDiscoverer 来获取. 构造函数, 参数名称, 参数类型, 参数值都肯定后就能够锁定构造函数以及转换对应的参数类型了.
    
    3. 根据肯定的构造函数转换对应的参数类型
    
       主要是使用Spring 中提供的类型转换器或者用户提供的自定义类型转换器进行转换.
    
    4. 构造函数不肯定性的验证
    
       固然, 有时候即便构造函数, 参数名称, 参数类型, 参数值都肯定后也不必定会直接锁定构造函数, 不一样构造函数的参数为父子关系, 因此Spring 在最后又作了一次验证.
    
    5. 根据实例化策略以及获得的构造函数及构造函数参数实例化Bean. 
    
    复制代码
    • instantiateBean

      经历了带有参数的构造函数的实例构造, 相信你会轻松愉快的理解不带参数的构造函数的实例化过程.

      org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#instantiateBean

      protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
      		try {
      			Object beanInstance;
      			final BeanFactory parent = this;
      			if (System.getSecurityManager() != null) {
      				beanInstance = AccessController.doPrivileged((PrivilegedAction<Object>) () ->
      						getInstantiationStrategy().instantiate(mbd, beanName, parent),
      						getAccessControlContext());
      			}
      			else {
      				beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
      			}
      			BeanWrapper bw = new BeanWrapperImpl(beanInstance);
      			initBeanWrapper(bw);
      			return bw;
      		}
      		catch (Throwable ex) {
      			throw new BeanCreationException(
      					mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
      		}
      	}
      
      复制代码

      此方法并无实质性的逻辑, 带有参数的实例构造中, Spring 把经理都放在了构造函数以及参数的匹配上, 因此若是没有参数的话那将是很是简单的一件事, 直接调用实例化策略进行实例化就能够了.

    • 实例化策略

      实例化过程当中反复提到过实例化策略, 那这又是作什么用的呢? 其实, 通过前面的分析, 咱们已经获得了足以实例化的全部相关信息, 彻底可使用最简单的反射方法直接反射来构造实例对象, 可是Spring却并无这么作.

      org.springframework.beans.factory.support.SimpleInstantiationStrategy#instantiate(org.springframework.beans.factory.support.RootBeanDefinition, java.lang.String, org.springframework.beans.factory.BeanFactory)

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

      看了上面两个函数后彷佛咱们已经感觉到了 Spring 的良苦用心以及为了能更方便的使用 Spring 而作了大量的工做. 程序中, 首先判断若是 beanDefinition.getMethodOverrides() 为空也就是用户没有使用 replace 或者 lookup 的配置方法, 那么直接使用放射的方式, 简单快捷, 可是若是使用了这两个特性, 在直接使用反射的方式建立实例就不妥了, 由于须要将这两个配置提供的功能切入进去, 因此就必需要使用动态代理的方式将包含两个特性所对应的逻辑的拦截加强器设置进去, 这样才能够保证在调用方法的时候会被相应的拦截器加强, 返回值为包含拦截器的代理实例.

5.7.2 记录建立bean的ObjectFactory

在 doCreate 函数中有这样一段代码:

/* 是否须要提前曝光: 单例&容许循环依赖&当前bean正在建立中, 检测循环依赖 */
 		boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences && isSingletonCurrentlyInCreation(beanName));
 		if (earlySingletonExposure) {
 			if (logger.isDebugEnabled()) {
 				logger.debug("Eagerly caching bean '" + beanName + "' to allow for resolving potential circular references");
 			}
			// 为避免后期循环依赖, 能够在bean初始化完成前将建立实例的ObjectFactory加入工厂
 			addSingletonFactory(beanName, new ObjectFactory<Object>() {
 				@Override
 				public Object getObject() throws BeansException {
 					// 对 bean 再一次依赖引用, 主要应用 SmartInstantiationAware BeanPostProcessor, 其中咱们熟悉的AOP就是在这里将advice动态织入bean中, 若没有则直接返回bean, 不作任何处理
 					return getEarlyBeanReference(beanName, mbd, bean);
 				}
 			});
 		}

复制代码

这段代码不是很复杂, 可是不少人不是太理解这段代码的做用, 并且, 这段代码仅今后函数中去理解也很难弄懂其中的含义, 咱们须要从全局的角度去思考 Spring 的依赖解决办法.

  • earlySingletonExposure: 从字面的意思就是提前曝光的单例, 咱们暂不定义它的学名叫什么, 咱们感兴趣的是有哪些条件影响这个值.

  • mbd.isSingleton(): 没有太多能够解释的, 此 RootBeanDefinition 表明的是不是单例.

  • this.allowCircularReferences: 是否容许循环依赖, 很抱歉, 并无找到在配置文件中如何配置, 可是在 AbstractRefreshableApplicationContext 中提供了设置函数, 能够经过硬编码的方式进行设置或者能够经过自定义命名空间进行配置, 其中硬编码的方式代码以下:

    ClassPathXmlApplicationContext bf = new ClassPathXmlApplicationContext("aspectTest.xml");
    bf.setAllowBeanDefinitionOverriding(false);
    
    复制代码
  • isSingletonCurrentlyCreation(beanName): 该 bean 是否在建立中, 在 Spring 中, 会有个专门的属性默认为 DefaultSingletonBeanRegistry 的 singletonsCurrentlyInCreation 来记录bean的加载状态, 在bean开始建立前会将 beanName 记录在属性中, 在 bean 建立结束后会将 beanName 从属性中移除, 那么咱们跟随代码一路走来但是对这个属性记录并无多少印象, 这个状态是在哪里记录的呢? 不一样 scope 的记录位置并不同, 咱们以 singleton 为例, 在 singleton 下记录属性的函数是在 DefaultSingletonBeanRegistry 类的 public Object getSingleton(String beanName, ObjectFactory singletonFactory) 函数的 beforeSingletonCreation(beanName) 和 afterSingletonCreation(beanName) 中, 在这两段函数中分别 this.singletonsCurrentlyInCreation.add(beanName) 与this.singletonsCurrentlyInCreation.remove(beanName) 来进行状态的记录与移除.

通过以上分析咱们了解变量 earlySingletonExposure 是否单例, 是否容许循环依赖, 是否对应的 bean 正在建立的 条件的综合. 当这3个条件都知足时会执行 addSingletonFactory 操做, 那么加入SingletonFactory 的做用是什么呢? 又是在何时调用的呢?

咱们仍是以最简单AB循环依赖为例, 类A中含有属性类B, 而类B中又会含有属性类A, 那么初始化beanA的过程如图所示:

graph TD
		建立beanA-->开始建立bean记录beanNameA
		subgraph A
		开始建立bean记录beanNameA-->addSingletonFactoryA(addSingletonFactory)
		addSingletonFactoryA(addSingletonFactory)-->populateBean填充A属性
		populateBean填充A属性-->结束建立bean移除beanNameA
		end
		
		subgraph B
		populateBean填充A属性-->开始建立bean记录beanNameB
		开始建立bean记录beanNameB-->addSingletonFactoryB(addSingletonFactory)
		addSingletonFactoryB(addSingletonFactory)-->populateBean填充B属性
		populateBean填充B属性-->结束建立bean移除beanNameB
		end
		
		subgraph C
		populateBean填充B属性-->getBeanA
		end
复制代码

上图展现了建立beanA的流程, 从图中咱们看到, 在建立A的时候首先会记录类A所对应的beanName, 并将beanA的建立工厂加入缓存中, 而在对A的属性填充也就是调用populate方法的时候又会再一次的对B进行递归建立, 一样的, 由于在B中一样存在A属性, 所以在实例化B的pupulate方法中优惠再次的初始化B, 也就是图形的最后, 调用getBean(A), 关键是在这里, 在这个函数中并非直接去实例化A, 而是先去检查缓存中是否有已经建立号的对应的bean, 或者是否已经建立好的ObjectFactory, 而此时对于A的ObjectFactory咱们早已建立, 因此便不会再去向后执行, 而是直接调用ObjectFactory去建立A. 这里最关键的是 ObjectFactory 的实现.

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));
 		}
     
     	protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
     		Object exposedObject = bean;
     		if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
     			for (BeanPostProcessor bp : getBeanPostProcessors()) {
     				if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
     					SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
     					exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
     				}
     			}
     		}
     		return exposedObject;
     	}

复制代码

在 getEarlyBeanReference 函数中并无太多的逻辑处理, 或者说除了后处理器的调用外, 没有别的处理工做, 根据以上分析, 基本能够理清 Spring 处理循环依赖的解决办法, 在B中建立依赖A时经过ObjectFactory提供的实例方法来中断A中的属性填充, 使B中持有的A仅仅是刚刚初始化并无填充任何属性的A, 而这正初始化A的步骤仍是在最开始建立A的时候进行的, 可是由于A与B中的A所表示的属性地址是同样的, 因此在A中建立好的属性填充天然能够经过B中的A获取, 这样就解决了循环依赖的问题.

5.7.3 属性注入

在了解循环依赖的时候, 咱们曾经反复提到了 populateBean 这个函数, 也多少了解了这个函数的主要功能就是属性填充, 那么到底是如何实现填充的呢?

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#populateBean

protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
     		if (bw == null) {
     			if (mbd.hasPropertyValues()) {
     				throw new BeanCreationException(
     						mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
     			}
     			else {
     				// 没有可填充的属性
     				return;
     			}
     		}
     
     		// 给 InstantiationAwareBeanPostProcessors 最后一次机会在属性设置前来改变 bean
     		// 如: 能够用来支持属性注入的类型
     		boolean continueWithPropertyPopulation = true;
     
     		if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
     			for (BeanPostProcessor bp : getBeanPostProcessors()) {
     				if (bp instanceof InstantiationAwareBeanPostProcessor) {
     					InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
              // 返回值为是否继续填充bean 
     					if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
     						continueWithPropertyPopulation = false;
     						break;
     					}
     				}
     			}
     		}
     
         // 若是后处理器发出中止填充命令则终止后续的进行
     		if (!continueWithPropertyPopulation) {
     			return;
     		}
     
     		PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
     
     		if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME || mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) {
     			MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
     			// 根据名称自动注入
     			if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME) {
     				autowireByName(beanName, mbd, bw, newPvs);
     			}
     			// 根据类型自动注入
     			if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) {
     				autowireByType(beanName, mbd, bw, newPvs);
     			}
     			pvs = newPvs;
     		}
     
         // 后处理器已经初始化
     		boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
         // 须要依赖检查
     		boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);
     
     		PropertyDescriptor[] filteredPds = null;
     		if (hasInstAwareBpps) {
     			if (pvs == null) {
     				pvs = mbd.getPropertyValues();
     			}
     			for (BeanPostProcessor bp : getBeanPostProcessors()) {
     				if (bp instanceof InstantiationAwareBeanPostProcessor) {
     					InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
              // 对全部须要依赖检查的属性进行后置处理
     					PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
     					if (pvsToUse == null) {
     						if (filteredPds == null) {
     							filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
     						}
     						pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
     						if (pvsToUse == null) {
     							return;
     						}
     					}
     					pvs = pvsToUse;
     				}
     			}
     		}
     		if (needsDepCheck) {
     			if (filteredPds == null) {
            // 依赖检查, 对应 depends-on 属性, 3.0已经弃用此属性 
     				filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
     			}
     			checkDependencies(beanName, mbd, filteredPds, pvs);
     		}
     
     		if (pvs != null) {
          // 将属性应用到 bean 中 
     			applyPropertyValues(beanName, mbd, bw, pvs);
     		}
     	}

复制代码

在 populateBean 函数中提供了这样的处理流程:

  • InstantiationAwareBeanPostProcessor处理器的 postProcessAfterInstantiation 函数的应用, 次函数能够控制程序是否继续进行属性填充.
  • 根据注入类型 (byName/byType), 提取依赖的 bean; 并统一存入 PropertyValue 中.
  • 应用 InstantiationAwareBeanPostProcessor 处理器的 postProcessPropertyValues 方法, 对属性获取完毕填充前对属性的再次处理, 典型应用是 RequiredAnnotationBeanPostProcessor 类中对属性的验证.
  • 将全部 PropertyValues 中的属性填充至 BeanWrapper 中.

在上面的步骤中有几个地方是咱们比较感兴趣的, 他们分别是依赖注入(autowireByName/autowireByType) 以及属性填充, 那么, 接下里进一步分析这几个功能的实现细节.

  1. autowireByName

    上文提到根据注入类型 (byName/byType), 提取依赖的bean吗并统一存入PropertyValues中, 那么咱们首先了解下 byName 功能是如何实现的.

    org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#autowireByName

    protected void autowireByName( String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
    
    	String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
    	for (String propertyName : propertyNames) {
    		if (containsBean(propertyName)) {
    			Object bean = getBean(propertyName);
    			pvs.add(propertyName, bean);
    			registerDependentBean(propertyName, beanName);
    			if (logger.isTraceEnabled()) {
    				logger.trace("Added autowiring by name from bean name '" + beanName +
    						"' via property '" + propertyName + "' to bean named '" + propertyName + "'");
    			}
    		}
    		else {
    			if (logger.isTraceEnabled()) {
    				logger.trace("Not autowiring property '" + propertyName + "' of bean '" + beanName +
    						"' by name: no matching bean found");
    			}
    		}
    	}
    }
    
    复制代码
  2. autowireByType

    autowireByType 与 autowireByName 对于咱们理解与使用来讲复杂程度都很类似, 可是其实现功能的复杂度却彻底不同.

    org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#autowireByType

    protected void autowireByType( String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
    
    	TypeConverter converter = getCustomTypeConverter();
    	if (converter == null) {
    		converter = bw;
    	}
    
    	Set<String> autowiredBeanNames = new LinkedHashSet<>(4);
    	// 寻找bw中须要依赖注入的属性
    	String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
    	for (String propertyName : propertyNames) {
    		try {
    			PropertyDescriptor pd = bw.getPropertyDescriptor(propertyName);
    			// Don't try autowiring by type for type Object: never makes sense,
    			// even if it technically is a unsatisfied, non-simple property.
    			if (Object.class != pd.getPropertyType()) {
    				// 探测定位属性的 set 方法
    				MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd);
    				// Do not allow eager init for type matching in case of a prioritized post-processor.
    				boolean eager = !PriorityOrdered.class.isInstance(bw.getWrappedInstance());
    				DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager);
    				// 解析指定 beanName 的属性所匹配的值, 并把解析到的属性名称存储在 autowireBeanName 中, 当属性存在多个封装的 bean 时如:
    				// @Autowired private List<A> aList; 将会找到全部匹配A类型的bean并将其注入
    				Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter);
    				if (autowiredArgument != null) {
    					pvs.add(propertyName, autowiredArgument);
    				}
    				for (String autowiredBeanName : autowiredBeanNames) {
    					// 注册依赖
    					registerDependentBean(autowiredBeanName, beanName);
    					if (logger.isTraceEnabled()) {
    						logger.trace("Autowiring by type from bean name '" + beanName + "' via property '" +
    								propertyName + "' to bean named '" + autowiredBeanName + "'");
    					}
    				}
    				autowiredBeanNames.clear();
    			}
    		}
    		catch (BeansException ex) {
    			throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName, propertyName, ex);
    		}
    	}
    }
    
    复制代码

    实现根据名称自动匹配的第一步就是寻找 bw 中须要依赖注入的属性, 一样对于根据类型自动匹配的实现来说第一步也是寻找bw中须要依赖注入的属性, 而后遍历这些属性并寻找类型匹配的bean, 其中最复杂的就是寻找类型匹配的 bean. 同事 Spring 中提供了对集合的类型注入的支持. 如使用注解的方式:

    @Autowired private List<Test> tests;
    
    复制代码

    Spring 将会把全部与 Test 匹配的类型找出来并出入到 tests 属性中, 正式因为这一因素, 因此在 autowireByType 函数中, 新建了局部遍历 autowiredBeanNames, 用于存储全部依赖的 bean, 若是只是对非集合类的属性注入来讲, 此属性并没有用处.

    对于寻找类型匹配的逻辑实现封装在了 resolveDependency 函数中.

    DefaultListableBeanFactory#resolveDependency

    @Override
    @Nullable
    public Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName, @Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {
    
    	descriptor.initParameterNameDiscovery(getParameterNameDiscoverer());
    	if (Optional.class == descriptor.getDependencyType()) {
    		return createOptionalDependency(descriptor, requestingBeanName);
    	}
    	else if (ObjectFactory.class == descriptor.getDependencyType() ||
    			ObjectProvider.class == descriptor.getDependencyType()) {
    // ObjectFactory 类注入的特殊处理
    		return new DependencyObjectProvider(descriptor, requestingBeanName);
    	}
    	else if (javaxInjectProviderClass == descriptor.getDependencyType()) {
    // javaxInjectProviderClass 类注入的特殊处理
    		return new Jsr330Factory().createDependencyProvider(descriptor, requestingBeanName);
    	}
    	else {
    		Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(
    				descriptor, requestingBeanName);
    		if (result == null) {
     // 通用逻辑处理
    			result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
    		}
    		return result;
    	}
    }
    
    @Nullable
    public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName, @Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {
    	/* 用于支持 Spring 中新增的注解 @Value */
    	InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor);
    	try {
    		Object shortcut = descriptor.resolveShortcut(this);
    		if (shortcut != null) {
    			return shortcut;
    		}
    
    		Class<?> type = descriptor.getDependencyType();
    		Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);
    		if (value != null) {
    			if (value instanceof String) {
    				String strVal = resolveEmbeddedValue((String) value);
    				BeanDefinition bd = (beanName != null && containsBean(beanName) ?
    						getMergedBeanDefinition(beanName) : null);
    				value = evaluateBeanDefinitionString(strVal, bd);
    			}
    			TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
    			try {
    				return converter.convertIfNecessary(value, type, descriptor.getTypeDescriptor());
    			}
    			catch (UnsupportedOperationException ex) {
    				// A custom TypeConverter which does not support TypeDescriptor resolution...
    				return (descriptor.getField() != null ?
    						converter.convertIfNecessary(value, type, descriptor.getField()) :
    						converter.convertIfNecessary(value, type, descriptor.getMethodParameter()));
    			}
    		}
    
    		Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
    		if (multipleBeans != null) {
    			return multipleBeans;
    		}
    
    		Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
    		if (matchingBeans.isEmpty()) {
    			if (isRequired(descriptor)) {
    				raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
    			}
    			return null;
    		}
    
    		String autowiredBeanName;
    		Object instanceCandidate;
    
    		if (matchingBeans.size() > 1) {
    			autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);
    			if (autowiredBeanName == null) {
    				if (isRequired(descriptor) || !indicatesMultipleBeans(type)) {
    					return descriptor.resolveNotUnique(descriptor.getResolvableType(), matchingBeans);
    				}
    				else {
    					// In case of an optional Collection/Map, silently ignore a non-unique case:
    					// possibly it was meant to be an empty collection of multiple regular beans
    					// (before 4.3 in particular when we didn't even look for collection beans).
    					return null;
    				}
    			}
    			instanceCandidate = matchingBeans.get(autowiredBeanName);
    		}
    		else {
    			// We have exactly one match.
    			Map.Entry<String, Object> entry = matchingBeans.entrySet().iterator().next();
    			autowiredBeanName = entry.getKey();
    			instanceCandidate = entry.getValue();
    		}
    
    		if (autowiredBeanNames != null) {
    			autowiredBeanNames.add(autowiredBeanName);
    		}
    		if (instanceCandidate instanceof Class) {
    			instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this);
    		}
    		Object result = instanceCandidate;
    		if (result instanceof NullBean) {
    			if (isRequired(descriptor)) {
    				raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
    			}
    			result = null;
    		}
    		if (!ClassUtils.isAssignableValue(type, result)) {
    			throw new BeanNotOfRequiredTypeException(autowiredBeanName, type, instanceCandidate.getClass());
    		}
    		return result;
    	}
    	finally {
    		ConstructorResolver.setCurrentInjectionPoint(previousInjectionPoint);
    	}
    }
    
    复制代码

    寻找类型的匹配执行顺序时, 首先尝试使用解析器进行解析, 若是解析器没有成功解析, 那么多是使用默认的解析器没有作任何处理, 或者是使用了自定义的解析器, 可是对于集合等类型来讲并不在解析范围以内, 因此再次对不一样类型进行不一样状况的处理, 虽然说对于不一样了性处理方式不一致, 可是大体的思路仍是很类似的, 因此函数中只对数组类型进行了详细的注释.

  3. applyPropertyValues

    程序运行到这里, 已经完成了对全部注入属性的获取, 可是获取的属性是以Propertyvalues形式存在的, 还并无应用到已经实例化的bean中, 这一工做是在applyPropertyValues中.

    org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyPropertyValues

    protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
    	if (pvs == null || pvs.isEmpty()) {
    		return;
    	}
    
    	MutablePropertyValues mpvs = null;
    	List<PropertyValue> original;
    
    	if (System.getSecurityManager() != null) {
    		if (bw instanceof BeanWrapperImpl) {
    			((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext());
    		}
    	}
    
    	if (pvs instanceof MutablePropertyValues) {
    		mpvs = (MutablePropertyValues) pvs;
        // 若是mpvs中的值已经被转换为对应的类型那么能够直接设置到beanwrapper中
    		if (mpvs.isConverted()) {
    			// Shortcut: use the pre-converted values as-is.
    			try {
    				bw.setPropertyValues(mpvs);
    				return;
    			}
    			catch (BeansException ex) {
    				throw new BeanCreationException(
    						mbd.getResourceDescription(), beanName, "Error setting property values", ex);
    			}
    		}
    		original = mpvs.getPropertyValueList();
    	}
    	else {
        // 若是pvs并非使用MutablePropertyValues封装的类型, 那么直接使用原始的属性获取方法
    		original = Arrays.asList(pvs.getPropertyValues());
    	}
    
    	TypeConverter converter = getCustomTypeConverter();
    	if (converter == null) {
    		converter = bw;
    	}
      // 获取对应的解析器
    	BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter);
    
    	// Create a deep copy, resolving any references for values.
    	List<PropertyValue> deepCopy = new ArrayList<PropertyValue>(original.size());
    	boolean resolveNecessary = false;
      // 遍历属性, 将属性转换为对应类的对应属性的类型
    	for (PropertyValue pv : original) {
    		if (pv.isConverted()) {
    			deepCopy.add(pv);
    		}
    		else {
    			String propertyName = pv.getName();
    			Object originalValue = pv.getValue();
    			Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);
    			Object convertedValue = resolvedValue;
    			boolean convertible = bw.isWritableProperty(propertyName) &&
    					!PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName);
    			if (convertible) {
    				convertedValue = convertForProperty(resolvedValue, propertyName, bw, converter);
    			}
    			// Possibly store converted value in merged bean definition,
    			// in order to avoid re-conversion for every created bean instance.
    			if (resolvedValue == originalValue) {
    				if (convertible) {
    					pv.setConvertedValue(convertedValue);
    				}
    				deepCopy.add(pv);
    			}
    			else if (convertible && originalValue instanceof TypedStringValue &&
    					!((TypedStringValue) originalValue).isDynamic() &&
    					!(convertedValue instanceof Collection || ObjectUtils.isArray(convertedValue))) {
    				pv.setConvertedValue(convertedValue);
    				deepCopy.add(pv);
    			}
    			else {
    				resolveNecessary = true;
    				deepCopy.add(new PropertyValue(pv, convertedValue));
    			}
    		}
    	}
    	if (mpvs != null && !resolveNecessary) {
    		mpvs.setConverted();
    	}
    
    	// Set our (possibly massaged) deep copy.
    	try {
    		bw.setPropertyValues(new MutablePropertyValues(deepCopy));
    	}
    	catch (BeansException ex) {
    		throw new BeanCreationException(
    				mbd.getResourceDescription(), beanName, "Error setting property values", ex);
    	}
    }
    
    复制代码

5.7.4 初始化bean

你们应该记得在 bean 配置时 bean 中有一个 init-method 的属性, 这个属性的做用是在 bean 实例化前调用 init-method 指定的方法来根据用户业务进行相应的实例化. 咱们如今就已经进入这个方法了, 首先看一下这个方法的执行位置, Spring 中程序已经执行过 bean 的实例化, 而且进行了属性的填充, 而就在这时将会调用用户设定的初始化方法.

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean(java.lang.String, java.lang.Object, org.springframework.beans.factory.support.RootBeanDefinition)

protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
	if (System.getSecurityManager() != null) {
		AccessController.doPrivileged(new PrivilegedAction<Object>() {
			@Override
			public Object run() {
				invokeAwareMethods(beanName, bean);
				return null;
			}
		}, getAccessControlContext());
	}
	else 
    // 对特殊的 bean 处理: Aware, BeanClassLoaderAware, BeanFactoryAware
		invokeAwareMethods(beanName, bean);
	}

	Object wrappedBean = bean;
	if (mbd == null || !mbd.isSynthetic()) {
    // 应用后处理器
		wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
	}

	try {
    // 激活用户自定义的 init 方法
		invokeInitMethods(beanName, wrappedBean, mbd);
	}
	catch (Throwable ex) {
		throw new BeanCreationException(
				(mbd != null ? mbd.getResourceDescription() : null),
				beanName, "Invocation of init method failed", ex);
	}

	if (mbd == null || !mbd.isSynthetic()) {
    // 后处理器应用
		wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
	}
	return wrappedBean;
}

复制代码

虽说此函数的主要目的是进行客户设定的初始化方法的调用, 可是除此以外还有些其余必要的工做.

  1. 激活 Aware 方法

    在分析其原理以前, 咱们先了解一下 Aware 的使用. Spring 中提供了一些 Aware 相关接口, 好比 BeanFactoryAware, ApplicationContextAware, ResourceLoaderAware, ServletContextAware等, 实现这些Aware 接口的 bean 在被初始化以后, 能够取得一些相应的资源, 例如实现 BeanFactoryAware 的 bean 在初始后, Spring 容器将会注入 BeanFactory 的实例, 而实现 ApplicationContextAware 的 bean, 在 bean 被初始后, 将会被注入 ApplicationContext 的实例等, 咱们首先经过示例方法来了解一下 Aware 的应用.

    (1) 定义普通 bean

    public class Hello {
      public void say() {
        System.out.println("hello");
      }
    }
    
    复制代码

    (2) 定义 BeanFactoryAware 类型的 bean

    public class Test implements BeanFactoryAware {
      private BeanFactory beanFactory;
      
      // 声明 bean 的时候 Spring 会自动注入 BeanFactory
      @Override
      public void setBeanFactory(BeanFactory beanFactory) throws BeanException {
        this.beanFactory = beanFactory;
      }
      
      public void testAware() {
        // 经过 hello 这个 bean id 从 beanFactory 获取实例
        Hello hello = (Hello) beanFactory.getBean("hello");
        hello.say();
      }
      
    }
    
    复制代码

    (3) 使用main方法测试

    public static void main(String[] s) {
      ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
      Test test = (Test) ctx.getBean("test");
      test.testAware();
    }
    
    复制代码

    裕兴测试类, 控制台输出:

    hello
    
    复制代码

    按照上面的方法咱们能够获取到Spring 中BeanFactory, 而且能够根据 BeanFactory 获取全部 bean, 以及进行相关设置. 固然还有其余 Aware 的使用方法都大同小异, 看一下 Spring 的实现方式, 便会使用了.

    org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#invokeAwareMethods

    private void invokeAwareMethods(final String beanName, final Object bean) {
    	if (bean instanceof Aware) {
    		if (bean instanceof BeanNameAware) {
    			((BeanNameAware) bean).setBeanName(beanName);
    		}
    		if (bean instanceof BeanClassLoaderAware) {
    			((BeanClassLoaderAware) bean).setBeanClassLoader(getBeanClassLoader());
    		}
    		if (bean instanceof BeanFactoryAware) {
    			((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
    		}
    	}
    }
    
    复制代码
  2. 处理器的应用

    BeanPostProcessor 相信你们都不陌生, 这是 Spring 中开放式架构中一个必不可少的亮点, 给用户充足的权限去更改或者扩展 Spring, 而除了 BeanPostProcessor 外还有不少其余的 PostProcessor, 固然啊部分都是以此为基础, 继承自BeanPostProcessor. BeanPostProcessor的使用位置就是这里, 在调用客户自定义初始化方法前以及调用自定义初始化方法后分别会调用 BeanPostProcessor 的 postProcessBeforeInitiallization 和 postProcessAfterInitialization 方法, 使用户能够根据本身的业务需求进行响应的处理.

    org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsBeforeInitialization

    @Override
    public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName) throws BeansException {
    
    	Object result = existingBean;
    	for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
    		result = beanProcessor.postProcessBeforeInitialization(result, beanName);
    		if (result == null) {
    			return result;
    		}
    	}
    	return result;
    }
    
    复制代码

    org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization

    @Override
    public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException {
    
    	Object result = existingBean;
    	for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
    		result = beanProcessor.postProcessAfterInitialization(result, beanName);
    		if (result == null) {
    			return result;
    		}
    	}
    	return result;
    }
    
    复制代码
  3. 激活自定义的init方法

    客户定制的初始化方法除了咱们熟知的使用配置init-method外, 还有使自定义的bean实现 InitializingBean 接口, 并在 afterPropertiesSet 中实现本身的初始化业务逻辑.

    init-method 与 afterPropertiesSet 都是在初始化 bean 时执行, 执行顺序是 afterPropertiesSet 先执行, 而 init-method 后执行.

    在 invokeInitMethods 方法中就实现了这两个步骤的初始化方法调用.

    protected void invokeInitMethods(String beanName, final Object bean, RootBeanDefinition mbd) throws Throwable {
    	// 首先会检查是不是 InitializingBean , 若是是的话须要调用 afterPropertiesSet 方法
    	boolean isInitializingBean = (bean instanceof InitializingBean);
    	if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
    		if (logger.isDebugEnabled()) {
    			logger.debug("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
    		}
    		if (System.getSecurityManager() != null) {
    			try {
    				AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
    					@Override
    					public Object run() throws Exception {
    						((InitializingBean) bean).afterPropertiesSet();
    						return null;
    					}
    				}, getAccessControlContext());
    			}
    			catch (PrivilegedActionException pae) {
    				throw pae.getException();
    			}
    		}
    		else {
          // 属性初始化后的处理
    			((InitializingBean) bean).afterPropertiesSet();
    		}
    	}
    
    	if (mbd != null) {
    		String initMethodName = mbd.getInitMethodName();
    		if (initMethodName != null && !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
    				!mbd.isExternallyManagedInitMethod(initMethodName)) {
          // 调用自定义初始化方法
    			invokeCustomInitMethod(beanName, bean, mbd);
    		}
    	}
    }
    
    复制代码

5.7.5 注册DisposableBean

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

org.springframework.beans.factory.support.AbstractBeanFactory#registerDisposableBeanIfNecessary

protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) {
	AccessControlContext acc = (System.getSecurityManager() != null ? getAccessControlContext() : null);
	if (!mbd.isPrototype() && requiresDestruction(bean, mbd)) {
		if (mbd.isSingleton()) {
			// 单例模式下注册须要销毁的 bean , 此方法中会处理实现 DisposableBean 的 bean, 而且对全部的 bean 使用 DestructionAwareBeanPostProcessor 处理 DisposableBean DestructionAwareBeanPostProcessors
			registerDisposableBean(beanName,
					new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
		}
		else {
			// 自定义 scope 的处理
			Scope scope = this.scopes.get(mbd.getScope());
			if (scope == null) {
				throw new IllegalStateException("No Scope registered for scope name '" + mbd.getScope() + "'");
			}
			scope.registerDestructionCallback(beanName,
					new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
		}
	}
}

复制代码
相关文章
相关标签/搜索