spring getBean()方法解析概述

1.getBean(beanName) 整体概述

1.transformedBeanName(name)

  • name可能是别名,将别名(alias)解析成真正的beanName
  • 截取&beanName中&字符,获得beanName

2.getSingleton(beanName) 从缓存中获取bean,有三个缓存集合,循环依赖会有单章讲解。

  • singletonObjects :缓存已经初始化完成的bean对象
  • earlySingletonObjects : 循环引用中,提前暴露的bean对象
  • singletonFactories :会调用getObject() 方法,返回一个earlyBean,放到earlySingletonObjects中,主要为了解决循环依赖时动态代理的问题

3.如果缓存中有bean对象,调用getObjectForBeanInstance 方法

  • 当前bean不是FactoryBean,直接返回对象
  • 当前bean是FactoryBean,且beanName中包换‘&’符号,直接放回对象。
  • 当前bean是FactoryBean,且beanName中不包含‘&’符号,调用当前bean的getObject()方法,返回getObject()方法的返回值。

4.如果bean中没有缓存对象

  • 检查是否有父工厂,有就要尝试从父工厂中拿,这里就实现了springmvc中的父子容器
  • 检查是否存在依赖的bean,有则优先实例化依赖的bean
  • 如果父工厂为空,或没有该bean,调用createBean(beanName, mbd, args)方法,创建对象,这里会判断scope类型,分别创建。

5.检查指定类型(requiredType)是否与获得Bean实例的类型匹配,不匹配就要使用转换器进行转换,转换失败就抛出异常。

6.返回最终bean对象。

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


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

	    //name可能是别名,将别名(alias)解析成真正的beanName
        //截取&beanName中&字符,获得beanName
		String beanName = transformedBeanName(name);
		Object bean;

		// Eagerly check singleton cache for manually registered singletons.
		// 检查单例缓存中是否有单例对象
		Object sharedInstance = getSingleton(beanName);
		// 如果有bean的单例对象,且没有创建bean实例时要使用的参数
		if (sharedInstance != null && args == null) {
			// 当前bean不是FactoryBean,直接返回对象
            // 当前bean是FactoryBean,且beanName中包换‘&’符号,直接放回对象。
            // 当前bean是FactoryBean,且beanName中不包含‘&’符号,调用当前bean的getObject()        
            //         方法,返回getObject()方法的返回值。
			bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
		}

		else {
			// 原型模式下如果存在循环依赖的情况,那么直接抛出异常
			if (isPrototypeCurrentlyInCreation(beanName)) {
				throw new BeanCurrentlyInCreationException(beanName);
			}

			// 当前bean不存在,就检查是否有父工厂
			BeanFactory parentBeanFactory = getParentBeanFactory();
			// 如果当前工厂中不包含beanName,那么就尝试从父容器中获取
			if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
				//如果name前面有'&',则会返回'&'+规范名称
				String nameToLookup = originalBeanName(name);
				// 如果父工厂是AbstractBeanFactory
				if (parentBeanFactory instanceof AbstractBeanFactory) {
					// 调用父工厂的doGetBean方法
					return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
							nameToLookup, requiredType, args, typeCheckOnly);
				}
                //有参数
				else if (args != null) {
					return (T) parentBeanFactory.getBean(nameToLookup, args);
				}
                //有类型
				else if (requiredType != null) {
					// No args -> delegate to standard getBean method.
					// 没有创建bean实例时要使用的参数 -> 委托给标准的getBean方法。
					// 使用父工厂获取该bean对象,通bean全类名和所需的bean类型
					return parentBeanFactory.getBean(nameToLookup, requiredType);
				}
				else {
					return (T) parentBeanFactory.getBean(nameToLookup);
				}
			}
		
			if (!typeCheckOnly) {
				// 将beanName标记为已经创建
				markBeanAsCreated(beanName);
			}

			try {
				// 当前bean的BeanDefinition是否有parentBeanDefinition,如果有就需要合并
				RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
				// 检查mbd是否时抽象的
				checkMergedBeanDefinition(mbd, beanName, args);

				// 如果是否存在依赖的bean,有则优先实例化依赖的bean
				String[] dependsOn = mbd.getDependsOn();
				if (dependsOn != null) {
					for (String dep : dependsOn) {
						// dep所指定的bean,和当前bean不能相互依赖
						if (isDependent(beanName, dep)) {
							throw new BeanCreationException(mbd.getResourceDescription(), beanName,
									"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
						}
						// 注册依赖关系
						registerDependentBean(dep, beanName);
						try {
							// 实例化被依赖的Bean
							getBean(dep);
						}
						catch (NoSuchBeanDefinitionException ex) {
							throw new BeanCreationException(mbd.getResourceDescription(), beanName,
									"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
						}
					}
				}

				// Create bean instance.
				// 创建单例bean
				if (mbd.isSingleton()) {
					sharedInstance = getSingleton(beanName, () -> {
						try {
							// 真正创建bean实例
							return createBean(beanName, mbd, args);
						}
						catch (BeansException ex) {
							destroySingleton(beanName);
							throw ex;
						}
					});
					// 当前bean不是FactoryBean,直接返回对象
                    // 当前bean是FactoryBean,且beanName中包换‘&’符号,直接放回对象。
                    // 当前bean是FactoryBean,且beanName中不包含‘&’符号,调用当前bean的        
                    //            getObject()方法,返回getObject()方法的返回值。
					bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
				}
				// 原型模式的bean对象创建
				else if (mbd.isPrototype()) {
					Object prototypeInstance = null;
					try {
						// beanName添加到prototypesCurrentlyInCreation,标记为正在创建
						beforePrototypeCreation(beanName);
						// 创建一个bean实例
						prototypeInstance = createBean(beanName, mbd, args);
					}
					finally {
						// 将beanName从prototypesCurrentlyInCreation移除,表示创建完成
						afterPrototypeCreation(beanName);
					}
	                // 当前bean不是FactoryBean,直接返回对象
                    // 当前bean是FactoryBean,且beanName中包换‘&’符号,直接放回对象。
                    // 当前bean是FactoryBean,且beanName中不包含‘&’符号,调用当前bean的        
                    //            getObject()方法,返回getObject()方法的返回值。
					bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
				}

				else {
					String scopeName = mbd.getScope();
					if (!StringUtils.hasLength(scopeName)) {
						throw new IllegalStateException("No scope name defined for bean ´" + beanName + "'");
					}
					// springmvc中,有session 或 request作用域
					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, () -> {
							// 类似与ProtoType,不能循环依赖
							beforePrototypeCreation(beanName);
							try {
								//创建一个bean实例
								return createBean(beanName, mbd, args);
							}
							finally {
								afterPrototypeCreation(beanName);
							}
						});
						// 当前bean不是FactoryBean,直接返回对象
                        // 当前bean是FactoryBean,且beanName中包换‘&’符号,直接放回对象。
                        // 当前bean是FactoryBean,且beanName中不包含‘&’符号,调用当前bean的        
                        //            getObject()方法,返回getObject()方法的返回值。
						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) {
				// 在Bean创建失败后,对缓存的元数据执行适当的清理
				cleanupAfterBeanCreationFailure(beanName);
				throw ex;
			}
		}

		// 如果requiredType不为null&&bean不是requiredType的实例
		if (requiredType != null && !requiredType.isInstance(bean)) {
			try {
				// 获取类型转换器,将bean转换为requiredType
				T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
				// 如果convertedBean为null,转换失败
				if (convertedBean == null) {
					throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
				}
				return convertedBean;
			}
			catch (TypeMismatchException ex) {
				
				throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
			}
		}
		// 将bean返回
		return (T) bean;
	}

2.createBean()方法概述

1.resolveBeanClass(mbd, beanName) :获取当前bean的class对象,因为mbd中beanClassName属性值可能是字符串类型,需要反射加载。

2.mbdToUse.prepareMethodOverrides() :对lookup-method  replace-method 修饰的方法,设置为未覆盖(意味着需要后面进行覆盖)。后面bean实例化时会有方法和这里对应。

3.resolveBeforeInstantiation(beanName, mbdToUse) : 调用InstantiationAwareBeanPostProcessor后置处理器的postProcessBeforeInstantiation(),如果有对象返回,则后续实例化工作不再继续。bean的后置处理的分类在这里https://blog.csdn.net/weixin_41009314/article/details/117293706 有说明。

4.doCreateBean(beanName, mbdToUse, args) :创建bean对象。

    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,mbd中存储的可能是bean的Class对象,也可能是类的全限定类名的字符串。
		Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
		// 全限定类名的字符串解析成Class对象,需要设置BeanClass属性,再次创建时可复用
		if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
			// 重新创建一个RootBeanDefinition对象
			mbdToUse = new RootBeanDefinition(mbd);
			// 设置BeanClass属性值
			mbdToUse.setBeanClass(resolvedClass);
		}

		// 验证及准备覆盖的方法,lookup-method  replace-method,
		// 当需要创建的bean对象中包含了lookup-method和replace-method标签的时候,会产生覆盖操作
		try {
			mbdToUse.prepareMethodOverrides();
		}
		catch (BeanDefinitionValidationException ex) {
			throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
					beanName, "Validation of method overrides failed", ex);
		}

		try {
			//调用InstantiationAwareBeanPostProcessor后置处理器的postProcessBeforeInstantiation(),
			// 如果有对象返回,则后续实例化工作不再继续
			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.isTraceEnabled()) {
				logger.trace("Finished creating instance of bean '" + beanName + "'");
			}
			return beanInstance;
		}
		catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
			// A previously detected exception with proper bean creation context already,
			// or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
			throw ex;
		}
		catch (Throwable ex) {
			throw new BeanCreationException(
					mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
		}
	}

3.doCreateBean()整体概述

1.创建bean对象,用BeanWrapper 类包装放回。

2.调用MergedBeanDefinitionPostProcessor 的postProcessMergedBeanDefinition()方法,主要用于@Autowire, @Resource 标记的属性注入(找到需要注入的属性并缓存)。

3.在三级缓存singletonFactories中添加getEarlyBeanReference()方法,用以解决循环依赖问题。

4.调用populateBean()方法,对bean的属性进行填充。

5.调用initializeBean()方法,对bean进行初始化。

6.假设exposedObject对象应该被代理,由于循环依赖提前生成了代理对象(earlySingletonObjects中),initializeBean()中返回的对象可能是未被代理,因此需要将提前生成的代理对象赋值给exposedObject,并返回。

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

		// 持有创建出来的bean对象
		BeanWrapper instanceWrapper = null;
		// 从缓存中获取
		if (mbd.isSingleton()) {
			// 如果是单例对象,从factorybean实例缓存中移除当前bean定义信息
			instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
		}
		// 没有就创建实例
		if (instanceWrapper == null) {
			instanceWrapper = createBeanInstance(beanName, mbd, args);
		}
		// 从包装类中获取bean
		Object bean = instanceWrapper.getWrappedInstance();
		// 获取具体的bean对象的Class属性
		Class<?> beanType = instanceWrapper.getWrappedClass();
		// 如果不等于NullBean类型,那么修改目标类型
		if (beanType != NullBean.class) {
			mbd.resolvedTargetType = beanType;
		}

		// Allow post-processors to modify the merged bean definition.
		// 允许beanPostProcessor去修改合并的beanDefinition
		synchronized (mbd.postProcessingLock) {
			if (!mbd.postProcessed) {
				try {
					// MergedBeanDefinitionPostProcessor后置处理器修改合并bean的定义
					applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
				}
				catch (Throwable ex) {
					throw new BeanCreationException(mbd.getResourceDescription(), beanName,
							"Post-processing of merged bean definition failed", ex);
				}
				mbd.postProcessed = true;
			}
		}

		// Eagerly cache singletons to be able to resolve circular references
		// even when triggered by lifecycle interfaces like BeanFactoryAware.
		// 判断当前bean是否需要提前曝光:单例&允许循环依赖&当前bean正在创建中(检测循环依赖)
		boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
				isSingletonCurrentlyInCreation(beanName));
		if (earlySingletonExposure) {
			// 为避免后期循环依赖,可以在bean初始化完成前将创建实例的ObjectFactory加入工厂
			addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));

		}

		// Initialize the bean instance.
		// 初始化bean实例
		Object exposedObject = bean;
		try {
			// 对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) {
				// 如果bean在循环依赖情况下,提前被代理,这里的exposedObject并不会被代理,因此需要赋值操作。
				if (exposedObject == bean) {
					exposedObject = earlySingletonReference;
				}
				else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
					String[] dependentBeans = getDependentBeans(beanName);
					Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
					for (String dependentBean : dependentBeans) {
						// 返回false说明依赖还没实例化好
						if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
							actualDependentBeans.add(dependentBean);
						}
					}
					// 因为bean创建后所依赖的bean一定是已经创建的
					// actualDependentBeans不为空则表示当前bean创建后其依赖的bean却没有全部创建完,也就是说存在循环依赖
					if (!actualDependentBeans.isEmpty()) {
						throw new BeanCurrentlyInCreationException(beanName,
								"Bean with name '" + beanName + "' has been injected into other beans [" +
								StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
								"] in its raw version as part of a circular reference, but has eventually been " +
								"wrapped. This means that said other beans do not use the final version of the " +
								"bean. This is often the result of over-eager type matching - consider using " +
								"'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.");
					}
				}
			}
		}

		// Register bean as disposable.
		try {
			// 注册bean对象,方便后续在容器销毁的时候销毁对象
			registerDisposableBeanIfNecessary(beanName, bean, mbd);
		}
		catch (BeanDefinitionValidationException ex) {
			throw new BeanCreationException(
					mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
		}

		return exposedObject;
	}

4.createBeanInstance() 方法解析

1.判断beanDefinition 中是否设置Supplier,可提前实例化,不需要走后面推断构造器,再实例化的过程。

2.判断beanDefinition 中是否有工厂方法(FactoryMethod),可提前实例化,不需要走后面推断构造器,再实例化的过程。

3.判断构造方法是否已经解析过来,如果已经解析过,直接实例化, 没有解析过需要根据【注解@Autowire, 参数(propertyValues)】等推断构造方法,再实例化

​
    protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
		// 获取bean的class对象
		Class<?> beanClass = resolveBeanClass(mbd, beanName);

		// class不为空,并且访问权限是public
		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());
		}

		// 判断beanDefinition中是否设置InstanceSupplier,可通过种方式实例化对象。
		Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
		if (instanceSupplier != null) {
			return obtainFromSupplier(instanceSupplier, beanName);
		}

		// 判断当前bean是否使用FactoryMethod实例化bean
		if (mbd.getFactoryMethodName() != null) {
			return instantiateUsingFactoryMethod(beanName, mbd, args);
		}

	
		// 标记当前bean的构造函数是否已经被解析
		boolean resolved = false;
		// 当前bean是否开启自动注入模式
		boolean autowireNecessary = false;
		if (args == null) {
			synchronized (mbd.constructorArgumentLock) {
                // resolvedConstructorOrFactoryMethod 保存已经被解析的构造方法
				if (mbd.resolvedConstructorOrFactoryMethod != null) {
					resolved = true;
                    //constructorArgumentsResolved 表示进入过autowireConstructor()方法,也就是进行过自动注入
					autowireNecessary = mbd.constructorArgumentsResolved;
				}
			}
		}
		// 构造函数是否已经被解析
		if (resolved) {
			// 进行过自动注入
			if (autowireNecessary) {
				// 进行过自动注入,即使构造函数已经被解析过,还是需要进入自动注入的方法
                // 原因:在自动注入的情况下,构造函数可能不是无参构造,也就是会有参数
                //       下面的instantiateBean(beanName, mbd) 只能实例化无参构造,                
                //       autowireConstructor()即可以实例化无参构造,也可以实例化有参构造
				return autowireConstructor(beanName, mbd, null, null);
			}
			else {
				// 使用默认构造函数构造
				return instantiateBean(beanName, mbd);
			}
		}

		// 调用SmartInstantiationAwareBeanPostProcessor 的determineCandidateConstructors()方法 
        // 主要用与解析@Autowire标注的构造方法
		Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
		// 以下情况符合其一即可进入
		// 1、存在可选构造方法(@Autowire修饰)
		// 2、自动装配模型为构造函数自动装配
		// 3、给BeanDefinition中设置了构造参数值
		// 4、有参与构造函数参数列表的参数
		if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
				mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
			return autowireConstructor(beanName, mbd, ctors, args);
		}

		// Preferred constructors for default construction?
		// 找出最合适的默认构造方法,一般返回null
		ctors = mbd.getPreferredConstructors();
		if (ctors != null) {
			return autowireConstructor(beanName, mbd, ctors, null);
		}

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

​

注:getBean流程中有很多细节,需要新的章节说明,这里无法展开。本文为个人理解和参考他人,如有问题请指出。

上一篇:关于 Spring 中 getBean 的全流程源码解析


下一篇:找不到Java xerces DocumentBuilderFactoryimpl-怎么办?