Bean的加载 createBean()

Posted 为人师表好少年

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Bean的加载 createBean()相关的知识,希望对你有一定的参考价值。

前言

在上一章的doGetBean()中,介绍了创建Bean前的各种处理,那么具体实例化Bean的功能则调用createBean(),该方法由AbstractAutowireCapableBeanFactory类重写,下面来解读一下源码:

一、createBean()

该方法大体步骤如下:

  1. 根据bean定义信息和bean名称解析得到bean的Class类型
  2. 验证并准备为此 bean 定义的方法覆盖,对应bean中的lookup-method + replaced-method2个属性,【不好维护,平常少用,特殊情况使用】
  3. InstantiationAwareBeanPostProcessor后置处理器一个机会,返回代理对象用来替换目标bean实例;
  4. 执行真正创建bean的方法 ==> doCreateBean()
  5. 返回创建好的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;

         // <1> 解析Class类型
		Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
         // 特殊判断
         // 在下面会判断一个属性:BeanDefinition中的beanClass, 看着是存储Class,但实际进去,它是一个Object类型
         // 主要针对注解和XML两种定义方式,注解肯定就正常了,直接把类Class存进去,但是XML的方式,我们是定义一个Class属性,存储的是字符串
         // 这里这么多判断就是为了确定已经解析了Bean
		if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) 
             // 这里克隆1份,官方给出的英文注释:克隆 bean 定义以防动态解析的 Class 无法存储在共享的合并 bean 定义中
			mbdToUse = new RootBeanDefinition(mbd);
			mbdToUse.setBeanClass(resolvedClass);
		

		// Prepare method overrides.
		try 
             // <2> 验证即准备覆盖的方法,用的很少,用于处理lookup-method和replaced-method2个属性
             // 【很少用,不好维护】
			mbdToUse.prepareMethodOverrides();
		
		catch (BeanDefinitionValidationException ex) 
			throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
					beanName, "Validation of method overrides failed", ex);
		
		
         
		try 
			// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
             // <3> 给BeanPostProcess一个机会来返回代理对象,来替代真实的实例
			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 
             // <4> 进行常规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);
		
	

1.resolveBeanClass() 解析Class

整体方法的逻辑很简单

  1. 如果通过该BeanDefinition创建过实例,那么其中肯定会有存储,例如多例的Bean
  2. 如果是第一次创建,那么会通过Class.forName创建Class类型,然后存储到BeanDefinition
@Nullable
protected Class<?> resolveBeanClass(RootBeanDefinition mbd, String beanName, Class<?>... typesToMatch)
      throws CannotLoadBeanClassException 

   try 
      // 1.如果已经解析过,则直接返回使用
      if (mbd.hasBeanClass()) 
         return mbd.getBeanClass();
      
      // 判单是否有安全管理器
      if (System.getSecurityManager() != null) 
         return AccessController.doPrivileged((PrivilegedExceptionAction<Class<?>>)
               () -> doResolveBeanClass(mbd, typesToMatch), getAccessControlContext());
      
      else 
         // 2.代表第一次解析
         // 没有详细解读具体源码, 最底层就是通过JDK原生方法Class.forName(),根据类名来获取Class对象
         return doResolveBeanClass(mbd, typesToMatch);
      
   
   catch (PrivilegedActionException pae) 
      ClassNotFoundException ex = (ClassNotFoundException) pae.getException();
      throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), ex);
   
   catch (ClassNotFoundException ex) 
      throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), ex);
   
   catch (LinkageError err) 
      throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), err);
   

2.resolveBeforeInstantiation()

实例化bean之前,判断是否应用后置处理器

@Nullable
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;

二、doCreateBean()

执行步骤

  1. 单例,则首先尝试从【未完成的FactoryBean实例缓存】获取

  2. 【Bean实例化】。可以通过4种方式来实例化

  3. 扩展机制:MergedBeanDefinitionPostProcessor后置处理器的应用,允许它修改RootBeanDefinition

  4. 是否允许提前暴露bean对象,用于解决循环依赖问题,暴露方式为加入三级缓存

  5. 【Bean属性填充】

  6. 【Bean初始化】

  7. 如果允许早期暴露,需要进行循环依赖检查

  8. 注册DisposableBean的实现,在注销时执行来源于DestructionAwareBeanPostProcessors、实现的DisposableBean的destroy方法还有自己配置的destroy-method的处理;

  9. 完成bean的创建并返回

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

		// Instantiate the bean.
		BeanWrapper instanceWrapper = null;
         // <1> 单例,则首先尝试从【未完成的FactoryBean实例缓存】获取
		if (mbd.isSingleton()) 
			instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
		
         // <2>【Bean实例化】
		if (instanceWrapper == null) 
			instanceWrapper = createBeanInstance(beanName, mbd, args);
		
         // <3> 获取Bean对象和Class
		Object bean = instanceWrapper.getWrappedInstance();
		Class<?> beanType = instanceWrapper.getWrappedClass();
		if (beanType != NullBean.class) 
			mbd.resolvedTargetType = beanType;
		

		// Allow post-processors to modify the merged bean definition.
         // <4> 允许后处理器修改合并的 bean 定义。
		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;
			
		

		// Eagerly cache singletons to be able to resolve circular references
		// even when triggered by lifecycle interfaces like BeanFactoryAware.
         // <5> 是否提前暴漏 = 单例bean && 配置允许提前暴暴露 && 当前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));
		

		// Initialize the bean instance.
		Object exposedObject = bean;
		try 
             // <6>【Bean属性注入】,可能存在依赖于其它bean的属性,则会递归初始化依赖的bean
			populateBean(beanName, mbd, instanceWrapper);
             // <7>【Bean初始化】初始化Bean,如执行aware接口、执行init-method方法、BeanPostProcessor后置增强等等
			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);
			
		

  		// <8> 特殊判断, 为了解决AOP情况下的循环依赖
		if (earlySingletonExposure) 
             // 从三级缓存获取, 如果为空则代表普通Bean, 有值则代表存在循环依赖
			Object earlySingletonReference = getSingleton(beanName, false);
			if (earlySingletonReference != null) 
                  // 初始化Bean方法中,没有把Bean引用改变
				if (exposedObject == bean) 
                      // 这为了解决的问题,如果经过循环依赖以后,A已经创建了代理对象,这里会替换把A替换成代理对象返回
					exposedObject = earlySingletonReference;
				
				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);
						
					
                      // 因为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 
             // <9> 注册DisposableBean的实现,在注销时执行来源于DestructionAwareBeanPostProcessors、
             // 实现的DisposableBean的destroy方法还有自己配置的destroy-method的处理
			registerDisposableBeanIfNecessary(beanName, bean, mbd);
		
		catch (BeanDefinitionValidationException ex) 
			throw new BeanCreationException(
					mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
		

         // <10> 完成bean的创建并返回
		return exposedObject;
	

1.createBeanInstance() Bean实例化

该方法的最终目的是把对象给创建出来,但创建完成的对象只是个初始对象,还未进行属性注入,那么创建的方式分为如下4种:

  1. obtainFromSupplier() :通过 Supplier 实例化
  2. instantiateUsingFactoryMethod():通过工厂方法实例化
  3. autowireConstructor():用合适的构造函数实例化
  4. instantiateBean():用无参构造函数实例化

这个方法会依次进行判断,当然其中最麻烦肯定是有参构造的判断,需要判断各种参数,而且判断通过以后,需要把这个构造方法缓存一下

protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) 
   // Make sure bean class is actually resolved at this point.
   // <1> 解析class属性
   Class<?> beanClass = resolveBeanClass(mbd, beanName);

   // 判断类是否为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());
   

   // <2> 通过Supplier回调,初始化Bean【也是注入Bean的一种方式,很少使用】
   Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
   if (instanceSupplier != null) 
      return obtainFromSupplier(instanceSupplier, beanName);
   

   // <3> 通过 factory-method 初始化Bean
   if (mbd.getFactoryMethodName() != null) 
      return instantiateUsingFactoryMethod(beanName, mbd, args);
   

   // Shortcut when re-creating the same bean...
   // <4> 缓存机制, (一般单例用不到,多例的适合才用到缓存)
   boolean resolved = false; // 是否解析过,也就是之前是否已经创建过对象了
   boolean autowireNecessary = false; // 是否需要自动装配
   // 如果有参数,那么创建的对象肯定不一样,就不能用缓存了
   if (args == null) 
      synchronized (mbd.constructorArgumentLock) 
         // resolvedConstructorOrFactoryMethod 缓存已经解析的构造函数或是工厂方法,
         // 其类型为Executable 是Method、Constructor类型的父类
         if (mbd.resolvedConstructorOrFactoryMethod != null) 
            resolved = true;
            autowireNecessary = mbd.constructorArgumentsResolved; // 构造函数参数标记为已解析
         
      
   
    
   // <5> 使用缓存
   if (resolved) 
      if (autowireNecessary) 
         // 有参构造函数自动注入
         return autowireConstructor(beanName, mbd, null, null);
      
      else 
         // 使用默认的无参构造
         return instantiateBean(beanName, mbd);
      
   

   // <6> 从bean后置处理器中为自动装配寻找构造方法
   // 一般就是二种情况: 1) 只有一个有参构造方法  2) 有且仅有@Autowired注解构造
   Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
   // 以下情况符合其一即可进入
   // 1、存在可选构造方法 
   // 2、自动装配模型为构造函数自动装配
   // 3、给BeanDefinition中设置了构造参数值
   // 4、有参与构造函数参数列表的参数
   if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
         mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) 
      // 通过有参构造方法初始化bean
      return autowireConstructor(beanName, mbd, ctors, args);
   

   // Preferred constructors for default construction?
   // <7> 找出最合适的默认构造方法
   ctors = mbd.getPreferredConstructors();
   if (ctors != null) 
      // 有参构造函数自动注入
      return autowireConstructor(beanName, mbd, ctors, null);
   
   
   // <8> 使用默认无参构造函数创建对象,如果没有无参构造且存在多个有参构造且没有@AutoWired注解构造,会报错
   // No special handling: simply use no-arg constructor.
   return instantiateBean(beanName, mbd);

<1> obtainFromSupplier()

该方式比较偏门,几乎不使用

这里首先介绍一下Supplier这个接口,它里面只有一个get()方法,它和@ComponentFactoryBean这些一样,都是注入Bean的方式,只不过这种方式很少使用,在之前的文章中介绍过该接口

那么回到这个方法中,主体就是调用get()这个方法获取实例

protected BeanWrapper obtainFromSupplier(Supplier<?> instanceSupplier, String beanName) 
   Object instance;

   String outerBean = this.currentlyCreatedBean.get();
   this.currentlyCreatedBean.set(<

spring源码分析IOC容器初始化

  • 前言:在上文bean加载过程中还要一个非常重要的方法没有分析createBean,该方法非常重要,因此特意提出来单独分析。

createBean方法定义在AbstractBeanFactory中:

技术图片

该方法根据给定的beanName、BeanDefinition和args实例化一个bean对象。所有bean实例的创建都会委托给该方法实现。

AbstractAutowireCapableBeanFactory#createBean

createBean的默认实现在AbstractAutowireCapableBeanFactory类中,代码如下:

 1 protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
 2             throws BeanCreationException {
 3         if (logger.isDebugEnabled()) {
 4             logger.debug("Creating instance of bean ‘" + beanName + "‘");
 5         }
 6         RootBeanDefinition mbdToUse = mbd;
 7 
 8         // Make sure bean class is actually resolved at this point, and
 9         // clone the bean definition in case of a dynamically resolved Class
10         // which cannot be stored in the shared merged bean definition.
11         // 确保此时的bean已经被解析了
12         // 如果获取的class属性不为null,则克隆该BeanDefinition,主要是因为动态解析的class无法保存到共享的BeanDefinition
13         Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
14         if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
15             mbdToUse = new RootBeanDefinition(mbd);
16             mbdToUse.setBeanClass(resolvedClass);
17         }
18 
19         // Prepare method overrides.
20         try {
21             // 验证和准备覆盖方法
22             mbdToUse.prepareMethodOverrides();
23         } catch (BeanDefinitionValidationException ex) {
24             throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
25                                                    beanName, "Validation of method overrides failed", ex);
26         }
27 
28         try {
29             // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
30             // 实例化的前置处理
31             // 给BeanPostProcessor一个机会用来返回一个代理类而不是真正的实例类
32             // AOP的功能就是基于这个地方
33             Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
34             if (bean != null) {
35                 return bean;
36             }
37         } catch (Throwable ex) {
38             throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
39                                             "BeanPostProcessor before instantiation of bean failed", ex);
40         }
41 
42         try {
43             // 创建Bean对象
44             Object beanInstance = doCreateBean(beanName, mbdToUse, args);
45             if (logger.isDebugEnabled()) {
46                 logger.debug("Finished creating instance of bean ‘" + beanName + "‘");
47             }
48             return beanInstance;
49         } catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
50             // A previously detected exception with proper bean creation context already,
51             // or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
52             throw ex;
53         } catch (Throwable ex) {
54             throw new BeanCreationException(
55                     mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
56         }
57     }

分析:

  • 通过resolveBeanClass解析BeanDefinition的class属性。
  • 处理override属性。
  • 通过resolveBeforeInstantiation进行实例化的前置处理。
  • 最后通过doCreateBean创建bean对象。

AbstractBeanFactory#resolveBeanClass

 1 protected Class<?> resolveBeanClass(final RootBeanDefinition mbd, String beanName, final Class<?>... typesToMatch)
 2             throws CannotLoadBeanClassException {
 3 
 4         try {
 5             if (mbd.hasBeanClass()) {
 6                 return mbd.getBeanClass();
 7             }
 8             if (System.getSecurityManager() != null) {
 9                 return AccessController.doPrivileged((PrivilegedExceptionAction<Class<?>>) () ->
10                         doResolveBeanClass(mbd, typesToMatch), getAccessControlContext());
11             } else {
12                 return doResolveBeanClass(mbd, typesToMatch);
13             }
14         // ..... 省略异常处理
15     }

分析:

该方法主要是解析BeanDefinition的class类,如果解析的class类不为空,则将其设置到mbdToUse中,因为动态解析的class无法保存到共享的BeanDefinition中。

AbstractBeanFactory#prepareMethodOverrides

 1 public void prepareMethodOverrides() throws BeanDefinitionValidationException {
 2         // Check that lookup methods exists.
 3         // 如果方法可以覆盖
 4         if (hasMethodOverrides()) {
 5             // 得到覆盖方法
 6             Set<MethodOverride> overrides = getMethodOverrides().getOverrides();
 7             // 同步
 8             synchronized (overrides) {
 9                 // 循环调用 prepareMethodOverride进行覆盖准备
10                 for (MethodOverride mo : overrides) {
11                     prepareMethodOverride(mo);
12                 }
13             }
14         }
15     }

分析:

bean标签中的lookup-method和replace-method属性就是放在BeanDefinition的methodOverrides属性中(关于这两个属性的分析后续再来分析),这里就是对methodOverrides属性进行处理,动态为当前bean生产代理并使用对应的拦截器为bean做增强处理。

上述处理逻辑就是循环获取MethodOverride属性,然后调用prepareMethodOverride进行处理。

 1 // AbstractBeanDefinition
 2 protected void prepareMethodOverride(MethodOverride mo) throws BeanDefinitionValidationException {
 3         int count = ClassUtils.getMethodCountForName(getBeanClass(), mo.getMethodName());
 4         if (count == 0) {
 5             throw new BeanDefinitionValidationException(
 6                     "Invalid method override: no method with name ‘" + mo.getMethodName() +
 7                             "‘ on class [" + getBeanClassName() + "]");
 8         } else if (count == 1) {
 9             // Mark override as not overloaded, to avoid the overhead of arg type checking.
10             mo.setOverloaded(false);
11         }
12     }

分析:

根据方法名,从class中获取该方法名的个数:

  • 如果方法名个数为0,则抛出BeanDefinitionValidationException异常,原因其实很简单:通过方法名去查找,而又没有找到,则说明有问题的,抛出异常。
  • 如果方法名个数为1,则设置该方法未被重载(overloaded属性模式为true)。如果一个类存在多个重载方法,在方法调用的时候还需根据参数类型来判断到底重载的是哪个方法,这里通过count=1,来表示该方法未被重载,在调用的时候可以直接找方法而不需要进行方法参数的校验,相当于一个小小的优化,提升后面调用函数的速度。

AbstractAutowireCapableBeanFactory#resolveBeforeInstantiation

 1 protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
 2         Object bean = null;
 3         // 如果bean不是应用系统的,有BeanPostProcessor
 4         if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
 5             // Make sure bean class is actually resolved at this point.
 6             if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
 7                 Class<?> targetType = determineTargetType(beanName, mbd);
 8                 if (targetType != null) {
 9                     // 前置处理
10                     bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
11                     if (bean != null) {
12                         // 后置处理
13                         bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
14                     }
15                 }
16             }
17             mbd.beforeInstantiationResolved = (bean != null);
18         }
19         return bean;
20     }

分析:

通过applyBeanPostProcessorsBeforeInstantiation和applyBeanPostProcessorsAfterInitialization对bean实例化前进行前置与后置处理。如果返回了代理对象,则直接返回结果,Spring后续实现AOP就是基于这个地方进行的判断。

前置处理与后置处理后续再具体进行分析。

AbstractAutowireCapableBeanFactory#doCreateBean

  1 protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
  2             throws BeanCreationException {
  3 
  4         // Instantiate the bean.
  5         // BeanWrapper是对Bean的包装,其接口中所定义的功能很简单包括设置获取被包装的对象、获取被包装bean的属性描述器
  6         BeanWrapper instanceWrapper = null;
  7         // 如果是单例模型,则从未完成的FactoryBean缓存中删除
  8         if (mbd.isSingleton()) {
  9             instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
 10         }
 11         // 使用合适的实例化策略来创建新的实例:工厂方法、构造函数自动注入、简单初始化
 12         if (instanceWrapper == null) {
 13             instanceWrapper = createBeanInstance(beanName, mbd, args);
 14         }
 15         // 包装的对象实例
 16         final Object bean = instanceWrapper.getWrappedInstance();
 17         // 包装的实例对象的类型
 18         Class<?> beanType = instanceWrapper.getWrappedClass();
 19         if (beanType != NullBean.class) {
 20             mbd.resolvedTargetType = beanType;
 21         }
 22 
 23         // Allow post-processors to modify the merged bean definition.
 24         // 先做同步,然后判断是否有后置处理
 25         synchronized (mbd.postProcessingLock) {
 26             if (!mbd.postProcessed) {
 27                 try {
 28                     // 后置处理修改BeanDefinition
 29                     applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
 30                 } catch (Throwable ex) {
 31                     throw new BeanCreationException(mbd.getResourceDescription(), beanName,
 32                                                     "Post-processing of merged bean definition failed", ex);
 33                 }
 34                 mbd.postProcessed = true;
 35             }
 36         }
 37 
 38         // Eagerly cache singletons to be able to resolve circular references
 39         // even when triggered by lifecycle interfaces like BeanFactoryAware.
 40         // 解决单例模式的循环依赖         // 单例模式               运行循环依赖
 41         boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
 42                 isSingletonCurrentlyInCreation(beanName));// 当前单例bean是否正在被创建
 43         if (earlySingletonExposure) {
 44             if (logger.isDebugEnabled()) {
 45                 logger.debug("Eagerly caching bean ‘" + beanName +
 46                                      "‘ to allow for resolving potential circular references");
 47             }
 48             // 提前将创建的bean实例加入到singletonFactories中
 49             // 为了后期避免循环依赖
 50             addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
 51         }
 52 
 53         // Initialize the bean instance.
 54         // 开始初始化bean实例对象
 55         Object exposedObject = bean;
 56         try {
 57             // 对bean进行填充,主要是进行属性注入,其中,可能存在依赖于其他bean的属性,则会递归初始化依赖bean
 58             populateBean(beanName, mbd, instanceWrapper);
 59             // 进行bean初始化
 60             exposedObject = initializeBean(beanName, exposedObject, mbd);
 61         } catch (Throwable ex) {
 62             if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
 63                 throw (BeanCreationException) ex;
 64             } else {
 65                 throw new BeanCreationException(
 66                         mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
 67             }
 68         }
 69 
 70         // 循环依赖处理
 71         if (earlySingletonExposure) {
 72             // 获取earlySingletonReference
 73             Object earlySingletonReference = getSingleton(beanName, false);
 74             // 只有在循环依赖的情况下,earlySingletonReference才不会为null
 75             if (earlySingletonReference != null) {
 76                 // 如果exposedObject没有在初始化方法中改变,也就是没有被增强
 77                 if (exposedObject == bean) {
 78                     exposedObject = earlySingletonReference;
 79                 } else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) { // 处理依赖
 80                     String[] dependentBeans = getDependentBeans(beanName);
 81                     Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
 82                     for (String dependentBean : dependentBeans) {
 83                         if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
 84                             actualDependentBeans.add(dependentBean);
 85                         }
 86                     }
 87                     if (!actualDependentBeans.isEmpty()) {
 88                         throw new BeanCurrentlyInCreationException(beanName,
 89                                                                    "Bean with name ‘" + beanName + "‘ has been injected into other beans [" +
 90                                                                            StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
 91                                                                            "] in its raw version as part of a circular reference, but has eventually been " +
 92                                                                            "wrapped. This means that said other beans do not use the final version of the " +
 93                                                                            "bean. This is often the result of over-eager type matching - consider using " +
 94                                                                            "‘getBeanNamesOfType‘ with the ‘allowEagerInit‘ flag turned off, for example.");
 95                     }
 96                 }
 97             }
 98         }
 99 
100         // Register bean as disposable.
101         try {
102             // 注册bean
103             registerDisposableBeanIfNecessary(beanName, bean, mbd);
104         } catch (BeanDefinitionValidationException ex) {
105             throw new BeanCreationException(
106                     mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
107         }
108 
109         return exposedObject;
110     }

分析:

如果没有代理对象,则会进行bean对象的创建。

  • 如果BeanDefinition为单例模式,首先从FactoryBean缓存中删除该beanName的缓存。
  • 调用createBeanInstance方法创建一个BeanWrapper对象。
  • 调用applyMergedBeanDefinitionPostProcessors对BeanDefinition进行后置处理
  • 进行单例模式的循环依赖处理。
  • 调用populateBean进行bean属性填充。
  • 调用initializeBean进行bean初始化。
  • 进行依赖检查。
  • 最后注册bean。

上述列出了创建bean对象的主要步骤,过程还是比较复杂的,下面一一进行分析。主要关注点createBeanInstance、populateBean、initializeBean三个函数。

AbstractAutowireCapableBeanFactory#createBeanInstance

 1 protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
 2         // Make sure bean class is actually resolved at this point.
 3         // 解析bean,将bean类名解析为class引用
 4         Class<?> beanClass = resolveBeanClass(mbd, beanName);
 5 
 6         if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
 7             throw new BeanCreationException(mbd.getResourceDescription(), beanName,
 8                                             "Bean class isn‘t public, and non-public access not allowed: " + beanClass.getName());
 9         }
10 
11         // 如果存在supplier回调,则使用给定的回调方法初始化策略
12         Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
13         if (instanceSupplier != null) {
14             return obtainFromSupplier(instanceSupplier, beanName);
15         }
16 
17         // 使用FactoryBean的factor-method来创建bean,支持静态工厂和实例工厂
18         if (mbd.getFactoryMethodName() != null) {
19             return instantiateUsingFactoryMethod(beanName, mbd, args);
20         }
21 
22         // Shortcut when re-creating the same bean...
23         boolean resolved = false;
24         boolean autowireNecessary = false;
25         if (args == null) {
26             // 做同步
27             synchronized (mbd.constructorArgumentLock) {
28                 // 如果已缓存的解析构造函数或者工厂方法不为null,则可以利用构造函数解析
29                 // 因为需要根据参数确认到底使用哪个构造函数,该过程比较消耗性能,所以采用缓存机制
30                 if (mbd.resolvedConstructorOrFactoryMethod != null) {
31                     resolved = true;
32                     autowireNecessary = mbd.constructorArgumentsResolved;
33                 }
34             }
35         }
36         // 已经解析好了,直接注入即可
37         if (resolved) {
38             // autowire自动注入,调用构造函数自动注入
39             if (autowireNecessary) {
40                 return autowireConstructor(beanName, mbd, null, null);
41             } else {
42                 // 使用默认构造函数构造
43                 return instantiateBean(beanName, mbd);
44             }
45         }
46 
47         // Need to determine the constructor...
48         // 确定解析的构造函数
49         // 主要是检查已经注册的SmartInstantiationAwareBeanPostProcessor
50         Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
51         // 确定构造方法进行bean创建
52         if (ctors != null ||
53                 mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||
54                 mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
55             return autowireConstructor(beanName, mbd, ctors, args);
56         }
57 
58         // 有参数,又没有获取到构造方法,则只能调用无参构造方法来创建实例
59         // 这是一个兜底的方法
60         // No special handling: simply use no-arg constructor.
61         return instantiateBean(beanName, mbd);
62     }

分析:

bean的实例化一个比较复杂的过程。

  • 如果设置Supplier回调,则调用obtainFromSupplier方法进行初始化。
  • 如果存在工厂方法,则使用工厂方法进行初始化。
  • 先判断缓存中是否存在构造函数,如果存在,则根据是否使用自动注入,还是默认的构造函数进行bean对象的初始化。
  • 如果缓存中不存在,则需先判断到底使用哪个构造函数来完成解析工作。
  • 如果上述条件还是不满足,则使用无参构造方法来创建实例。

#1.如果设置Supplier回调,则使用obtainFromSupplier方法进行初始化。

首先了解下Supplier接口(java.util.function)

技术图片

  • Supplier接口仅有一个功能性的get()方法,该方法会返回一个<T>类型的对象,有点类似工厂方法。
  • 如果我们在创建BeanDefinition的时候设置了Supplier参数,那么其他的构造器或者工厂方法就没有作用了。
  • AbstractBeanDefinition中提供了设置Supplier的入口:
  • 技术图片

AbstractAutowireCapableBeanFactory#obtainFromSupplier

 1 protected BeanWrapper obtainFromSupplier(Supplier<?> instanceSupplier, String beanName) {
 2         // 获得原创建的Bean的对象名
 3         String outerBean = this.currentlyCreatedBean.get();
 4         // 设置新的Bean对象名到currentlyCreatedBean中
 5         this.currentlyCreatedBean.set(beanName);
 6         Object instance;
 7         try {
 8             // 调用Supplier的get(),返回一个Bean对象
 9             instance = instanceSupplier.get();
10         } finally {
11             // 设置原创建的Bean对象名到currentlyCreatedBean中
12             if (outerBean != null) {
13                 this.currentlyCreatedBean.set(outerBean);
14             } else {
15                 this.currentlyCreatedBean.remove();
16             }
17         }
18         // 创建BeanWrapper对象
19         BeanWrapper bw = new BeanWrapperImpl(instance);
20         // 初始化BeanWrapper
21         initBeanWrapper(bw);
22         return bw;
23     }

分析:

  • 调用Supplier#get方法,获取一个Bean实例对象。
  • 根据该实例对象构建BeanWrapper对象。
  • 最后初始化该对象。

如果存在工厂方法,则会调用工厂方法来完成bean的初始化工作,该方法实现比较长,并且细节复杂,由于篇幅原因放在下篇文章中解析。

总结

这里仅仅分析了doCreateBean方法中的一点点内容,如果存在Supplier回调,则会直接通过Supplier来创建Bean对象,构造函数和工厂方法则失效,下面将对分析使用工厂方法实例化Bean对象的过程。


by Shawn Chen,2019.04.23,下午。

以上是关于Bean的加载 createBean()的主要内容,如果未能解决你的问题,请参考以下文章

spring源码分析IOC容器初始化

Spring源码浅析之bean实例的创建过程

Spring中AOP源码

Spring中AOP源码

死磕 Spring----- IOC 之开启 bean 的实例化进程

[死磕 Spring 20/43] --- IOC 之开启 bean 的实例化进程