《Spring系列》第9章 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(beanName);
   try {
      // 通过调用get()方法, 这里函数式接口,实际上会调用传入的方法初始化Bean
      instance = instanceSupplier.get();
   }
   finally {
      if (outerBean != null) {
         this.currentlyCreatedBean.set(outerBean);
      }
      else {
         this.currentlyCreatedBean.remove();
      }
   }

   if (instance == null) {
      instance = new NullBean();
   }
   BeanWrapper bw = new BeanWrapperImpl(instance);
   initBeanWrapper(bw);
   return bw;
}

<2> instantiateUsingFactoryMethod()

返回值会创建一个解析类ConstructorResolver, 然后调用instantiateUsingFactoryMethod() 这个方法,这个方法里面的代码太长了,增加了非常多的判断,这里不做具体解读,概述一下实现的功能:

  1. 当只配置了factory-method,则该方法必须为静态方法,可以直接调用静态方法创建对象,否则抛出异常,这就是静态工厂模式
  2. 当配置了factory-method + factory-bean,则代表该方法为普通方法,则,这就是实例工厂模式
protected BeanWrapper instantiateUsingFactoryMethod(
      String beanName, RootBeanDefinition mbd, @Nullable Object[] explicitArgs) {

   return new ConstructorResolver(this).instantiateUsingFactoryMethod(beanName, mbd, explicitArgs);
}

<3> 有参构造创建

这里会调用autowireConstructor(),有参构造函数自动注入,源码很长就不解读了,有以下原因:

  1. 很多源码的构造方法都定义很多逻辑,但是自己开发,还是更多的使用无参构造方法
  2. 有参构造可以有多个,而且参数的类型、顺序不同, 这就导致有很多的可能性,尤其那个参数类型,例如:我定义有参构造的参数类型为Object,这就需要一个类型匹配规则
  3. 而且这里还会处理@Autowired注解,构造方法上面加该注解,代表参数可以从Bean容器中依赖注入,这从方法名autowireConstructor()带了autowire这个词可以看到

就相当于从各种各样的构造方法中寻找最适合的那个

<4> 无参构造初始化

这里会调用instantiateBean(),具体源码就不解读了,肯定是借助Java反射机制,简单介绍一下步骤:

  1. 获取到Class类

  2. 通过Class获取到构造方法clazz.getDeclaredConstructor()

  3. 有了构造方法,接下来就反射创建一个对象即可ctor.newInstance()

2.扩展机制修改BeanDefinition

提供的扩展机制,允许通过后置处理器的方式,修改RootBeanDefinition

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

遍历执行后置处理器

protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName) {
   for (MergedBeanDefinitionPostProcessor processor : getBeanPostProcessorCache().mergedDefinition) {
      processor.postProcessMergedBeanDefinition(mbd, beanType, beanName);
   }
}

3.是否提前暴露bean

是否提前暴露该bean是为了解决单例情况下的循环依赖

// 判断条件 = 单例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");
   }
   // 注意这里第二个参数是函数式表达式
   addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}

addSingletonFactory()

如果允许提前暴露,那么就会加入将该Bean以ObjectFactory的形式加入到三级缓存,主要为了适配AOP的循环依赖,后续会有单独篇幅介绍循环依赖。

protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
   Assert.notNull(singletonFactory, "Singleton factory must not be null");
   synchronized (this.singletonObjects) {
      // 单例缓存中不存在该bean
      if (!this.singletonObjects.containsKey(beanName)) {
         // 存入三级缓存,对象是ObjectFactory类型
         this.singletonFactories.put(beanName, singletonFactory);
         // 二级缓存清空一下
         this.earlySingletonObjects.remove(beanName);
         this.registeredSingletons.add(beanName);
      }
   }
}

getEarlyBeanReference()

存入到三级缓存的是ObjectFactory,是个Lambda的形式,当调用getObject()实际上会调用getEarlyBeanReference(),Spring框架最重要的AOP就是在这里这里创建的代理

protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
   Object exposedObject = bean;
   if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
      for (SmartInstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().smartInstantiationAware) {
         exposedObject = bp.getEarlyBeanReference(exposedObject, beanName);
      }
   }
   return exposedObject;
}

【举例】

上面用到了bp.getEarlyBeanReference(exposedObject, beanName),如果使用了AOP,这里面是递归到了AbstractAutoProxyCreator类,就是处理AOP的类

// AbstractAutoProxyCreator#getEarlyBeanReference()
@Override
public Object getEarlyBeanReference(Object bean, String beanName) {
   Object cacheKey = getCacheKey(bean.getClass(), beanName);
   this.earlyProxyReferences.put(cacheKey, bean);
   return wrapIfNecessary(bean, beanName, cacheKey);
}

4.populateBean() 属性填充

  1. 获取bean中哪些属性需要注入,注入的模式
  2. 定义MutablePropertyValues,存储需要注入的属性
  3. 根据名称注入,将需要注入的bean存储到MutablePropertyValues中,注意此时只是获取了,但是还没有绑定关系
  4. 根据类型注入,同样保存到MutablePropertyValues中,没有绑定到属性上
  5. 依赖检查
  6. bean绑定到属性上
@SuppressWarnings("deprecation")  // for postProcessPropertyValues
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
   // 一般正常注入都是有值的
   if (bw == null) {
      // 如果BeanWrapper为空,但是有属性值,就跑异常
      if (mbd.hasPropertyValues()) {
         throw new BeanCreationException(
               mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
      }
      else {
         // 没有可填充的属性
         return;
      }
   }

   // Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
   // state of the bean before properties are set. This can be used, for example,
   // to support styles of field injection.
   // 给InstantiationAwareBeanPostProcessors最后一次机会在属性注入前修改Bean的属性值
   // 具体通过调用postProcessAfterInstantiation方法,如果调用返回false,表示不必继续进行依赖注入,直接返回
   if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
      for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
         if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
            return;
         }
      }
   }

   // 获取需要注入的属性值
   PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);

   // 获取装配模式
   int resolvedAutowireMode = mbd.getResolvedAutowireMode();
   if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
      // 1)把需要注入的属性先拷贝过来  2)经过下面的方法,获取到需要注入的bean,也会存到这里面来
      // 简单点说,就是这里面存储了哪些属性需要注入,然后下面获取到也存到这里面来, 但此时还没有进行引用关系的绑定
      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;
   }

   // 容器是否注册了InstantiationAwareBeanPostProcessor
   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);
   }

   // 上面获取的属性是以PropertyValues形式存在的, 需要注入到bean中
   if (pvs != null) {
      applyPropertyValues(beanName, mbd, bw, pvs);
   }
}

autowireByName() 根据名称自动注入

通过名称,将需要注入的属性添加到MutablePropertyValues

protected void autowireByName(String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {

   // 获取到需要依赖注入的属性
   // 获取到可写的(即set方法存在) && 非简单属性(包装类+Number+Date) 的属性名
   String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
   for (String propertyName : propertyNames) {
      // 判断缓存中是否有当前bean
      if (containsBean(propertyName)) {
         // 递归初始化相关的bean
         Object bean = getBean(propertyName);
         // 把需要注入的bean存进去
         pvs.add(propertyName, bean);
         // 注册依赖,将依赖关系保存到dependentBeanMapdependentBeanMap 中,key是 bean,value是 转化后的 propertyName
         registerDependentBean(propertyName, beanName);
         if (logger.isTraceEnabled()) {
            logger.trace("Added autowiring by name from bean name '" + beanName +
                  "' via property '" + propertyName + "' to bean named '" + propertyName + "'");
         }
      }
      else {
         if (logger.isTraceEnabled()) {
            logger.trace("Not autowiring property '" + propertyName + "' of bean '" + beanName +
                  "' by name: no matching bean found");
         }
      }
   }
}

autowireByType() 根据类型自动注入

通过类型,将需要注入的属性添加到MutablePropertyValues

protected void autowireByType(
      String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {

   // 获取自定义的类型转换器
   TypeConverter converter = getCustomTypeConverter();
   if (converter == null) {
      converter = bw;
   }

   Set<String> autowiredBeanNames = new LinkedHashSet<>(4);
   // 过滤出满足装配条件的Bean属性
   String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
   for (String propertyName : propertyNames) {
      try {
         // 获取属性描述符
         PropertyDescriptor pd = bw.getPropertyDescriptor(propertyName);
         // Don't try autowiring by type for type Object: never makes sense,
         // even if it technically is an unsatisfied, non-simple property.
         // 这里不解析Object的官方注释 :不要尝试按类型为Object类型自动装配:即使从技术上讲是不满意的,非简单的属性,也从没有意义。
         if (Object.class != pd.getPropertyType()) {
            // 获取指定属性的 set 方法
            MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd);
            // Do not allow eager init for type matching in case of a prioritized post-processor.
            boolean eager = !(bw.getWrappedInstance() instanceof PriorityOrdered);
            DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager);
            // 解析指定beanName 的属性所匹配的值,并把解析到的属性名存储在 autowiredBeanNames  中
		   // 当属性存在多个封装bean时,如 @Autowired List<Bean> beans,会找到所有的匹配Bean 类型的bean并将其注入。
		   // 这里的返回值是真正的需要注入的属性, autowiredBeanNames 是需要注入的属性(可能是集合)的names
            Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter);
            if (autowiredArgument != null) {
               // 添加到待注入的bean列表中
               pvs.add(propertyName, autowiredArgument);
            }
            // 注册依赖
            for (String autowiredBeanName : autowiredBeanNames) {
               // 注册依赖关系。操作 dependentBeanMap 和  dependenciesForBeanMap 集合
               registerDependentBean(autowiredBeanName, beanName);
               if (logger.isTraceEnabled()) {
                  logger.trace("Autowiring by type from bean name '" + beanName + "' via property '" +
                        propertyName + "' to bean named '" + autowiredBeanName + "'");
               }
            }
            autowiredBeanNames.clear();
         }
      }
      catch (BeansException ex) {
         throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName, propertyName, ex);
      }
   }
}

applyPropertyValues() 属性注入

上面已经通过名称/类型获取到了属性,并且添加到了PropertyValues中,但是此时还没有添加到bean中,下面的方法就是负责这个

protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
	// 如果属性列表为null,直接返回
	if (pvs.isEmpty()) {
		return;
	}

	if (System.getSecurityManager() != null && bw instanceof BeanWrapperImpl) {
		((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext());
	}

	MutablePropertyValues mpvs = null;
	List<PropertyValue> original;
	
	// 如果pvs 是 MutablePropertyValues 类型的封装
	if (pvs instanceof MutablePropertyValues) {
		mpvs = (MutablePropertyValues) pvs;
		// 判断 mpvs 中的值类型已经转换完毕,则可以直接设置到BeanWrapper 中
		if (mpvs.isConverted()) {
			try {
				bw.setPropertyValues(mpvs);
				return;
			}
			catch (BeansException ex) {
				throw new BeanCreationException(
							mbd.getResourceDescription(), beanName, "Error setting property values", ex);
			}
		}
		original = mpvs.getPropertyValueList();
	}
	else {
		original = Arrays.asList(pvs.getPropertyValues());
	}

	// 获取自定义转换类型,如果为null ,使用默认的bw, BeanWrapper 类继承了 TypeConverter 
	TypeConverter converter = getCustomTypeConverter();
	if (converter == null) {
		converter = bw;
	}
	BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter);

	// 这里是创建一个深度拷贝的list,解决值引用相关的问题
	List<PropertyValue> deepCopy = new ArrayList<>(original.size());
	boolean resolveNecessary = false;
	for (PropertyValue pv : original) {
		// 如果已经转换之后直接保存
		if (pv.isConverted()) {
			deepCopy.add(pv);
		}
		else {
			// 进行类型转换
			String propertyName = pv.getName();
			Object originalValue = pv.getValue();
			Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);
			Object convertedValue = resolvedValue;
			// 检查给定的属性是否可写, 或者检查属性是否是索引或嵌套的属性,比如a.b , 或者 [a,b]
			boolean convertible = bw.isWritableProperty(propertyName) &&
					!PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName);
			// 进行类型转换
			if (convertible) {
				convertedValue = convertForProperty(resolvedValue, propertyName, bw, converter);
			}
			// 将转换转换的值保存在pv 里面,同时加到深度拷贝list里面
			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);
	}
}

5.initializeBean() 初始化

  1. 执行3个处理器,BeanNameAwareBeanClassLoaderAwareBeanFactoryAware
  2. 执行BeanPostProcessor后置处理器的postProcessBeforeInitialization()
  3. 执行InitializingBean接口的afterPropertiesSet()
  4. 执行init-method初始化方法
  5. 执行BeanPostProcessor后置处理器的postProcessAfterInitialization()
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
   if (System.getSecurityManager() != null) {
      AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
         invokeAwareMethods(beanName, bean);
         return null;
      }, getAccessControlContext());
   }
   else {
      // 调用BeanNameAware、BeanClassLoaderAware、BeanFactoryAware
      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;
}

invokeAwareMethods()

如果该bean实现了对应的Aware接口,那么会负责实现,下面的代码就很简答了,分别负责处理BeanNameAwareBeanClassLoaderAwareBeanFactoryAware

private void invokeAwareMethods(String beanName, Object bean) {
   if (bean instanceof Aware) {
      if (bean instanceof BeanNameAware) {
         ((BeanNameAware) bean).setBeanName(beanName);
      }
      if (bean instanceof BeanClassLoaderAware) {
         ClassLoader bcl = getBeanClassLoader();
         if (bcl != null) {
            ((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
         }
      }
      if (bean instanceof BeanFactoryAware) {
         ((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
      }
   }
}

处理器的应用

BeanPostProcess是Spring开放式架构中一个必不可少的亮点,给用户充足的权限去更改或者扩展Spring。这里就是调用其注册的处理器,对bean进行处理

@Override
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
      throws BeansException {

   Object result = existingBean;
   for (BeanPostProcessor processor : getBeanPostProcessors()) {
      Object current = processor.postProcessBeforeInitialization(result, beanName);
      if (current == null) {
         return result;
      }
      result = current;
   }
   return result;
}
@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
      throws BeansException {

   Object result = existingBean;
   for (BeanPostProcessor processor : getBeanPostProcessors()) {
      Object current = processor.postProcessAfterInitialization(result, beanName);
      if (current == null) {
         return result;
      }
      result = current;
   }
   return result;
}

激活自定义的init方法

客户定制的初始化方法除了我们使用的配置init-method外,还有使自定义的bean实现InitializingBean接口,并在afterPropertiesSet()初始化业务逻辑

这2个都会在该方法中进行初始化,执行顺序为:

  1. afterPropertiesSet()
  2. init-method
protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBeanDefinition mbd)
      throws Throwable {

   // 1.检查该bean是否实现了InitializingBean接口
   boolean isInitializingBean = (bean instanceof InitializingBean);
   if (isInitializingBean && (mbd == null || !mbd.hasAnyExternallyManagedInitMethod("afterPropertiesSet"))) {
      if (logger.isTraceEnabled()) {
         logger.trace("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
      }
      if (System.getSecurityManager() != null) {
         try {
            AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
               ((InitializingBean) bean).afterPropertiesSet();
               return null;
            }, getAccessControlContext());
         }
         catch (PrivilegedActionException pae) {
            throw pae.getException();
         }
      }
      else {
         // 调用其自定义的初始化方法
         ((InitializingBean) bean).afterPropertiesSet();
      }
   }

   // 2.执行init-method方法
   if (mbd != null && bean.getClass() != NullBean.class) {
      String initMethodName = mbd.getInitMethodName();
      if (StringUtils.hasLength(initMethodName) &&
            !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
            !mbd.hasAnyExternallyManagedInitMethod(initMethodName)) {
         // 看到这里的方法名带个invoke就猜到会通过反射调用
         invokeCustomInitMethod(beanName, bean, mbd);
      }
   }
}

6.循环依赖检查

在Spring中解决循环依赖只对单例有效,而对于多例的bean,Spring没有好的解决办法,唯一要做的就是抛出异常

// 允许提前暴露Bean
if (earlySingletonExposure) {
   // 尝试从缓存获取,如果存在循环依赖,那么缓存中会存在
   Object earlySingletonReference = getSingleton(beanName, false);
   // 只要检测到循环依赖的情况才有值
   if (earlySingletonReference != null) {
      // 如果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) {
            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 " +
                  "'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.");
         }
      }
   }
}

7.销毁方法处理

如果配置了destroy-method,这里需要注册以便于在销毁时候调用

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()) {
         // Register a DisposableBean implementation that performs all destruction
         // work for the given bean: DestructionAwareBeanPostProcessors,
         // DisposableBean interface, custom destroy method.
         registerDisposableBean(beanName, new DisposableBeanAdapter(
               bean, beanName, mbd, getBeanPostProcessorCache().destructionAware, acc));
      }
      else {
         // A bean with a custom 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));
      }
   }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

为人师表好少年

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值