栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

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

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

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 getBean(String name, Class 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 getBean(String name, @Nullable Class requiredType, @Nullable Object... args)
		throws BeansException {

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

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

protected  T doGetBean(
		String name, @Nullable Class requiredType, @Nullable Object[] args, boolean typeCheckOnly)
		throws BeansException {

	
	String beanName = transformedBeanName(name);
	Object beanInstance;

	
	// 直接尝试从缓存获取 或者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 {
		
		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 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加载过程中所涉及的步骤大致如下:

    将参数 name 转换成对应的真实 beanName检查缓存中或者实例工厂中是否有对应的实例,若存在则进行实例化并返回对象,否则继续往下执如果是获取 prototype 类型对象,则检查依赖关系,防止出现循环依赖;如果 beanDefinitionMap中也就是在所有已经加载的类中不包括 beanName 则尝试从parentBeanFactory中检测将之前解析过程返得到的 GenericBeanDefinition 对象合并为 RootBeanDefinition 对象,如果存在父bean,则同时合并父bean的相关属性若存在依赖其它的bean则需要递归实例化依赖的 bean依据当前 bean 的作用域对 bean 进行实例化如果对返回 bean 类型有要求,则进行类型检查,并做类型转换。返回 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)) {
		
		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) {
		
		
		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 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) () -> 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 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 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) () -> {
			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 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的创建流程总结
    Spring所管理的Bean实际上是缓存在一个ConcurrentHashMap中的(singletonObjects对象中)。该对象本质上是一个key-value对的形式,key指的是bean的名字(id),value是一个Object对象,就是所创建的bean对象。在创建Bean之前,首先需要将该Bean的创建标识制定好,表示该Bean已经或是即将被创建,目的是增强缓存的效率。根据bean的scope属性来确定当前这个bean是一个singleton还是一个prototype的bean,然后创建相应的对象。无论是singleton还是prototype的bean,其创建的过程是一致的。通过Java反射机制来创建Bean的实例,在创建之前需要检查构造方法的访问修饰符,如果不是public的,则会调用setAccessible(true) 方法来突破Java的语法限制,使得可以通过非public构造方法来完成对象实例的创建。当对象创建完毕后,开始进行对象属性的注入。在对象属性注入的过程中,Spring除了去使用之前通过BeanDefinition对象获取的Bean信息外,还会通过反射的方式获取到上面所创建的Bean中的真实属性信息(还包括一个class属性,表示该Bean所对应的class类型)。完成Bean属性的注入(或者抛出异常)如果Bean是一个单例的,那么将所创建出来的Bean添加到singletonObjects对象中(缓存中),供程序后续再次使用。
转载请注明:文章转载自 www.mshxw.com
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号