亲宝软件园·资讯

展开

spring获取bean源码 spring获取bean的源码解析

not back 人气:0
想了解spring获取bean的源码解析的相关内容吗,not back在本文为您仔细讲解spring获取bean源码的相关知识和一些Code实例,欢迎阅读和指正,我们先划重点:spring获取bean源码,spring,bean源码,下面大家一起来学习吧。

介绍

前面一章说了AbstractApplicationContext中的refresh方法中的invokeBeanFactoryPostProcessors。主要是调用BeanFactoryPostProcessor。其中也有获取bean的过程,就是beanFactory.getBean的方法。这一章就说下getBean这个方法。由于spring中获取bean的方法比较复杂,涉及到的流程也非常多,这一章就先说下整个大体的流程。其中的细节会在后面也会慢慢说。

源码

直接看源码吧

@Override
	public Object getBean(String name) throws BeansException {
		return doGetBean(name, null, null, false);
	}
 
	@Override
	public <T> T getBean(String name, @Nullable 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);
	}
 
 
	@SuppressWarnings("unchecked")
	protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
			@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
        
        // 把name转化成beanName,也就是把FactoryBean的名称转化成beanName如果有别名则用别名
		final String beanName = transformedBeanName(name);
		Object bean;
 
		// 从缓存中获取实例
        // 可能是需要的Bean实例,也可能是FactoryBean
		Object sharedInstance = getSingleton(beanName);
		if (sharedInstance != null && args == null) {
			if (logger.isDebugEnabled()) {
				if (isSingletonCurrentlyInCreation(beanName)) {
					logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +
							"' that is not fully initialized yet - a consequence of a circular reference");
				}
				else {
					logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
				}
			}
            // 获取需要的bean或者FactoryBean
			bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
		}
 
		else {
			// 判断prototype类型的bean是否存在循环引用
			if (isPrototypeCurrentlyInCreation(beanName)) {
				throw new BeanCurrentlyInCreationException(beanName);
			}
 
			// 校验父类BeanFactory
			BeanFactory parentBeanFactory = getParentBeanFactory();
			if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
				// 父类去获取bean
				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 {
					// No args -> delegate to standard getBean method.
					return parentBeanFactory.getBean(nameToLookup, requiredType);
				}
			}
            
            // 标记成已创建
			if (!typeCheckOnly) {
				markBeanAsCreated(beanName);
			}
 
			try {
                // 把原来BeanDefinition转换成RootBeanDefinition
				final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
				checkMergedBeanDefinition(mbd, beanName, args);
 
				// 获取依赖的bean,也就是通过@DependsOn注入进来的bean
				String[] dependsOn = mbd.getDependsOn();
				if (dependsOn != null) {
					for (String dep : dependsOn) {
                        // 校验dependsOn的bean是否存在循环应用
						if (isDependent(beanName, dep)) {
							throw new BeanCreationException(mbd.getResourceDescription(), beanName,
									"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
						}
                        // 加入到引用的缓存中,由于校验dependsOn循环引用
						registerDependentBean(dep, beanName);
                        // 获取@dependsOn的bean
						getBean(dep);
					}
				}
 
				// 创建单例的bean
				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或者FactoryBean
					bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
				}
                // 创建prototype的bean
				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);
				}
                // 创建其他的bean,比如session,request等
				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的实例类型,则进行转换
		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.isDebugEnabled()) {
					logger.debug("Failed to convert bean '" + name + "' to required type '" +
							ClassUtils.getQualifiedName(requiredType) + "'", ex);
				}
				throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
			}
		}
		return (T) bean;
	}

获取bean的整体流程就像上面源码所示,这里再梳理下spring获取bean的整个流程

1.先转换bean的名称,转换成beanName。这里意思就是,我们在获取bean的时候,可能是FactoryBean的名称(&开头),这里转成不带&开头的名称,如果有别名,再获取别名。

2.从缓存中获取bean,这里的缓存分为一二三级缓存,也就是我们常常被问到了spring三级缓存,具体逻辑下面再说。

3.根据获取的到对象再去获取我们想要的bean,因为这里获取到的对象可能是我们需要的bean,也可能是FactoryBean。

4.如果缓存中没有,那么我们就要自己去创建bean了。

5.查看有没有父类的BeanFactory,如果有,那么就父类去创建bean。

6.获取要创建的bean对象的@DependsOn注解上的名称,先去创建DependsOn的bean,并且校验是否存在循环引用

7.创建bean,根据类型创建不同的bean,比如singleton,prototype,request,session等。

8.如果需要转换类型,则进行类型转换。

整体的获取bean的流程就是这样了,其中有些具体流程接着分析。

从缓存中获取bean对象

public Object getSingleton(String beanName) {
		return getSingleton(beanName, true);
	}
 
 
	@Nullable
	protected Object getSingleton(String beanName, boolean allowEarlyReference) {
        // 从一级缓存中获取
		Object singletonObject = this.singletonObjects.get(beanName);
		if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
			synchronized (this.singletonObjects) {
                // 从二级缓存中获取
				singletonObject = this.earlySingletonObjects.get(beanName);
				if (singletonObject == null && allowEarlyReference) {
                    // 从三级缓存中获取
					ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
					if (singletonFactory != null) {
						singletonObject = singletonFactory.getObject();
						this.earlySingletonObjects.put(beanName, singletonObject);
						this.singletonFactories.remove(beanName);
					}
				}
			}
		}
		return singletonObject;
	}

spring通过三级缓存来解决循环依赖的问题。简单来介绍下三级缓存。

1. singletonObjects为一级缓存,我们实例化的bean都在这个map里,侠义的说singletonObjects才是我们真正的spring容器,存放bean的地方。

2. earlySingletonObjects为二级缓存,是存放未完成的bean的缓存,如果有代理的话,存放的是代理对象。

3. singletonFactories为三级缓存,存放的是一个ObjectFactory,数据通过getObject方法获得。

从BeanInstance中获取对象

接下来看getObjectForBeanInstance方法。

	protected Object getObjectForBeanInstance(
			Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {
 
        // name是不是factoryBean的name(&开头的)
		if (BeanFactoryUtils.isFactoryDereference(name)) {
			if (beanInstance instanceof NullBean) {
				return beanInstance;
			}
            // 如果是FactoryBeanName,但是获取到的bean不是FactoryBean,则抛异常
			if (!(beanInstance instanceof FactoryBean)) {
				throw new BeanIsNotAFactoryException(transformedBeanName(name), beanInstance.getClass());
			}
		}
 
        // 如果bean不是FactoryBean,或者名称是FactoryBeanName,直接返回BeanInstace
		if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {
			return beanInstance;
		}
 
		Object object = null;
		if (mbd == null) {
            // 从缓存中获取
			object = getCachedObjectForFactoryBean(beanName);
		}
		if (object == null) {
			// 这里可以确定beanInstance是FactoryBean了
			FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
			// Caches object obtained from FactoryBean if it is a singleton.
			if (mbd == null && containsBeanDefinition(beanName)) {
				mbd = getMergedLocalBeanDefinition(beanName);
			}
			boolean synthetic = (mbd != null && mbd.isSynthetic());
            // 通过FactoryFBean中获取需要的beanInstance
			object = getObjectFromFactoryBean(factory, beanName, !synthetic);
		}
		return object;
	}

这里是通过BeanInstance获取我们想要的bean,这里也简单说下流程

1. 首先判断name是不是FactoryBean的name,也就是&开头的name,如果是去判断beanInstance是不是FactoryBean,如果beanInstance不是FactoryBean则抛异常。

2. 由于上面已经判断过,如果name是FactoryBeanName,但是BeanInstance不是FactoryBean的话,就会抛出异常。所以如果BeanInstance如果不是FactoryBean的话,那么name一定不是FactoryBeanName。那么就直接返回BeanInstance就是我们需要的了。

如果name是FactoryBeanName,那么我们需要获取的就是FactoryBean,也直接返回就可以了。

3. 如果都没有返回,那么已经可以确定我们此时的已经可以确定BeanInstance是FactoryBean了,因为如果不是FactoryBean的话,在!(beanInstance instanceof FactoryBean)就已经返回了。

4. 通过FactoryBean的getObject方法获取我们需要的bean实例。

创建bean

根据@dependsOn查找依赖的bean并且加到依赖里面去没有什么好说的,代码逻辑也很简单,接下来看创建单例bean。其他类型的bean的创建也都差别不大。看源码

	public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
		Assert.notNull(beanName, "Bean name must not be null");
		synchronized (this.singletonObjects) {
            // 直接从一级缓存中取
			Object singletonObject = this.singletonObjects.get(beanName);
			if (singletonObject == null) {
				if (this.singletonsCurrentlyInDestruction) {
					throw new BeanCreationNotAllowedException(beanName,
							"Singleton bean creation not allowed while singletons of this factory are in destruction " +
							"(Do not request a bean from a BeanFactory in a destroy method implementation!)");
				}
				if (logger.isDebugEnabled()) {
					logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
				}
                // 在没创建bean之前的处理
				beforeSingletonCreation(beanName);
				boolean newSingleton = false;
				boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
				if (recordSuppressedExceptions) {
					this.suppressedExceptions = new LinkedHashSet<>();
				}
				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;
		}
	}

对于创建单例bean的主要流程就是如此,传入一个beanName,和一个ObjectFactory。ObjectFactory中具体实现了创建bean的逻辑。在看具体创建bean的逻辑之前,我们还需要去看下getSingleton中的创建bean之前的工作和创建bean之后的工作。这里面就是查找bean的循环依赖的方法(和dependsOn不同)。主要是查找根据filed,set,构造器方法的循环依赖。

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

可以看到代码非常的简单,就是创建bean之前,如果没有排除依赖检查,那么就加入到正在创建的Set中,如果加入不进去,说明之前已经加过,这就产生了循环依赖,从而抛出异常。

如果在创建bean之后,没有排除检查依赖,并且移除失败,说明已经不在Set中,也会抛出异常。

好了,既然明白了spring是如何校验循环依赖的,也看到了三级缓存,后面再说为什么不能解决构造器依赖就很好说了。接着看创建bean的方法。

protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
			throws BeanCreationException {
 
		if (logger.isDebugEnabled()) {
			logger.debug("Creating instance of bean '" + beanName + "'");
		}
		RootBeanDefinition mbdToUse = mbd;
        
        // 获取要创建bean的class
		Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
		if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
            // 如果没有beanclass,设置beanclass
			mbdToUse = new RootBeanDefinition(mbd);
			mbdToUse.setBeanClass(resolvedClass);
		}
 
		// 配置方法重载
		try {
			mbdToUse.prepareMethodOverrides();
		}
		catch (BeanDefinitionValidationException ex) {
			throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
					beanName, "Validation of method overrides failed", ex);
		}
 
		try {
			// 那些beanPostProcessor如果能产生代理,则直接返回bean
			Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
			if (bean != null) {
				return bean;
			}
		}
		catch (Throwable ex) {
			throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
					"BeanPostProcessor before instantiation of bean failed", ex);
		}
 
		try {
            // 创建bean
			Object beanInstance = doCreateBean(beanName, mbdToUse, args);
			if (logger.isDebugEnabled()) {
				logger.debug("Finished creating instance of bean '" + beanName + "'");
			}
			return beanInstance;
		}
		catch (BeanCreationException ex) {
			// A previously detected exception with proper bean creation context already...
			throw ex;
		}
		catch (ImplicitlyAppearedSingletonException ex) {
			// An IllegalStateException to be communicated up to DefaultSingletonBeanRegistry...
			throw ex;
		}
		catch (Throwable ex) {
			throw new BeanCreationException(
					mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
		}
	}

这里其实还是没有到创建bean的过程,还是在创建bean的一些准备工作。其实我们可以发现,spring中,真正做事的都是do开头的方法。

这边的流程就是设置beanClass,后面需要根据反射来创建bean。然后会根据spring里面的beanPostProcessor,看看有没有能产生代理bean的,如果有就返回,没有就去创建bean。

看真正的doCreateBean方法

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
			throws BeanCreationException {
 
		// 装饰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.getWrappedInstance();
		Class<?> beanType = instanceWrapper.getWrappedClass();
		if (beanType != NullBean.class) {
			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;
			}
		}
 
		// 加入到三级缓存中去
		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");
			}
			addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
		}
 
		// Initialize the bean instance.
		Object exposedObject = bean;
		try {
            // 填充依赖的bean,field注入,和方法注入的bean
			populateBean(beanName, mbd, instanceWrapper);
            // 调用初始化的方法
			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);
			if (earlySingletonReference != null) {
                // 如果一致,则直接使用二级缓存的对象
				if (exposedObject == bean) {
					exposedObject = earlySingletonReference;
				}
                // 如果调用初始化后的bean和之前的bean不一致,并且有依赖
				else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
                    // 查找循环依赖
					String[] dependentBeans = getDependentBeans(beanName);
					Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
					for (String dependentBean : dependentBeans) {
                        // 如果有循环依赖并且在创建中,则抛出异常
						if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
							actualDependentBeans.add(dependentBean);
						}
					}
					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.");
					}
				}
			}
		}
 
		// 注册disposableBean
		try {
			registerDisposableBeanIfNecessary(beanName, bean, mbd);
		}
		catch (BeanDefinitionValidationException ex) {
			throw new BeanCreationException(
					mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
		}
 
		return exposedObject;
	}

真正创建bean这里还是有点复杂的。这里再进行一个简单梳理。

1. 根据class还有bean以及参数创建bean。

2. 调用beanPostprocessor的方法,调用属于MergedBeanDefinitionPostProcessor的方法。对bean进行一些处理,比如找到那些依赖的bean的field和method。

3. 将bean加入到三级缓存中去。

4. 填充bean需要注入的其他bean。

5. 调用初始化方法,先去调用@PostConstruct注解方法,然后调用InitializingBean的afterPropertiesSet,以及自定义的init-method方法。在bean调用初始化方法之后,再去调用后置接口看看是否需要生成Aop代理。

6. 接着进行校验。这里稍微比较复杂一点。如果从二级缓存能取到,那就说明之前被别人从三级缓存拿出来过了。可能是因为循环依赖,也可能是因为别的地方调用了getBean方法了。从三级缓存拿出来的时候有个getEarlyBeanReference的方法,就是查看是否要生成代理的bean。如果生成过了,那么在调用第五步的时候,就不会在生成代理了。这样exposedObject ==bean,直接只用代理返回。

如果不相等:这里的情况就是如果是spring自己的@Async,在从二级缓存生成代理之后,再去调用第五步时候一样会生成代理。所以exposedObject !=bean,所以在再往下发现有循环调用,并且bean还在创建时,就会抛出异常了。所以一般慎用spring的@Async。但是一般也可以使用@Lazy进行处理。至于原理后面再说。

到这里spring的创建bean就结束了。然后返回时候就到了入口方法getBean的getObjectForBeanInstance的方法,到底需要的bean还是FactoryBean。

最后就是如果requiredType和实例不一样就要进行类型转换了。

总结

本篇大概说下spring获取bean和加到容器里面的流程。其实广义上来说Bean的容器是BeanFactory或者applicationContext。狭义上说就是一个map。也就是一级缓存SingletonObjects。我们获取的真正需要的bean也就是从中获取的。本篇只是简要的说了下bean获取和加入容器的整个流程,具体的根据无参构造器创建bean,有参数构造器创建bean。还有对于创建bean中依赖的bean的查找还有创建,三级缓存如何解决循环依赖还有为何不能解决构造器依赖,以及bean调用初始化的等等操作都没有说。因为一篇说起来确实太长了。后面都会一一去分析。

加载全部内容

相关教程
猜你喜欢
用户评论