Spring源码——bean的加载

经过上一节的分析,我们完成了通过xmlBeanFactory容器初始化的内容,后面会继续讲解关于AplicationContext容器初始化的讲解。这一节我们主要分析的是bean的加载,及getBean方法的过程及原理实现。首先我们整体看一下getBean方法真正的执行者doGetBean方法,该方法在AbstractBeanFactory中,下面进入正题!

@Override
	public Object getBean(String name) throws BeansException {
        //我们从源码中不能难到,真正干事情的都是以do开头的
		return doGetBean(name, null, null, false);
	}

	protected <T> T doGetBean(
			final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly){
        //提取对应的beanName,比如说有alias等等
		final String beanName = transformedBeanName(name);
		Object bean;

		/*检测缓存中或者实例工厂中是否有对应的实例,在创建单例bean的时候会存在依赖注入的情况,
         *而在创建依赖的时候为了避免循环依赖,spring的原则是不等bean创建完成就会将创建bean的                                
         *ObjectFactory提早曝光,也就是将其放入到缓存中,
         *一旦下个bean创建时候需要依赖上个bean则直接使用ObjectFactory,直接尝试从缓存获取或者            
         *singletonFactor中的ObjectFactory中获取
        */
		Object sharedInstance = getSingleton(beanName);
		if (sharedInstance != null && args == null) {
            //返回对应实例,有时候不是返回实例本身,有可能是FactoryBean的getObject方法之类
			bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
		}

		else {
			//只有单例才会尝试解决循环依赖
			if (isPrototypeCurrentlyInCreation(beanName)) {
				throw new BeanCurrentlyInCreationException(beanName);
			}

			//如果beanDefinitionMap中不包括beanName则尝试从parentBeanFactor中检测
			BeanFactory parentBeanFactory = getParentBeanFactory();
			if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
				String nameToLookup = originalBeanName(name);
				if (args != null) {
					// 递归到BeanFactory中找
					return (T) parentBeanFactory.getBean(nameToLookup, args);
				}
				else {
					return parentBeanFactory.getBean(nameToLookup, requiredType);
				}
			}
            //如果不是仅仅做类型检查则是创建bean,这里要记录
			if (!typeCheckOnly) {
				markBeanAsCreated(beanName);
			}

			try {
        //将GernericBeanDefinition转换为RootBeandefinition,如果指定BeanName是子Bean的话会合并父类的属性
				final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
				checkMergedBeanDefinition(mbd, beanName, args);

				//若存在依赖则需要递归实例化依赖的bean.
				String[] dependsOn = mbd.getDependsOn();
				if (dependsOn != null) {
					for (String dep : dependsOn) {
						if (isDependent(beanName, dep)) {
                        //缓存依赖调用
						registerDependentBean(dep, beanName);
						getBean(dep);
					}
				}

				// 实例化mbd本身.
				if (mbd.isSingleton()) {
					sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
						@Override
						public Object getObject() throws BeansException {
							try {
								return createBean(beanName, mbd, args);
							}
						}
					});
                //返回对应实例,有时候不是返回实例本身,有可能是FactoryBean的getObject方法之类
					bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
				}

				else if (mbd.isPrototype()) {
					//prototype模式创建bean
					Object prototypeInstance = null;
					try {
						beforePrototypeCreation(beanName);
						prototypeInstance = createBean(beanName, mbd, args);
					}
					finally {
						afterPrototypeCreation(beanName);
					}
					bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
				}

				else {
                    //指定的scope上实例bean
					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, new ObjectFactory<Object>() {
							@Override
							public Object getObject() throws BeansException {
								beforePrototypeCreation(beanName);
								try {
									return createBean(beanName, mbd, args);
								}
								finally {
									afterPrototypeCreation(beanName);
								}
							}
						});
						bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
			}
		}

		//检查需要的类型是否符合bean的实际类型.
		if (requiredType != null && bean != null && !requiredType.isAssignableFrom(bean.getClass())) {
			try {
				return getTypeConverter().convertIfNecessary(bean, requiredType);
			}
		}
		return (T) bean;
	}

不难看出bean的加载经历了一个相当复杂的过程,从注释可以粗略的了解整个spring加载bean的过程。大致步骤如下:

  1. 转换对应的bean:传入的参数可能是别名,也有可能是FactoryBean,所以需要解析
  2. 尝试从缓存中加载单例:单例在容器中只会创建一次,后面直接从单例缓存中获取。当然这里只是尝试加载,首先尝试从缓存中加载,然后再尝试从singletonFactories中加载,因为在创建单例Bean的时候会存在依赖注入的情况,而在创建依赖的时候为了避免循环依赖,不等bean创建完成就会将bean的ObjectFactory提早曝光加入到缓存中,一旦下一个需要则直接使用ObejctFactory
  3. bean的实例化:记录的只是最原始的bean状态,不一定是我们最终想要的bean,比如factoryBean
  4. 原型模式的依赖检查
  5. 检测parentBeanFatory
  6. 将GernericBeanDefinition转换为RootBeanDefinition:转换同时如果父类bean不为空的话会合并父类属性
  7. 寻找依赖:在初始化某一个bean的时候首先会初始化这个bean所对应的依赖
  8. 针对不同的scope进行bean的创建
  9. 类型转换

下面我们就将注意进行分析

缓存中获取单例Bean

跟踪代码来到DefaultSingletonBeanRegistry

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) {
                    //当某些方法需要提前初始化的时候会将对应的objectFactory存在singletonFactories
					ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
					if (singletonFactory != null) {
                        //调用预先设定的getObject方法
						singletonObject = singletonFactory.getObject();
                        //记录在缓存中,以下两者互斥
						this.earlySingletonObjects.put(beanName, singletonObject);
						this.singletonFactories.remove(beanName);
					}
				}
			}
		}
		return (singletonObject != NULL_OBJECT ? singletonObject : null);
	}

这个方法首先从singletonObjects中获取实例,获取不到再到erlySingletonObejcts中获取,还获取不到就到singletonFactoryies中获取ObjectFatory的getObject获取bean

Bean的实例化

getObjectForBeanInstanse方法在getBean中是个高频少用的方法,无论从缓存中获取还是根据不同的scope策略加载,总之,我们得到bean的实例后第一步就是调用此方法,检测当前bean 是否是FactoryBean,如果是,那么需要调用该bean对应的getObject方法作为返回值。

protected Object getObjectForBeanInstance(
			Object beanInstance, String name, String beanName, RootBeanDefinition mbd) {
        //如果指定的name是工厂相关(以&为前缀)且又不是FactoryBean类型则验证不通过
		if (BeanFactoryUtils.isFactoryDereference(name) && !(beanInstance instanceof FactoryBean)) {
			throw new BeanIsNotAFactoryException(transformedBeanName(name), beanInstance.getClass());
		}

		// Now we have the bean instance, which may be a normal bean or a FactoryBean.
		// If it's a FactoryBean, we use it to create a bean instance, unless the
		// caller actually wants a reference to the factory.
		if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {
			return beanInstance;
		}
        //加载FactoryBean
		Object object = null;
		if (mbd == null) {
            //从缓存中加载bean
			object = getCachedObjectForFactoryBean(beanName);
		}
		if (object == null) {
			// 到这儿已经知道是FactoryBean类型.
			FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
			// 检测beanDifinitionMap中是否已经定义了beanName.
			if (mbd == null && containsBeanDefinition(beanName)) {
				mbd = getMergedLocalBeanDefinition(beanName);
			}
            //是否是用户定义的而不是应用程序本身定义的
			boolean synthetic = (mbd != null && mbd.isSynthetic());
			object = getObjectFromFactoryBean(factory, beanName, !synthetic);
		}
		return object;
	}
  1. 对FactoryBean正确性的验证
  2. 对非FactoryBean不做任何处理
  3. 对bean进行转换
  4. 将从Factory中解析bean的工作委托给getObjectFromFactoryBean
	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);
					Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
					if (alreadyThere != null) {
						object = alreadyThere;
					}
					else {
						if (object != null && shouldPostProcess) {
							try {
                                //调用ObjectFactory的后处理器
								object = postProcessObjectFromFactoryBean(object, beanName);
							}
						}
						this.factoryBeanObjectCache.put(beanName, (object != null ? object : NULL_OBJECT));
					}
				}
				return (object != NULL_OBJECT ? object : null);
			}
		}
		else {
			Object object = doGetObjectFromFactoryBean(factory, beanName);
			if (object != null && shouldPostProcess) {
				try {//调用ObjectFactory的后处理器
					object = postProcessObjectFromFactoryBean(object, beanName);
				}
			}
			return object;
		}
	}

此方法做了一件事就是返回的bean如果是单例,就必须保证全局唯一性,同时利用缓存来提升性能,然后调用了ObejctFactory的后处理器对object进行处理,下面进入doGetObjectFromFactoryBean方法

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(new PrivilegedExceptionAction<Object>() {
						@Override
						public Object run() throws Exception {
								return factory.getObject();
							}
						}, acc);
				}
				catch (PrivilegedActionException pae) {
					throw pae.getException();
				}
			}
            //直接调用getObject方法
			else {
				object = factory.getObject();
			}
		}


		if (object == null && isSingletonCurrentlyInCreation(beanName)) {
			throw new BeanCurrentlyInCreationException(
					beanName, "FactoryBean which is currently in creation returned null from getObject");
		}
		return object;
	}

返回了这个factory.getObejct后回到下面看看后处理,跟进代码来到AbstractAutowireObjectFromFactoryBean中

	protected Object postProcessObjectFromFactoryBean(Object object, String beanName) {
		return applyBeanPostProcessorsAfterInitialization(object, beanName);
	}

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

 

后面会做详细描述,在此我们只要了解尽可能保证所有bean初始化后都会调用注册的BeanPostProcessor的postProcessAfterInitialization方法进行处理,在实际开发过程中大可以针对此特性设计自己的业务逻辑

获取单例

上面我们分析了从缓存中获取单例,那么如果缓存中不存在加载的单例bean就是要重头开始bean的加载过程了

	public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
		//锁住全局变量
		synchronized (this.singletonObjects) {
            //检测是否已经加载
			Object singletonObject = this.singletonObjects.get(beanName);
			if (singletonObject == null) {
				if (this.singletonsCurrentlyInDestruction) {
					throw new BeanCreationNotAllowedException(beanName,
				}
				}
				beforeSingletonCreation(beanName);
				boolean newSingleton = false;
				boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
				if (recordSuppressedExceptions) {
					this.suppressedExceptions = new LinkedHashSet<Exception>();
				}
				try {
                    //初始化bean
					singletonObject = singletonFactory.getObject();
					newSingleton = true;
				}
				finally {
					if (recordSuppressedExceptions) {
						this.suppressedExceptions = null;
					}
					afterSingletonCreation(beanName);
				}
				if (newSingleton) {
                    //加入缓存
					addSingleton(beanName, singletonObject);
				}
			}
			return (singletonObject != NULL_OBJECT ? singletonObject : null);
		}
	}
  1. 检查缓存是否已经加载过
  2. 若没有加载,则记录beanName的正在加载状态
  3. 加载单例前记录加载状态(beforeSingletonCreation),便于对循环依赖进行检测
  4. 实例化bean
  5. 加载单例后处理的方法(afterSingletonCreation),移除正在加载状态
  6. 将结果记录至缓存并删除bean加载过程中的各种辅助状态
  7. 返回处理结果,核心只是调用了ObjectFactory中的createBean方法,所以我们要回到doGetBean方法中的createBean中去
	protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
		RootBeanDefinition mbdToUse = mbd;

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

		// 验证及准备覆盖的方法.
		try {
			mbdToUse.prepareMethodOverrides();
		}
	    try {
			//给BeanPostProcessors机会来返回一个代理实例
			Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
			if (bean != null) {
				return bean;
			}
		}
        //具体创建bean
		Object beanInstance = doCreateBean(beanName, mbdToUse, args);
		return beanInstance;
	}
  1. 根据设置的class属性或者根据className属性来解析Class
  2. 对override属性进行标记及验证
  3. 应用初始化的后处理器
  4. 创建bean

在调用doCreateBean之前调用了resolveBeforeInstantiation方法对BeanDefinition中的属性做些前置处理,当前置处理后返回的不为空,那么直接略过创建而直接返回结果,我们熟知的Aop功能呢=就是基于这里判断的。

protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
		Object bean = null;
        //如果尚未被解析
		if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
			// Make sure bean class is actually resolved at this point.
			if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
				Class<?> targetType = determineTargetType(beanName, mbd);
				if (targetType != null) {
					bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
					if (bean != null) {
						bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
					}
				}
			}
			mbd.beforeInstantiationResolved = (bean != null);
		}
		return bean;
	}

此方法中最吸引我们的无疑是applyBeanPostProcessorsBeforeInstantiation以及applyBeanPostProcessorsAfterInstantiation。无非是对后处理器中的所有InstantiationAwareBeanPostProcessor类型的后处理器进行postProcessBeforeInstantiation方法和BeanPostProcessor的postProcessAfterInitialization方法的调用

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

循环依赖

对于构造循环依赖,spring无法处理,对于setter循环依赖是通过spring提前暴露刚完成构造器注入但未完成其他步骤的bean来完成的,而且只能是单例作用域的bean,通过提前暴露一个单例工厂方法,从而使其他bean能引用到该bean。下面我们接着上面的如果后置处理器返回结果为空后的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改变beanDefinition
					applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
				}
				mbd.postProcessed = true;
			}
		}

		// 是否需要提早曝光:单例&允许循环依赖&当前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 {
                    //其中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) {
				exposedObject = initializeBean(beanName, exposedObject, mbd);
			}
		}
		}

		if (earlySingletonExposure) {
			Object earlySingletonReference = getSingleton(beanName, false);
            //earlyingletonReference 只有检测到有循环依赖的情况下才不为空
			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)
					}
				}
			}
		}

		// 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转换为BeanWraper
  3. MergedBeanDefinitionPostProcessor的应用:bean合并后的处理,Autowired注解正式通过此方法实现诸如类型的预解析
  4. 依赖处理
  5. 填充属性
  6. 循环依赖检查
  7. 注册DisosableBean
  8. 完成创建并返回

参考:《sping源码深度解析》

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值