Spring源码解析:Bean的加载流程

经过上篇的分析,我们已经完成了Bean实例的注册流程解析,已经将XML文件内容解析成一个个的 BeanDefinition 实例存在于容器之中。接下来就可以调用 BeanFactory的getBean 方法获取目标 Bean 实例。

public class SpringClient {
    public static void main(String[] args) {
        // 类路径下的资源 将其具体抽象成资源对象
        Resource resource = new ClassPathResource("applicationContext.xml");
        // 创建Bean工厂实例
        DefaultListableBeanFactory defaultListableBeanFactory = new DefaultListableBeanFactory();
        // 创建bean读取器实例
        BeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(defaultListableBeanFactory);
        // 将读取的资源放到defaultListableBeanFactory工厂当中
        beanDefinitionReader.loadBeanDefinitions(resource);
        // 读取完,我们需要哪个对象找工厂要
        Student student = (Student) defaultListableBeanFactory.getBean("student");
        Student student2 = (Student) defaultListableBeanFactory.getBean("student");

        System.out.println(student.getAge());
        System.out.println(student.getName());
        System.out.println(student == student2);

    }
}

Spring 提供了多种重载和覆盖的 getBean 方法,当我们在执行 defaultListableBeanFactory.getBean(“student”);时,我们实际上是在调用 AbstractBeanFactory 中的实现:

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

@Override
public <T> T getBean(String name, Class<T> requiredType) throws BeansException {
	return doGetBean(name, requiredType, null, false);
}

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

public <T> T getBean(String name, @Nullable Class<T> requiredType, @Nullable Object... args)
		throws BeansException {

	return doGetBean(name, requiredType, args, false);
}

一个真正干活的函数其实是以 do 开头的,doGetBean 方法也不例外,其中包含了整个创建和获取 bean 的过程。

/*
返回指定bean的实例,该实例可以是共享的,也可以是独立的。
*/
protected <T> T doGetBean(
		String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
		throws BeansException {

	/*
     * 提取对应的beanName
     *
     * 因为传入的参数可以是 alias,也可能是 FactoryBean 的 name,所以需要进行解析,包含以下内容:
     * 1. 如果是 FactoryBean,则去掉 “&” 前缀
     * 2. 沿着引用链获取 alias 对应的最终 name
     */
	String beanName = transformedBeanName(name);
	Object beanInstance;

	/*
	 * 检查缓存中或者实例工厂中是否有对应的实例
	 * 为什么首先会使用这段代码呢?
	 * 因为在创建单例 bean的时候会存在依赖注入的情况,而在创建依赖的时候为了避免循环依赖,
	 * Spring创建bean的原则是不等bean创建完成就会将创建bean的ObjectFactory提早曝光
	 * 也就是将 ObjectFactory 加入到缓存中,一旦下个bean创建时候需要依赖上个 bean则直接使用
	 * ObjectFactory
	 */
	// 直接尝试从缓存获取 或者singletonFactories 中的 ObjectFactory中获取
	// Eagerly check singleton cache for manually registered singletons.
	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 + "'");
			}
		}
		// 返回对应的实例
		beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, null);
	}

	// 目标实例不存在
	else {
		/*
		 * 只有在单例情况才会尝试解决循环依赖,原型模式情况下,如果存在
		 * A中有B的属性,B中有A的属性,那么当依赖注入的时候,就会产生当A还未创建完的时候因为
		 * 对于B的创建再次返回创建A,造成循环依赖,也就是下面的情况
		 * isPrototypeCurrentlyInCreation (beanName)为 true
		 */
		if (isPrototypeCurrentlyInCreation(beanName)) {
			throw new BeanCurrentlyInCreationException(beanName);
		}

		BeanFactory parentBeanFactory = getParentBeanFactory();
		// 如果 beanDefinitionMap中也就是在所有已经加载的类中不包括 beanName 则尝试从parentBeanFactory中检测
		if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
			String nameToLookup = originalBeanName(name);
			// 递归到父 BeanFactory 中进行检索
			if (parentBeanFactory instanceof AbstractBeanFactory) {
				return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
						nameToLookup, requiredType, args, typeCheckOnly);
			}
			else if (args != null) {
				return (T) parentBeanFactory.getBean(nameToLookup, args);
			}
			else if (requiredType != null) {
				return parentBeanFactory.getBean(nameToLookup, requiredType);
			}
			else {
				return (T) parentBeanFactory.getBean(nameToLookup);
			}
		}

		// 如果不是仅仅做类型检查则是创建bean,这里要进行记录(将指定的bean标记为已创建(或即将创建)。)
		if (!typeCheckOnly) {
			markBeanAsCreated(beanName);
		}

		StartupStep beanCreation = this.applicationStartup.start("spring.beans.instantiate")
				.tag("beanName", name);
		try {
			if (requiredType != null) {
				beanCreation.tag("beanType", requiredType::toString);
			}
			// 将存储XML配置的GenericBeanDefinition实例转换成RootBeanDefinition实例
			// 如果存在父bean,则同时合并父bean的相关属性
			RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
			checkMergedBeanDefinition(mbd, beanName, args);

			String[] dependsOn = mbd.getDependsOn();
			// 若存在依赖其它的bean则需要递归实例化依赖的 bean
			if (dependsOn != null) {
				for (String dep : dependsOn) {
					if (isDependent(beanName, dep)) {
					    // 检查是否存在循环依赖
						throw new BeanCreationException(mbd.getResourceDescription(), beanName,
								"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
					}
					// 缓存依赖调用
					registerDependentBean(dep, beanName);
					try {
						getBean(dep);
					}
					catch (NoSuchBeanDefinitionException ex) {
						throw new BeanCreationException(mbd.getResourceDescription(), beanName,
								"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
					}
				}
			}

			// 实例化依赖的bean后便可以实例化 mbd本身了
			// singleton 模式的创建
			// scope == singleton
			// Create bean instance.
			if (mbd.isSingleton()) {
				sharedInstance = getSingleton(beanName, () -> {
					try {
						return createBean(beanName, mbd, args);
					}
					catch (BeansException ex) {
					    // 出现异常 清理工作,从单例缓存中移除
						destroySingleton(beanName);
						throw ex;
					}
				});
				beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
			}

			else if (mbd.isPrototype()) {
				// scope == prototype
				Object prototypeInstance = null;
				try {
				    // 设置正在创建的状态
					beforePrototypeCreation(beanName);
					// 创建bean
					prototypeInstance = createBean(beanName, mbd, args);
				}
				finally {
					afterPrototypeCreation(beanName);
				}
				// 返回对应的实例
				beanInstance = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
			}

			else {
			    // 其它scope
				String scopeName = mbd.getScope();
				if (!StringUtils.hasLength(scopeName)) {
					throw new IllegalStateException("No scope name defined for bean ´" + beanName + "'");
				}
				Scope scope = this.scopes.get(scopeName);
				if (scope == null) {
					throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
				}
				try {
					Object scopedInstance = scope.get(beanName, () -> {
						beforePrototypeCreation(beanName);
						try {
							return createBean(beanName, mbd, args);
						}
						finally {
							afterPrototypeCreation(beanName);
						}
					});
					beanInstance = 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();
		}
	}

	return adaptBeanInstance(name, beanInstance, requiredType);
}

// 检查需要的类型是否符合bean 的实际类型 对应getBean时指定的requireType
@SuppressWarnings("unchecked")
<T> T adaptBeanInstance(String name, Object bean, @Nullable Class<?> requiredType) {
	// Check if required type matches the type of the actual bean instance.
	if (requiredType != null && !requiredType.isInstance(bean)) {
		try {
			Object convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
			if (convertedBean == null) {
				throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
			}
			return (T) 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;
}

对于Bean加载过程中所涉及的步骤大致如下:

  1. 将参数 name 转换成对应的真实 beanName
  2. 检查缓存中或者实例工厂中是否有对应的实例,若存在则进行实例化并返回对象,否则继续往下执
  3. 如果是获取 prototype 类型对象,则检查依赖关系,防止出现循环依赖;
  4. 如果 beanDefinitionMap中也就是在所有已经加载的类中不包括 beanName 则尝试从parentBeanFactory中检测
  5. 将之前解析过程返得到的 GenericBeanDefinition 对象合并为 RootBeanDefinition 对象,如果存在父bean,则同时合并父bean的相关属性
  6. 若存在依赖其它的bean则需要递归实例化依赖的 bean
  7. 依据当前 bean 的作用域对 bean 进行实例化
  8. 如果对返回 bean 类型有要求,则进行类型检查,并做类型转换。
  9. 返回 bean 实例。

1.缓存中获取单例 bean

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

@Override
@Nullable
public Object getSingleton(String beanName) {
	return getSingleton(beanName, true);
}

@Nullable
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
	
	// 检查缓存中是否存在实例 
	// singletonObjects:用于保存BeanName和创建bean实例之间的关系,beanName --> beanInstance
	Object singletonObject = this.singletonObjects.get(beanName);
	// 实例不存在 && 正在创建中
	if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
		/*
		 * earlySingletonObjects: 也是保存 BeanName 和创建 bean 实例之间的关系
		 * 与singletonObjects 的不同之处在于,当一个单例 bean 被放到这里面后,
		 * 那么当bean还在创建中就可以通过 getBean 方法获取到了,其目的是用来检测循环引用。
		 * 也就是Bean实例还处于创建中
		 */
		singletonObject = this.earlySingletonObjects.get(beanName);
		// 如果bean在加载中 则不处理
		if (singletonObject == null && allowEarlyReference) {
			synchronized (this.singletonObjects) {
				// 再次检查缓存 双重检查
				singletonObject = this.singletonObjects.get(beanName);
				if (singletonObject == null) {
					// 再次检查bean是否再创建中
					singletonObject = this.earlySingletonObjects.get(beanName);
					if (singletonObject == null) {
						// 当某些方法需要提前初始化的时候,会调用addSingletonFactory将对应的objectFactory初始化策略存储在singletonFactories中
						ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
						if (singletonFactory != null) {
							// 调用预先设定的 getobject方法
							singletonObject = singletonFactory.getObject();
							// 记录在缓存中,earlySingletonObjects 和 singletonFactories互斥
							this.earlySingletonObjects.put(beanName, singletonObject);
							this.singletonFactories.remove(beanName);
						}
					}
				}
			}
		}
	}
	return singletonObject;
}

这个方法首先尝试从 singletonObjects 里面获取实例,如果获取不到再从 earlySingletonObjects 里面获取,如果还获取不到,再尝试从 singletonFactories 里面获取 beanName 对应的 ObjectFactory,然后调用这个 ObjectFactory 的 getObject 来创建 bean,并放到 earlySingletonObjects里面去,并且从 singletonFactories里面 remove掉这个ObjectFactory,而对于后续的所有内存操作都只为了循环依赖检测时候使用,也就是在allowEarlyReference 为 true的情况下才 会使用.

这里涉及用于存储 bean的不同的map,简单解释如下:
在这里插入图片描述
singletonObjects:单例对象的缓存,用于保存BeanName 和创建bean 实例之间的关系,beanName -> beanInstance

在这里插入图片描述
singletonFactories:用于保存BeanName和创建 bean 的工厂之间的关系,beanName ->ObjectFactory.

在这里插入图片描述
earlySingletonObjects: 也是保存BeanName 和创建 bean 实例之间的关系,与 singletonObjects 的不同之处在于,当一个单例 bean 被放到这里面后,那么当 bean 还 在创建过程中,就可以通过 getBean 方法获取到了,其目的是用来检测循环引用。

在这里插入图片描述
registeredSingletons:用来保存当前所有已注册的 bean。

2.获取单例

如果在上一步 缓存中没有获取到单例 bean ,那么就需要从头开始 bean 的加载过程了,而 Spring 中使用 getSingleton 的重载方法实现bean的加载过程。

// Create bean instance.
if (mbd.isSingleton()) {
	sharedInstance = getSingleton(beanName, () -> {
		try {
			// 创建bean 的真正逻辑
			return createBean(beanName, mbd, args);
		}
		catch (BeansException ex) {
			// 出现异常 清理工作,从单例缓存中移除
			destroySingleton(beanName);
			throw ex;
		}
	});
	beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
/*
返回以给定名称注册的单例对象,如果尚未注册,则创建并注册一个新的单例对象。
*/
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
	Assert.notNull(beanName, "Bean name must not be null");
	// 	全局变量需要加锁
	synchronized (this.singletonObjects) {
		// singletonObjects用于缓存beanName与已创建的单例对象的映射关系
		// 首先检查对应的bean是否已经加载过,因为singleton 模式其实就是复用以创建的 bean,
		// 所以这一步是必须的
		Object singletonObject = this.singletonObjects.get(beanName);
		// 如果为空才可以进行singleto的 bean 的初始化
		if (singletonObject == null) {
			// 当前单例对象是否处于销毁状态
			if (this.singletonsCurrentlyInDestruction) {
				throw new BeanCreationNotAllowedException(beanName,
						"Singleton bean creation not allowed while singletons of this factory are in destruction " +
						"(Do not request a bean from a BeanFactory in a destroy method implementation!)");
			}
			if (logger.isDebugEnabled()) {
				logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
			}
			
			// 前置处理,设置状态为“正在创建中”
			beforeSingletonCreation(beanName);
			// 标识bean是否创建成功
			boolean newSingleton = false;
			boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
			if (recordSuppressedExceptions) {
				this.suppressedExceptions = new LinkedHashSet<>();
			}
			try {
				// 初始化bean  执行的是传进来的 lambda 表达式
				singletonObject = singletonFactory.getObject();
				// 创建成功 标识改为true
				newSingleton = true;
			}
			catch (IllegalStateException ex) {
				// 出现异常,再次尝试从缓存中获取
				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;
	}
}

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

1.检查缓存是否已经加载过。
2.若没有加载,则将 bean 设置状态为“正在创建中”,可以对循环依赖进行检测。
3.实例化 bean,如果过程中出现异常,则再次尝试从缓存中获取实例
4.后置处理,移除“bean正在创建中”的状态
5.将结果记录至缓存并删除加载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 的真正逻辑位于ObjectFactory 的核心部分其createBean 方法,所以我们还需要到 createBean进行探索。

3.创建Bean

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

	if (logger.isTraceEnabled()) {
		logger.trace("Creating instance of bean '" + beanName + "'");
	}
	RootBeanDefinition mbdToUse = mbd;

	// 根据设置的class属性或者根据className 来解析 Class (拿到Class对象)
	Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
	if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
		mbdToUse = new RootBeanDefinition(mbd);
		mbdToUse.setBeanClass(resolvedClass);
	}

	try {
		// 对override属性进行标记和验证,本质上是处理lookup-method和replaced-method标签
		mbdToUse.prepareMethodOverrides();
	}
	catch (BeanDefinitionValidationException ex) {
		throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
				beanName, "Validation of method overrides failed", ex);
	}

	try {
		// BeanPostProcessors 个机会来返回代理来替代真正的实例
		Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
		if (bean != null) {
			// 当经过前置处理后返回的结果如果不为空,那么会直接略过后续的Bean 的创建
			return bean;
		}
	}
	catch (Throwable ex) {
		throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
				"BeanPostProcessor before instantiation of bean failed", ex);
	}

	try {
		// 创建bean实例
		Object beanInstance = doCreateBean(beanName, mbdToUse, args);
		if (logger.isTraceEnabled()) {
			logger.trace("Finished creating instance of bean '" + beanName + "'");
		}
		return beanInstance;
	}
	catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
		throw ex;
	}
	catch (Throwable ex) {
		throw new BeanCreationException(
				mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
	}
}

一个真正干活的函数其实是以do 开头的,这个规则对于 createBean 也不例外,createBean方法主要还是在做一些前期准备工作。而常规bean的创建就是在 doCreateBean中完成的。

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

	// BeanWrapper 可以看作是偏底层的 bean 包装器,提供了对标准 java bean 的分析和操作方法,包括获取和设置属性值、获取属性描述符,以及属性的读写特性等
	BeanWrapper instanceWrapper = null;
	if (mbd.isSingleton()) {
		// 如果是单例则需要首先清除缓存
		instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
	}

	// bean未实例化,创建 bean 实例
	if (instanceWrapper == null) {
		
		/*
		 * 根据指定bean 使用对应的策略创建新的实例,如:工厂方法、构造函数自动注入、简单初始化
		 * 将beanDefinition转成BeanWrapper,大致流程如下:
		 * 1. 如果存在工厂方法,则使用工厂方法初始化
		 * 2. 否则,如果存在多个构造函数,则根据参数确定构造函数,并利用构造函数初始化
		 * 3. 否则,使用默认构造函数初始化
		 */
		instanceWrapper = createBeanInstance(beanName, mbd, args);
	}

	// 从BeanWrapper中获取包装的bean实例
	Object bean = instanceWrapper.getWrappedInstance();

	// 从BeanWrapper获取包装bean的Class对象
	Class<?> beanType = instanceWrapper.getWrappedClass();
	if (beanType != NullBean.class) {
		mbd.resolvedTargetType = beanType;
	}

	// 应用 MergedBeanDefinitionPostProcessor
	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;
		}
	}

	// 是否需要提早曝光:单例&&允许循环依赖&&当前bean正在创建中,检测循环依赖
	boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
			isSingletonCurrentlyInCreation(beanName));
	if (earlySingletonExposure) {
		if (logger.isTraceEnabled()) {
			logger.trace("Eagerly caching bean '" + beanName +
					"' to allow for resolving potential circular references");
		}
		// 为避免后期循环依赖,可以在 bean初始化完成前将创建实例的ObjectFactory 加入工厂
		addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
	}

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

	if (earlySingletonExposure) {
		Object earlySingletonReference = getSingleton(beanName, false);
		// earlySingletonReference只有在检测到有循环依赖的情况下才会不为空
		if (earlySingletonReference != null) {
			// 如果exposedObject 没有在初始化方法中被改变,也就是没有被增强
			if (exposedObject == bean) { 
				exposedObject = earlySingletonReference;
			}
			else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
				// 获取依赖的bean的name
				String[] dependentBeans = getDependentBeans(beanName);
				Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
				for (String dependentBean : dependentBeans) {
					if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
						// 检测依赖,记录未完成创建的bean
						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.");
				}
			}
		}
	}

	try {
		// 注册DisposableBean
		registerDisposableBeanIfNecessary(beanName, bean, mbd);
	}
	catch (BeanDefinitionValidationException ex) {
		throw new BeanCreationException(
				mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
	}

	return exposedObject;
}

我们看看整个函数的概要思路:
1.如果是单例则需要首先清除缓存。
2.实例化 bean, 将 BeanDefinition 转换为BeanWrapper
3.MergedBeanDefinitionPostProcessor 的应用
4.依赖处理:在 Spring 中会有循环依赖的情况,例如,当A中含有B的属性,而B中又含有A的属性 时就会构成一个循环依赖,此时如果A和B都是单例,那么在Spring 中的处理方式就是当创 建B的时候,涉及自动注入A的步骤时,并不是直接去再次创建A,而是通过放入缓存中的 ObjectFactory来创建实例,这样就解决了循环依赖的问题。
5.属性填充。将所有属性填充至 bean 的实例中
6.循环依赖检查:之前有提到过,在 Sping中解决循环依赖只对单例有效,而对于prototype 的 bean, Spring 没有好的解决办法,唯一要做的就是抛出异常。在这个步骤里面会检测已经加载的bean 是否 已经出现了依赖循环,并判断是否需要抛出异常。
7.注册DisposableBean

创建Bean实例createBeanInstance

将 BeanDefinition 转换为BeanWrapper
使用适当的实例化策略为指定的bean创建一个新实例:工厂方法、构造函数自动注入、简单初始化

// 使用适当的实例化策略为指定的bean创建一个新实例:工厂方法、构造函数自动注入、简单初始化
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
	// 解析Class
	Class<?> beanClass = resolveBeanClass(mbd, beanName);

	// 判断是否允许被创建 , 不允许则直接抛异常
	if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
		throw new BeanCreationException(mbd.getResourceDescription(), beanName,
				"Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
	}

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

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

	// 利用构造函数进行实例化,解析并确定目标构造函数
	boolean resolved = false;
	boolean autowireNecessary = false;
	if (args == null) {
		synchronized (mbd.constructorArgumentLock) {
			// 一个类可能有多个构造函数,需要根据参数来确定具体的构造函数
			if (mbd.resolvedConstructorOrFactoryMethod != null) {
				resolved = true;
				autowireNecessary = mbd.constructorArgumentsResolved;
			}
		}
	}
	// 如果已经解析过,则使用已经确定的构造方法
	if (resolved) {
		if (autowireNecessary) {
			// 依据构造函数注入
			return autowireConstructor(beanName, mbd, null, null);
		}
		else {
			// 使用默认构造函数构造
			return instantiateBean(beanName, mbd);
		}
	}

	// 需要根据参数决定使用哪个构造函数
	Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
	if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
			mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
		return autowireConstructor(beanName, mbd, ctors, args);
	}

	ctors = mbd.getPreferredConstructors();
	if (ctors != null) {
		// 构造函数自动注入
		return autowireConstructor(beanName, mbd, ctors, null);
	}

	// 使用默认构造函数构造 无参构造器
	return instantiateBean(beanName, mbd);
}

我们这里看下使用默认构造函数实例化给定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);
		}
		// 利用包装器包装bean实例
		BeanWrapper bw = new BeanWrapperImpl(beanInstance);
		initBeanWrapper(bw);
		return bw;
	}
	catch (Throwable ex) {
		throw new BeanCreationException(
				mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
	}
}

到这里得到的也仅仅是一个 bean 的最初实例,还不是我们最终期望的 bean,因为后面还需要对 bean 实例进行初始化处理,注入相应的属性值等。

属性注入populateBean

将所有属性填充至 bean 的实例中

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

	if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
		for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
			if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
				return;
			}
		}
	}

	// 属性集合 age 和 name
	PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);

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

	if (pvs != null) {
		// 属性值设值
		applyPropertyValues(beanName, mbd, bw, pvs);
	}
}

applyPropertyValues属性值设值

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中的值已经被转换为对应的类型那么可以直接设置到beanwapper 中
		if (mpvs.isConverted()) {
			try {
				bw.setPropertyValues(mpvs);
				return;
			}
			catch (BeansException ex) {
				throw new BeanCreationException(
						mbd.getResourceDescription(), beanName, "Error setting property values", ex);
			}
		}
		// 拿到属性名 和 属性值 age name 26 zhangsan
		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);

	List<PropertyValue> deepCopy = new ArrayList<>(original.size());
	boolean resolveNecessary = false;
	// 遍历属性,将属性转换为对应类的对应属性的类型
	for (PropertyValue pv : original) {
		if (pv.isConverted()) {
			deepCopy.add(pv);
		}
		else {
			String propertyName = pv.getName(); // 属性名 age name
			Object originalValue = pv.getValue(); // 属性值
			if (originalValue == AutowiredPropertyMarker.INSTANCE) {
				Method writeMethod = bw.getPropertyDescriptor(propertyName).getWriteMethod();
				if (writeMethod == null) {
					throw new IllegalArgumentException("Autowire marker for property without write method: " + pv);
				}
				originalValue = new DependencyDescriptor(new MethodParameter(writeMethod, 0), true);
			}
			Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);
			Object convertedValue = resolvedValue;
			boolean convertible = bw.isWritableProperty(propertyName) &&
					!PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName);
			if (convertible) {
				// 属性值转换
				convertedValue = convertForProperty(resolvedValue, propertyName, bw, converter);
			}
	
			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();
	}
	try {
		bw.setPropertyValues(new MutablePropertyValues(deepCopy));
	}
	catch (BeansException ex) {
		throw new BeanCreationException(
				mbd.getResourceDescription(), beanName, "Error setting property values", ex);
	}
}

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

protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
	if (System.getSecurityManager() != null) {
		AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
			invokeAwareMethods(beanName, bean);
			return null;
		}, getAccessControlContext());
	}
	else {
		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;
}

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

protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) {
	AccessControlContext acc = (System.getSecurityManager() != null ? getAccessControlContext() : null);
	if (!mbd.isPrototype() && requiresDestruction(bean, mbd)) {
		if (mbd.isSingleton()) {
			// 单例模式下注册需要销毁的bean
			// 记录到
			// private final Map<String, Object> disposableBeans = new LinkedHashMap<>();
			registerDisposableBean(beanName, new DisposableBeanAdapter(
					bean, beanName, mbd, getBeanPostProcessorCache().destructionAware, 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, getBeanPostProcessorCache().destructionAware, acc));
		}
	}
}

4.关于Spring Bean的创建流程总结

  1. Spring所管理的Bean实际上是缓存在一个ConcurrentHashMap中的(singletonObjects对象中)。
  2. 该对象本质上是一个key-value对的形式,key指的是bean的名字(id),value是一个Object对象,就是所创建的bean对象。
  3. 在创建Bean之前,首先需要将该Bean的创建标识制定好,表示该Bean已经或是即将被创建,目的是增强缓存的效率。
  4. 根据bean的scope属性来确定当前这个bean是一个singleton还是一个prototype的bean,然后创建相应的对象。
  5. 无论是singleton还是prototype的bean,其创建的过程是一致的。
  6. 通过Java反射机制来创建Bean的实例,在创建之前需要检查构造方法的访问修饰符,如果不是public的,则会调用setAccessible(true) 方法来突破Java的语法限制,使得可以通过非public构造方法来完成对象实例的创建。
  7. 当对象创建完毕后,开始进行对象属性的注入。
  8. 在对象属性注入的过程中,Spring除了去使用之前通过BeanDefinition对象获取的Bean信息外,还会通过反射的方式获取到上面所创建的Bean中的真实属性信息(还包括一个class属性,表示该Bean所对应的class类型)。
  9. 完成Bean属性的注入(或者抛出异常)
  10. 如果Bean是一个单例的,那么将所创建出来的Bean添加到singletonObjects对象中(缓存中),供程序后续再次使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值