springboot源码分析——启动流程分析

前言

本文剖析SpringBoot启动时候做了哪些事情。

1、SpringBoot启动流程分析

1.1、 main方法进入

image

1.2、new SpringApplication&SpringApplication#run方法

  1. 首先new SpringApplication(primarySources)创建SpringApplication
  2. 调用其run方法

image

1.2.1、new SpringApplication(primarySources)创建SpringApplication

这里会调用其重载构造方法,构造方法执行步骤如下:

  1. 保存主启动类
  2. WebApplicationType#deduceFromClasspath:判断当前应用环境,从classpath下判断当前SpringBoot应用应该使用哪种环境启动。
  3. 设置初始化器(会将一组类型为ApplicationContextInitializer的初始化器放入SpringApplication中)
  4. 设置监听器(加载类型为ApplicationListener的监听器,和上面初始化器一样)
  5. 确定主配置类(找到有main方法的类)

image

1.2.1.1、WebApplicationType#deduceFromClasspath

从当前的classpath下面判断有没有一些类来确定当前应用的运行环境。

  1. 第一个if结构先判断是否是 Reactive 环境,发现有 WebFlux 的类但没有 WebMvc 的类,则判定为 Reactive 环境
  2. 之后的for循环要检查是否有跟 Servlet 相关的类,如果有任何一个类没有,则判定为非Web环境
  3. 如果for循环走完了,证明所有类均在当前 classpath 下,则为 Servlet(WebMvc) 环境

image

1.2.1.2、setInitializers& getSpringFactoriesInstances(ApplicationContextInitializer.class)

这个接口会加载ApplicationContextInitializer列表,ApplicationContextInitializer的作用是用于在刷新容器之前初始化Spring ConfigurableApplicationContext 的回调接口,我们也可以实现ApplicationContextInitializer接口来在容器刷新之前做一些我们的初始化逻辑。
这里SpringFactoriesLoader.loadFactoryNames之前文章已经讲解过了,这里他会通过SPI机制从META-INFO下的spring.factories加载所有类型为ApplicationContextInitializer并且创建对应的实例返回。

image

通过反射创建ApplicationContextInitializer实例

image

在spring-boot中一共配置了6个ApplicationContextInitializer:

  • ConfigurationWarningsApplicationContextInitializer:报告IOC容器的一些常见的错误配置
  • ContextIdApplicationContextInitializer:设置Spring应用上下文的ID
  • DelegatingApplicationContextInitializer:加载 application.properties 中 context.initializer.classes 配置的类
  • ServerPortInfoApplicationContextInitializer:将内置servlet容器实际使用的监听端口写入到 Environment 环境属性中
  • SharedMetadataReaderFactoryContextInitializer:创建一个 SpringBoot 和ConfigurationClassPostProcessor 共用的 CachingMetadataReaderFactory 对象
  • ConditionEvaluationReportLoggingListener:将 ConditionEvaluationReport 写入日志

setInitializers方法会把创建好的ApplicationContextInitializer放到initializers属性中

image

1.2.2.3、setListeners&getSpringFactoriesInstances(ApplicationListener.class))

这个流程和上面加载ApplicationContextInitializer一样,流程:

  1. 通过SPI机制加载所有类型为ApplicationListener的组件,并创建对应的实例
  2. 把创建出来的实例设置到listeners属性中

spring配置的内部监听者:

  • ClearCachesApplicationListener:应用上下文加载完成后对缓存做清除工作-
  • ParentContextCloserApplicationListener:监听双亲应用上下文的关闭事件并往自己的子应用上下文中传播
  • FileEncodingApplicationListener:检测系统文件编码与应用环境编码是否一致,如果系统文件编码和应用环境的编码不同则终止应用启动
  • AnsiOutputApplicationListener:根据 spring.output.ansi.enabled 参数配置 AnsiOutput
  • ConfigFileApplicationListener:从常见的那些约定的位置读取配置文件 -
  • DelegatingApplicationListener:监听到事件后转发给 application.properties 中配置的 context.listener.classes 的监听器
  • ClasspathLoggingApplicationListener:对环境就绪事件
  • ApplicationEnvironmentPreparedEvent 和应用失败事件 ApplicationFailedEvent 做出响应
  • LoggingApplicationListener:配置 LoggingSystem。使用 logging.config 环境变量指定的配置或者缺省配置
  • LiquibaseServiceLocatorApplicationListener:使用一个可以和 SpringBoot 可执行jar包配合工作的版本替换 LiquibaseServiceLocator
  • BackgroundPreinitializer:使用一个后台线程尽早触发一些耗时的初始化任务

1.2.2.4、deduceMainApplicationClass()

这里就是跟着当前方法的调用栈往上爬,哪一层调用栈上有main方法,方法对应的类就是主配置类,就返回这个类。

image

1.2.2、SpringApplication#run

方法步骤如下:

  1. StopWatch:创建时间性能监控器
  2. 创建空的IOC容器,和一组异常报告器
  3. configureHeadlessProperty():配置与awt相关的信息
  4. getRunListeners:获取SpringApplicationRunListeners
  5. prepareEnvironment:准备运行时环境
  6. configureIgnoreBeanInfo:配置系统参数
  7. printBanner:打印Banner
  8. createApplicationContext:创建IOC容器
  9. prepareContext:初始化IOC容器
  10. refreshContext:刷新IOC容器
  11. afterRefresh:刷新后的处理
  12. listeners.started:发布started时间
  13. callRunners:运行器回调

image

1.2.2.1、new StopWatch()

这个就是一个计时器,用来监控启动耗时的,不重要

1.2.2.2、创建空的IOC容器和一组异常报告器

这里SpringBootExceptionReporter是启动错误报告的报告器,并且也是用SpringFactoriesLoader加载,实现类只有一个:FailureAnalyzers

image

1.2.2.3、configureHeadlessProperty:设置awt相关

这里从System中取出一个配置,然后又给设置回去了,这里大家可以不用关注,这里的作用是:设置应用在启动时,即使没有检测到显示器也允许其继续运行。

image

1.2.2.4、getRunListeners:获取SpringApplicationRunListeners

这里又是使用SPI机制加载SpringApplicationRunListener的实现类,默认加载的listener只有一个,类型为EventPublishingRunListener。

image

SpringApplicationRunListener的回调方法以及回调时机。

image

1.2.2.5、prepareEnvironment:准备运行时环境

  1. 这里在执行prepareEnvironment之前调用了listeners.starting()进行事件回调。
  2. 这里可以把Environment理解为IOC容器的运行环境,包括Profile和Properties两大部分,他可由一个到几个激活的Profile共同配置,他的配置可在应用级bean中获取。
    下面方法步骤如下:
  • getOrCreateEnvironment:创建运行时环境
  • configureEnvironment:配置运行时环境
  • bindToSpringApplication:环境与应用绑定
  • 这里也会回调listeners.environmentPrepared方法。

image

1.2.2.5.1、getOrCreateEnvironment:创建运行时环境

这里就是根据当前的应用运行环境类型,创建不同的Environment,默认SpringBoot环境下会创建StandardServletEnvironment。
image

1.2.2.5.2、configureEnvironment:配置运行时环境
  1. 这里ConversionService是类型转换的根接口,它是用来在SpringWebMvc中用来做参数转换的。
  2. 配置PropertySource和Profile

image

1.2.2.5.3、configureEnvironment:环境与应用绑定

这里逻辑比较深,但是作用是:把配置内容绑定到指定的属性配置类中(类似@ConfigurationProperties)

image

1.2.2.6、configureIgnoreBeanInfo:设置系统参数

这里是控制是否跳过BeanInfo类的搜索(spring.beaninfo.ignore),默认是true。
image

1.2.2.7、printBanner:打印Banner

这里就是控制SpringBoot启动时候打印的图案,默认情况下是打印在控制台的Banner。
image

1.2.2.8、createApplicationContext:创建IOC容器

这里根据不同的环境创建不同的IOC容器,但是创建的都是基于Annotation的ApplicationContext.
IOC容器类型:

  • Servlet - StandardServletEnvironment - AnnotationConfigServletWebServerApplicationContext
  • Reactive - StandardReactiveWebEnvironment - AnnotationConfigReactiveWebServerApplicationContext
  • None - StandardEnvironment - AnnotationConfigApplicationContext

image

image

1.2.2.9、prepareContext:初始化IOC容器

  1. 将创建好的Environment设置到IOC容器中
  2. 执行IOC容器的后置处理
  3. 执行Initializer
  4. 执行listeners#contextPrepared回调方法
  5. 创建两个组件用来在控制台打印Banner
  6. 加载和注册主启动类
  7. 回调listeners#contextLoaded方法

image

1.2.2.9.1、postProcessApplicationContext:IOC容器的后置处理

这里设置了几个组件:

  1. 如果 beanNameGenerator 不为空,则把它注册到IOC容器中。 BeanNameGenerator 是Bean的name生成器。
  2. 设置ResourceLoader 和 ClassLoader,这个之前已经准备好了
  3. 设置ConversionService,这个之前已经准备好了,并且还做了容器共享。

image

1.2.2.9.2、applyInitializers:执行Initializer

这里会获取到所有的ApplicationContextInitializer,然后调用其initialize方法。

image

1.2.2.9.2、getAllSources:获取主启动类

这里会获取primarySources和sources,之前分析的时候知道primarySources已经被设置为主启动类,sources目前是空的,所以这个方法最终返回的是主启动类。
image

1.2.2.9.3、load:注册主启动类
  1. getBeanDefinitionRegistry获取到IOC容器,然后执行createBeanDefinitionLoader创建一个> BeanDefinitionLoader
  2. 给leader设置BeanName生成器、资源加载器、运行时环境
  3. 调用BeanDefinitionLoader#load方法。

image

1.2.2.9.3.1、BeanDefinitionLoader#load

这里会根据传入的source类型,来决定用哪种方式加载,这里我们的主启动类是属于Class类型,所以继续调用重载的lead方法

image

这里上面Groovy相关的判断我们不关心,下面会判断source是否是一个Component,因为我们的主启动类上标记了@SpringBootApplication注解,而 @SpringBootApplication 组合了一个 @SpringBootConfiguration,它又组合了一个 @Configuration 注解,@Configuration 的底层就是一个 @Component 。所以这里会调用annotatedReader#register方法

image

1.2.2.9.3.1、AnnotatedBeanDefinitionReader#register

这里会调用到doRegisterBean,在doRegisterBean方法中会把启动类包装成BeanDefinition,然后把BeanDefinition注册到容器中。

image

1.2.2.10、refreshContext:刷新容器上下文

  1. 这里调用了refresh方法,这个是最重要的方法了
  2. 这里注册了一个关闭的钩子,这个钩子是监听JVM关闭时销毁IOC容器和里面的Bean,这里面有一个很经典的应用:应用停止和释放数据库连接池里面的连接。

image

1.2.2.10.1 、SpringApplication#refreshContext:刷新容器上下文

这里会直接强转成AbstractApplicationContext并调用其refresh方法。AbstractApplicationContext的refresh方法是IOC容器启动最核心的方法,我们在下面单起一小节讲IOC容器的刷新方法。

image

1.2.2.11、afterRefresh:刷新后的处理

空方法,目前没有实现。

image

1.2.2.12、listeners.started:发布started事件

image

1.2.2.12.1、EventPublishingRunListener#started

这里就是调用ConfigurableApplicationContext来发布ApplicationReadyEvent事件
image

1.2.2.12、callRunners:运行器回调

这里会回调CommandLineRunner和ApplicationRunner的run方法,这个也是回调使用的,可以实现它用来扩展。

image

至此,SpringBoot启动完成。

2. AbstractApplicationContext#refresh方法:刷新容器上下文

这个方法非常长,我们下面逐一剖析其中的每个流程

	public void refresh() throws BeansException, IllegalStateException {
		synchronized (this.startupShutdownMonitor) {
			StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");
			// Prepare this context for refreshing.
			//1.初始化前的预处理
			prepareRefresh();
			// Tell the subclass to refresh the internal bean factory.
			//2.获取BeanFactory,加载所有bean的定义信息(未实例化)
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

			// Prepare the bean factory for use in this context.
			//3.BeanFactory的预处理配置
			prepareBeanFactory(beanFactory);
			try {
				// Allows post-processing of the bean factory in context subclasses.
				//4.准备BeanFactory完成后进行的后置处理,是个抽象
				postProcessBeanFactory(beanFactory);

				StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
				// Invoke factory processors registered as beans in the context.
				//5. 执行BeanFactory创建后的后置处理器,他会执行所有的BeanDefinitionRegistryPostProcessor 和 BeanFactoryPostProcessor ,
				// 主要工作是包扫描、解析配置类等
				invokeBeanFactoryPostProcessors(beanFactory);

				// Register bean processors that intercept bean creation.
				//6.注册BeanPostProcessor,这个方法中会注册所有的BeanPostProcessor
				// AnnotationAwareAspectJAutoProxyCreator的初始化时机, AnnotationAwareAspectJAutoProxyCreator实现了Ordered接口,
				//他会提前于普通BeanPostProcessor的创建,也就表示普通的BeanPostProcessor也会被AOP代理
					registerBeanPostProcessors(beanFactory);
				beanPostProcess.end();

				// Initialize message source for this context.
				//7.初始化MessageSource,初始化国际化组件
				initMessageSource();

				// Initialize event multicaster for this context.
				//8.初始化事件派发器
				//它会构造一个 SimpleApplicationEventMulticaster ,并注册进 BeanFactory
				initApplicationEventMulticaster();

				// Initialize other special beans in specific context subclasses.
				//9. 子类的多态onRefresh,子类扩展的刷新动作
				onRefresh();

				// Check for listener beans and register them.
				//10.注册监听器
				registerListeners();

				// Instantiate all remaining (non-lazy-init) singletons.
				//11.初始化剩余的单实例Bean
				finishBeanFactoryInitialization(beanFactory);

				// Last step: publish corresponding event.
				//12.完成容器的创建工作
				finishRefresh();
			} catch (BeansException ex) {
				if (logger.isWarnEnabled()) {
					logger.warn("Exception encountered during context initialization - " +
							"cancelling refresh attempt: " + ex);
				}

				// Destroy already created singletons to avoid dangling resources.
				destroyBeans();

				// Reset 'active' flag.
				cancelRefresh(ex);

				// Propagate exception to caller.
				throw ex;
			} finally {
				// Reset common introspection caches in Spring's core, since we
				// might not ever need metadata for singleton beans anymore...
				//清除缓存
				resetCommonCaches();
				contextRefresh.end();
			}
		}
	}

2.1 、prepareRefresh:初始化前的预处理

  1. 记录启动时间,标记IOC容器状态,之后初始化属性
  2. 保存容器的早期事件(这个时候事件广播器还没初始化,所以需要保存需要广播的事件)

image

2.2 、obtainFreshBeanFactory:获取BeanFactory,加载所有bean定义信息

先刷新后获取

image

2.2.1、GenericApplicationContext#refreshBeanFactory

refreshBeanFactory是一个抽象方法,留给子类重写,对于XML配置的IOC容器和注解配置的IOC容器非别有一种实现GenericApplicationContext 和 AbstractRefreshableApplicationContext 重写了它。根据前面的分析,AnnotationConfigServletWebServerApplicationContext 继承了 GenericApplicationContext。AbstractRefreshableApplicationContext就不进行分析了,因为现在都是基于注解驱动,很少用xml配置了。

image

GenericApplicationContext#refreshBeanFactory只是简单设置了序列化ID,

image

2.2.2、GenericApplicationContext#getBeanFactory

这里getBeanFactory也是一个抽象方法,我们看下GenericApplicationContext#getBeanFactory的实现就是把beanFactory直接返回

image

2.3 、prepareBeanFactory:BeanFactory的预处理配置

  1. 首先配置了一个ApplicationContextAwareProcessor,然后又忽略了一些Aware接口。
  2. 然后就是自动注入的支持
  3. 又注册一个后置处理器ApplicationListenerDetector,它是用来收集ApplicationListener的。

image

2.3.1、ApplicationContextAwareProcessor

首先我们注册了ApplicationContextAwareProcessor到IOC容器,并且忽略了一些Ware接口。我们发现注入的后置处理作用就是在挨个判断Ware类型,然后注入需要的数据。

image

2.3.2、ApplicationListenerDetector

addBeanPostProcessor(new ApplicationListenerDetector(this))注册了一个ApplicationListenerDetector的后置处理器,这个后置处理器会收集所有的监听器,把监听器挂载到applicationContext中,这样这些监听器后续才可以被事件广播器广播到。

image

2.4 、postProcessBeanFactory:BeanFactory的后置处理

这个方法是个抽象方法,子类AnnotationConfigServletWebServerApplicationContext重写了这个方法

image

2.4.1、ServletWebServerApplicationContext#postProcessBeanFactory

首先调用了父类ServletWebServerApplicationContext#postProcessBeanFactory方法,这里往IOC容器中注册了WebApplicationContextServletContextAwareProcessor,并且忽略了ServletContextAware。

image

这里就是和上面之前处理aware接口一样,她会把ServletContext和ServletConfig注入到组件中。
image

2.4.2、registerWebApplicationScopes

registerWebApplicationScopes方法,这里就不细看了,逻辑就是把Web的request域和session域注册到IOC容器中,让IOC容器知道这两种作用域(Bean的作用域)

image

2.4.3、包扫描

这里如果debug的话if是不进来的,在后续的refresh#invokeBeanFactoryPostProcessors会调用到,我们这里先讲一下ClassPathBeanDefinitionScanner#scan方法执行流程

image

2.4.3.1、ClassPathBeanDefinitionScanner#doCcan

这里发现首先会调用findCandidateComponents方法,这里返回的是beanDefinition,然后后续对beanDefinition做一些处理然后调用registerBeanDefinition注册到IOC容器中

image

2.4.3.1.1、findCandidateComponents

这里会来到父类ClassPathScanningCandidateComponentProvider#findCandidateComponents方法,然后这里会进入scanCandidateComponents方法

image

2.4.3.1.2、scanCandidateComponents

首先它将要扫描的包和一些前缀进行拼接:首先它将要扫描的包和一些前缀进行拼接:前缀是 classpath*: ,后缀默认扫 **/.class ,中间部分调了一个 resolveBasePackage 方法,这个方法其实不看也能猜出来是把这个包名转换成文件路径。这里拼接出来的包路径是: classpath:/com/example/demo/xx/x.class。然后后面会调用getResources方法执行包扫描逻辑。

image

2.4.3.1.3、PathMatchingResourcePatternResolver#getResources方法

整个方法的大if结构中,先判断要扫描的包路径是否有 classpath*: ,有则截掉,之后判断路径是否能匹配扫描规则。而这个规则的匹配器,通过IDEA发现 PathMatcher 只有一个实现类: AntPathMatcher ,由此也解释了 SpringFramework 支持的是ant规则声明包。

如果规则匹配,则会进入下面的 findPathMatchingResources 方法

image

2.4.3.1.3.1、findPathMatchingResources方法

首先它会截取扫描根路径,就是启动类所在的包classpath*:com/example/demo/ ,截取完成之后,又把根路径传入了getResources方法,这次没有后缀,只有根路径,然后在getResources方法中会进入findAllClassPathResources方法中

image

2.4.3.1.3.2、findAllClassPathResources方法

这里真正进行扫描获取包的工作会交给doFindAllClassPathResources方法
image

2.4.3.1.3.3、doFindAllClassPathResources方法

这里它做的工作就是使用类加载器,把传入的根包以Resource的形式加载出来,以便后续的文件读取。
image

2.4.3.1.4、解析Component

在scanCandidateComponents方法中,获取所有的Resources,那么后续它使用了一个 MetadataReader 来解析.class文件,它就可以读取这个class的类定义信息、注解标注信息。之后要用 MetadataReader 来判断这个class是否为一个 Component。isCandidateComponent方法会判断class是否被@Component/@ManagedBean标注,如果判断为Component后,会将这个class封装成beanDefinition

image

image

2.4.3.2、ClassPathBeanDefinitionScanner#doScan

在上面方法中我们已经解析出来了路径中包含的Componet的组件,并且生成了BeanDefinition。然后后续就是遍历这些BeanDefinition然后生成BeanName,处理一些bean的元信息,然后注册到IOC容器中

image

2.5 、invokeBeanFactoryPostProcessors:创建BeanFactory创建后的后置处理器

BeanFactoryPostProcessor是一个接口,它提供一个方法,可以在BeanDefinition已经被加载,但没有Bean被实例化,可以对BeanFactory进行后置处理。他还有一个字接口BeanDefinitionRegistryPostProcessor,执行时机是在所有Bean的定义信息即将被加载但未实例化时,也就是咸鱼BeanFactoryPostProcessor,可以实现往容器中添加BeanDefinition。
我们看下下面这个方法,它会去调用invokeBeanFactoryPostProcessors方法。

image

2.5.1 、PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors:回调后置处理器

  1. 首先遍历一次,把BeanDefinitionRegistryPostProcessor的后置处理器单独挑出来,直接回调postProcessBeanDefinitionRegistry方法
  2. 把BeanFactory中所有的BeanDefinitionRegistryPostProcessor分成三部分:实现 PriorityOrdered 接口的、实现 Ordered 接口的,普通的。下面的流程是先进行筛选,然后进行排序,然后注册,最后执行回调,再清除
  3. 最后也会筛选出BeanFactoryPostProcessor,执行和上面BeanDefinitionRegistryPostProcessor的所有逻辑。
	public static void invokeBeanFactoryPostProcessors(
			ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {

		// WARNING: Although it may appear that the body of this method can be easily
		// refactored to avoid the use of multiple loops and multiple lists, the use
		// of multiple lists and multiple passes over the names of processors is
		// intentional. We must ensure that we honor the contracts for PriorityOrdered
		// and Ordered processors. Specifically, we must NOT cause processors to be
		// instantiated (via getBean() invocations) or registered in the ApplicationContext
		// in the wrong order.
		//
		// Before submitting a pull request (PR) to change this method, please review the
		// list of all declined PRs involving changes to PostProcessorRegistrationDelegate
		// to ensure that your proposal does not result in a breaking change:
		// https://github.com/spring-projects/spring-framework/issues?q=PostProcessorRegistrationDelegate+is%3Aclosed+label%3A%22status%3A+declined%22

		// Invoke BeanDefinitionRegistryPostProcessors first, if any.
		// 首先调用BeanDefinitionRegistryPostProcessor
		Set<String> processedBeans = new HashSet<>();

		//这里要判断BeanFactory的类型,默认SpringBoot创建的BeanFactory是DefaultListableBeanFacotry
		//这个类实现了BeanDefinitionRegistry,则此if结构必进
		if (beanFactory instanceof BeanDefinitionRegistry registry) {
			List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
			List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();

			//这里会区分不同的后置处理器,并划分成不同的集合中
			// 该部分会将BeanFactoryPostProcessor与BeanDefinitionRegistryPostProcessor分离开
			for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
				if (postProcessor instanceof BeanDefinitionRegistryPostProcessor registryProcessor) {
					registryProcessor.postProcessBeanDefinitionRegistry(registry);
					registryProcessors.add(registryProcessor);
				} else {
					regularPostProcessors.add(postProcessor);
				}
			}

			// Do not initialize FactoryBeans here: We need to leave all regular beans
			// uninitialized to let the bean factory post-processors apply to them!
			// Separate between BeanDefinitionRegistryPostProcessors that implement
			// PriorityOrdered, Ordered, and the rest.
			// 不要在这里初始化BeanFactory:我们需要保留所有未初始化的常规bean,以便让bean工厂后处理器应用到它们!
			// 独立于实现PriorityOrdered、Ordered和其他的BeanDefinitionRegistryPostProcessor之间。
			List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();

			// 这部分实际上想表达的意思是,在创建Bean之前,要先执行这些
			// BeanDefinitionRegistryPostProcessor的后置处理方法,并且实现了
			// PriorityOrdered排序接口或实现了Ordered接口的Bean需要优先被加载。

			// 下面一段是从BeanFactory中取出所有BeanDefinitionRegistryPostProcessor类型的全限定名(String[]),
			// 放到下面遍历,还要判断这些类里是否有实现PriorityOrdered接口的,
			// 如果有,存到集合里,之后进行排序、统一回调这些后置处理器

			// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
			// 首先,调用实现PriorityOrdered接口的BeanDefinitionRegistryPostProcessors。
			String[] postProcessorNames =
					beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
			for (String ppName : postProcessorNames) {
				if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
					currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
					processedBeans.add(ppName);
				}
			}
			sortPostProcessors(currentRegistryProcessors, beanFactory);
			registryProcessors.addAll(currentRegistryProcessors);
			invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
			currentRegistryProcessors.clear();

			// Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
			//接下来,执行实现了Ordered接口的BeanDefinitionRegistryPostProcessor
			postProcessorNames =
					beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
			for (String ppName : postProcessorNames) {
				if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
					currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
					processedBeans.add(ppName);
				}
			}
			sortPostProcessors(currentRegistryProcessors, beanFactory);
			registryProcessors.addAll(currentRegistryProcessors);
			invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
			currentRegistryProcessors.clear();

			// Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
			//最后,执行所有其他的BeanDefinitionRegistryPostProcessor
			boolean reiterate = true;
			while (reiterate) {
				reiterate = false;
				postProcessorNames =
						beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
				for (String ppName : postProcessorNames) {
					if (!processedBeans.contains(ppName)) {
						currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
						processedBeans.add(ppName);
						reiterate = true;
					}
				}
				sortPostProcessors(currentRegistryProcessors, beanFactory);
				registryProcessors.addAll(currentRegistryProcessors);
				invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
				currentRegistryProcessors.clear();
			}

			// Now, invoke the postProcessBeanFactory callback of all processors handled so far.
			//回调所有BeanFactoryPostProcessor的postProcessBeanFactory方法
			// 先回调BeanDefinitionRegistryPostProcessor的postProcessBeanFactory方法
			// 再调用BeanFactoryPostProcessor的postProcessBeanFactory方法
			invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
			invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
		} else {
			// 如果BeanFactory没有实现BeanDefinitionRegistry接口,则进入下面的代码流程

			//调用在上下文实例中注册的工厂处理器
			invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
		}

		// 下面的部分是回调BeanFactoryPostProcessor,思路与上面的几乎一致。
		// Do not initialize FactoryBeans here: We need to leave all regular beans
		// uninitialized to let the bean factory post-processors apply to them!
		String[] postProcessorNames =
				beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);

		// Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
		// Ordered, and the rest.
		List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
		List<String> orderedPostProcessorNames = new ArrayList<>();
		List<String> nonOrderedPostProcessorNames = new ArrayList<>();
		for (String ppName : postProcessorNames) {
			if (processedBeans.contains(ppName)) {
				// skip - already processed in first phase above
			} else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
				priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
			} else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
				orderedPostProcessorNames.add(ppName);
			} else {
				nonOrderedPostProcessorNames.add(ppName);
			}
		}

		// First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
		sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
		invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

		// Next, invoke the BeanFactoryPostProcessors that implement Ordered.
		List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
		for (String postProcessorName : orderedPostProcessorNames) {
			orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
		}
		sortPostProcessors(orderedPostProcessors, beanFactory);
		invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);

		// Finally, invoke all other BeanFactoryPostProcessors.
		List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
		for (String postProcessorName : nonOrderedPostProcessorNames) {
			nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
		}
		invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);

		// Clear cached merged bean definitions since the post-processors might have
		// modified the original metadata, e.g. replacing placeholders in values...
		//清理缓存
		beanFactory.clearMetadataCache();
	}

2.5.2、ConfigurationClassPostProcessor#postProcessBeanDefinitionRegistry

在上面回调各种BeanFactory的后置处理器,在spring内部有一个很重要的BeanFactoryPostProcessor是ConfigurationClassPostProcessor,他的作用是用于@Configuration类的扫描加载处理。我们看下它的postProcessBeanDefinitionRegistry方法的执行逻辑:他取出BeanFactory的id,判断是否已经被调用过了,如果没有,会在被调用过的集合中加上当前BeanFactory的id,之后会调用processConfigBeanDefinitions方法。

image

2.5.2.1、ConfigurationClassPostProcessor#processConfigBeanDefinitions

  1. 首先获取所有的配置类和组件,然后对配置类排序
  2. 构造默认的Bean名称的生成器
  3. 调用ConfigurationClassParser#parse方法解析配置类
  4. 调用ConfigurationClassBeanDefinitionReader#loadBeanDefinitions加载配置类中的Bean定义信息,然后注册到IOC容器中
	public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
		List<BeanDefinitionHolder> configCandidates = new ArrayList<>();
		String[] candidateNames = registry.getBeanDefinitionNames();

		//筛选出来所有的配置类
		for (String beanName : candidateNames) {
			BeanDefinition beanDef = registry.getBeanDefinition(beanName);
			//full configuration
			if (beanDef.getAttribute(ConfigurationClassUtils.CONFIGURATION_CLASS_ATTRIBUTE) != null) {
				if (logger.isDebugEnabled()) {
					logger.debug("Bean definition has already been processed as a configuration class: " + beanDef);
				}
			} else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
				configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
			}
		}

		// Return immediately if no @Configuration classes were found
		if (configCandidates.isEmpty()) {
			return;
		}

		// Sort by previously determined @Order value, if applicable
		//配置类排序
		configCandidates.sort((bd1, bd2) -> {
			int i1 = ConfigurationClassUtils.getOrder(bd1.getBeanDefinition());
			int i2 = ConfigurationClassUtils.getOrder(bd2.getBeanDefinition());
			return Integer.compare(i1, i2);
		});

		// Detect any custom bean name generation strategy supplied through the enclosing application context
		//构造默认的BeanNameGenerator bean的名称生成器
		SingletonBeanRegistry sbr = null;
		if (registry instanceof SingletonBeanRegistry) {
			sbr = (SingletonBeanRegistry) registry;
			if (!this.localBeanNameGeneratorSet) {
				BeanNameGenerator generator = (BeanNameGenerator) sbr.getSingleton(
						AnnotationConfigUtils.CONFIGURATION_BEAN_NAME_GENERATOR);
				if (generator != null) {
					this.componentScanBeanNameGenerator = generator;
					this.importBeanNameGenerator = generator;
				}
			}
		}

		if (this.environment == null) {
			this.environment = new StandardEnvironment();
		}

		// Parse each @Configuration class
		//真正解析配置类的组件  ConfigurationClassParser
		ConfigurationClassParser parser = new ConfigurationClassParser(
				this.metadataReaderFactory, this.problemReporter, this.environment,
				this.resourceLoader, this.componentScanBeanNameGenerator, registry);

		Set<BeanDefinitionHolder> candidates = new LinkedHashSet<>(configCandidates);
		Set<ConfigurationClass> alreadyParsed = new HashSet<>(configCandidates.size());
		do {
			StartupStep processConfig = this.applicationStartup.start("spring.context.config-classes.parse");
			//解析配置类 go parse method
			parser.parse(candidates);
			parser.validate();

			Set<ConfigurationClass> configClasses = new LinkedHashSet<>(parser.getConfigurationClasses());
			configClasses.removeAll(alreadyParsed);

			// Read the model and create bean definitions based on its content
			if (this.reader == null) {
				this.reader = new ConfigurationClassBeanDefinitionReader(
						registry, this.sourceExtractor, this.resourceLoader, this.environment,
						this.importBeanNameGenerator, parser.getImportRegistry());
			}
			//加载配置类的内容 go loadBeanDefinitions 在这里注册所有的BeanDefinition
			this.reader.loadBeanDefinitions(configClasses);
			alreadyParsed.addAll(configClasses);
			processConfig.tag("classCount", () -> String.valueOf(configClasses.size())).end();

			candidates.clear();
			if (registry.getBeanDefinitionCount() > candidateNames.length) {
				String[] newCandidateNames = registry.getBeanDefinitionNames();
				Set<String> oldCandidateNames = new HashSet<>(Arrays.asList(candidateNames));
				Set<String> alreadyParsedClasses = new HashSet<>();
				for (ConfigurationClass configurationClass : alreadyParsed) {
					alreadyParsedClasses.add(configurationClass.getMetadata().getClassName());
				}
				for (String candidateName : newCandidateNames) {
					if (!oldCandidateNames.contains(candidateName)) {
						BeanDefinition bd = registry.getBeanDefinition(candidateName);
						if (ConfigurationClassUtils.checkConfigurationClassCandidate(bd, this.metadataReaderFactory) &&
								!alreadyParsedClasses.contains(bd.getBeanClassName())) {
							candidates.add(new BeanDefinitionHolder(bd, candidateName));
						}
					}
				}
				candidateNames = newCandidateNames;
			}
		}
		while (!candidates.isEmpty());

		// Register the ImportRegistry as a bean in order to support ImportAware @Configuration classes
		if (sbr != null && !sbr.containsSingleton(IMPORT_REGISTRY_BEAN_NAME)) {
			sbr.registerSingleton(IMPORT_REGISTRY_BEAN_NAME, parser.getImportRegistry());
		}

		if (this.metadataReaderFactory instanceof CachingMetadataReaderFactory cachingMetadataReaderFactory) {
			// Clear cache in externally provided MetadataReaderFactory; this is a no-op
			// for a shared cache since it'll be cleared by the ApplicationContext.
			cachingMetadataReaderFactory.clearCache();
		}
	}

2.5.2.2、ConfigurationClassParser#parse

它会遍历每一个BeanDefinition,并根据类型来决定如何解析,SpringBoot通常使用的注解配置会进入第一个if结构,我们看下重载的parse方法。
image

2.5.2.2.1、ConfigurationClassParser#processConfigurationClass

重载的方法会调用processConfigurationClass方法,在processConfigurationClass判断下是否已经重复处理了,最终会调用processConfigurationClass方法。

image

2.5.2.2.2、ConfigurationClassParser#doProcessConfigurationClass

里方法中就会去解析 @PropertySource 、@ComponentScan 、@Import 、@ImportResource 、@Bean 等注解,并整理成一个 ConfigClass,在这一步,一个配置类就被解析完成了。

	protected final SourceClass doProcessConfigurationClass(
			ConfigurationClass configClass, SourceClass sourceClass, Predicate<String> filter)
			throws IOException {

		//处理@Component注解
		if (configClass.getMetadata().isAnnotated(Component.class.getName())) {
			// Recursively process any member (nested) classes first
			processMemberClasses(configClass, sourceClass, filter);
		}

		// Process any @PropertySource annotations
		//处理@PropertySource注解
		for (AnnotationAttributes propertySource : AnnotationConfigUtils.attributesForRepeatable(
				sourceClass.getMetadata(), PropertySources.class,
				org.springframework.context.annotation.PropertySource.class)) {
			if (this.environment instanceof ConfigurableEnvironment) {
				processPropertySource(propertySource);
			} else {
				logger.info("Ignoring @PropertySource annotation on [" + sourceClass.getMetadata().getClassName() +
						"]. Reason: Environment must implement ConfigurableEnvironment");
			}
		}

		// Process any @ComponentScan annotations
		//处理@ComponentScan注解
		Set<AnnotationAttributes> componentScans = AnnotationConfigUtils.attributesForRepeatable(
				sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class);
		if (!componentScans.isEmpty() &&
				!this.conditionEvaluator.shouldSkip(sourceClass.getMetadata(), ConfigurationPhase.REGISTER_BEAN)) {
			//如果有@ComponentScans,则要取出里面所有的@ComponentScan依次扫描
			for (AnnotationAttributes componentScan : componentScans) {
				// The config class is annotated with @ComponentScan -> perform the scan immediately
				// 【复杂】借助ComponentScanAnnotationParser扫描  go parse method
				Set<BeanDefinitionHolder> scannedBeanDefinitions =
						this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());
				// Check the set of scanned definitions for any further config classes and parse recursively if needed
				//是否扫描到了其他的注解配置类
				for (BeanDefinitionHolder holder : scannedBeanDefinitions) {
					BeanDefinition bdCand = holder.getBeanDefinition().getOriginatingBeanDefinition();
					if (bdCand == null) {
						bdCand = holder.getBeanDefinition();
					}
					if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) {
						//如果扫描到了递归解析
						parse(bdCand.getBeanClassName(), holder.getBeanName());
					}
				}
			}
		}

		// Process any @Import annotations
		//处理@Import注解
		processImports(configClass, sourceClass, getImports(sourceClass), filter, true);

		// Process any @ImportResource annotations
		//处理@ImportResource注解
		//注解配置类上标注 @ImportResource 可以导入 xml 配置文件,而解析这些 @ImportResource 的逻辑就在这里。不过看源码的套路中,怎么只是把配置文件的路径放入了
		// configClass 而已呢?咋不解析呀?莫慌,我们之前看 ConfigurationClassPostProcessor 的后置处理 processConfigBeanDefinitions 方法中,
		// 不是在 parse 方法下面还有个 loadBeanDefinitions 方法嘛
		AnnotationAttributes importResource =
				AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(), ImportResource.class);
		if (importResource != null) {
			String[] resources = importResource.getStringArray("locations");
			Class<? extends BeanDefinitionReader> readerClass = importResource.getClass("reader");
			for (String resource : resources) {
				String resolvedResource = this.environment.resolveRequiredPlaceholders(resource);
				configClass.addImportedResource(resolvedResource, readerClass);
			}
		}

		// Process individual @Bean methods
		//处理@Bean注解,这里也只是存起来,处理是在retrieveBeanMethodMetadata方法中
		Set<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(sourceClass);
		for (MethodMetadata methodMetadata : beanMethods) {
			configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
		}

		// Process default methods on interfaces
		//处理父接口
		processInterfaces(configClass, sourceClass);

		// Process superclass, if any
		//父类的返回
		//如果配置类存在父类的话,父类也应该一起加载,所以这里会取到配置类的父类,并继续递归处理。
		if (sourceClass.getMetadata().hasSuperClass()) {
			String superclass = sourceClass.getMetadata().getSuperClassName();
			if (superclass != null && !superclass.startsWith("java") &&
					!this.knownSuperclasses.containsKey(superclass)) {
				this.knownSuperclasses.put(superclass, configClass);
				// Superclass found, return its annotation metadata and recurse
				return sourceClass.getSuperClass();
			}
		}

		// No superclass -> processing is complete
		return null;
	}

2.5.2.2.3、解析 @ComponentScan

这里以解析@ComponentScan注解为例,来看下解析流程,它会调用到ComponentScanAnnotationParser#parse方法,这里会解析注解中的属性和包扫描路径等,最终会调用到ClassPathBeanDefinitionScanner#doScan方法,这里doScan方法我们之前已经剖析过了,会去扫描注册所有的Component组件。

	public Set<BeanDefinitionHolder> parse(AnnotationAttributes componentScan, String declaringClass) {
		//构造ClassPathBeanDefinitionScanner
		ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(this.registry,
				componentScan.getBoolean("useDefaultFilters"), this.environment, this.resourceLoader);

		//解析@ComponentScan中的属性
		Class<? extends BeanNameGenerator> generatorClass = componentScan.getClass("nameGenerator");
		boolean useInheritedGenerator = (BeanNameGenerator.class == generatorClass);
		scanner.setBeanNameGenerator(useInheritedGenerator ? this.beanNameGenerator :
				BeanUtils.instantiateClass(generatorClass));

		//整理要扫描的basePackages
		ScopedProxyMode scopedProxyMode = componentScan.getEnum("scopedProxy");
		if (scopedProxyMode != ScopedProxyMode.DEFAULT) {
			scanner.setScopedProxyMode(scopedProxyMode);
		}
		else {
			Class<? extends ScopeMetadataResolver> resolverClass = componentScan.getClass("scopeResolver");
			scanner.setScopeMetadataResolver(BeanUtils.instantiateClass(resolverClass));
		}

		scanner.setResourcePattern(componentScan.getString("resourcePattern"));

		for (AnnotationAttributes includeFilterAttributes : componentScan.getAnnotationArray("includeFilters")) {
			List<TypeFilter> typeFilters = TypeFilterUtils.createTypeFiltersFor(includeFilterAttributes, this.environment,
					this.resourceLoader, this.registry);
			for (TypeFilter typeFilter : typeFilters) {
				scanner.addIncludeFilter(typeFilter);
			}
		}
		for (AnnotationAttributes excludeFilterAttributes : componentScan.getAnnotationArray("excludeFilters")) {
			List<TypeFilter> typeFilters = TypeFilterUtils.createTypeFiltersFor(excludeFilterAttributes, this.environment,
				this.resourceLoader, this.registry);
			for (TypeFilter typeFilter : typeFilters) {
				scanner.addExcludeFilter(typeFilter);
			}
		}

		boolean lazyInit = componentScan.getBoolean("lazyInit");
		if (lazyInit) {
			scanner.getBeanDefinitionDefaults().setLazyInit(true);
		}

		Set<String> basePackages = new LinkedHashSet<>();
		String[] basePackagesArray = componentScan.getStringArray("basePackages");
		for (String pkg : basePackagesArray) {
			String[] tokenized = StringUtils.tokenizeToStringArray(this.environment.resolvePlaceholders(pkg),
					ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS);
			Collections.addAll(basePackages, tokenized);
		}
		for (Class<?> clazz : componentScan.getClassArray("basePackageClasses")) {
			basePackages.add(ClassUtils.getPackageName(clazz));
		}
		//没有声明basePackages,则当前配置类所在的包即为根包
		if (basePackages.isEmpty()) {
			basePackages.add(ClassUtils.getPackageName(declaringClass));
		}

		scanner.addExcludeFilter(new AbstractTypeHierarchyTraversingFilter(false, false) {
			@Override
			protected boolean matchClassName(String className) {
				return declaringClass.equals(className);
			}
		});
		//执行包扫描动作
		return scanner.doScan(StringUtils.toStringArray(basePackages));
	}

2.5.2.2、loadBeanDefinitions:解析配置类中的内容

在processConfigBeanDefinitions方法中,调用玩parse方法解析完成后,会调用ConfigurationClassBeanDefinitionReader#loadBeanDefinition方法解析配置类中的内容,这里会注册所有的BeanDefinition。

image

2.5.2.2.1、loadBeanDefinitionsForConfigurationClass

之前已经解析过configClass,所以在这里会区分不同的类型,@Import,@Bean等,区分处理,构造BeanDefinition然后注册到容器中。
image

2.6 、registerBeanPostProcessors:注册BeanPostProcessor

  1. 首先从IOC容器中获取了所有实现了BeanPostProcessor的beanName
  2. 这里和之前逻辑一样,按照规则给所有后置处理器,首先注册所有实现了priorityOrdered接口的后置处理器,然后注册所有实现了Ordered接口的后置处理器,最后注册所有普通的后置处理器
	public static void registerBeanPostProcessors(
			ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
		
		//这里从bean容器中获取所有实现了BeanPostProcessor的bean的beanName
		String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);

		// Register BeanPostProcessorChecker that logs an info message when
		// a bean is created during BeanPostProcessor instantiation, i.e. when
		// a bean is not eligible for getting processed by all BeanPostProcessors.
		int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
		beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));

		// Separate between BeanPostProcessors that implement PriorityOrdered,
		// Ordered, and the rest.
		//根据排序规则,给所有的后置处理器分类
		List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
		List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
		List<String> orderedPostProcessorNames = new ArrayList<>();
		List<String> nonOrderedPostProcessorNames = new ArrayList<>();
		for (String ppName : postProcessorNames) {
			if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
				//注意此处,	priorityOrdered类型的后置处理器被提前初始化了
				BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
				priorityOrderedPostProcessors.add(pp);
				// MergedBeanDefinitionPostProcessor要额外筛出来
				if (pp instanceof MergedBeanDefinitionPostProcessor) {
					internalPostProcessors.add(pp);
				}
			} else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
				orderedPostProcessorNames.add(ppName);
			} else {
				nonOrderedPostProcessorNames.add(ppName);
			}
		}

		// First, register the BeanPostProcessors that implement PriorityOrdered.
		//首先,注册所有实现了priorityOrdered接口的后置处理器
		sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
		registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

		// Next, register the BeanPostProcessors that implement Ordered.
		//其次,注册所有实现了Ordered接口的后置处理器
		List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
		for (String ppName : orderedPostProcessorNames) {
			BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
			orderedPostProcessors.add(pp);
			if (pp instanceof MergedBeanDefinitionPostProcessor) {
				internalPostProcessors.add(pp);
			}
		}
		sortPostProcessors(orderedPostProcessors, beanFactory);
		registerBeanPostProcessors(beanFactory, orderedPostProcessors);

		// Now, register all regular BeanPostProcessors.
		//最后,注册所有普通的后置处理器
		List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
		for (String ppName : nonOrderedPostProcessorNames) {
			BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
			nonOrderedPostProcessors.add(pp);
			if (pp instanceof MergedBeanDefinitionPostProcessor) {
				internalPostProcessors.add(pp);
			}
		}
		registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);

		// Finally, re-register all internal BeanPostProcessors.
		// 1.3 注意此处,所有MergedBeanDefinitionPostProcessor又被注册了一次
		sortPostProcessors(internalPostProcessors, beanFactory);
		registerBeanPostProcessors(beanFactory, internalPostProcessors);

		// Re-register post-processor for detecting inner beans as ApplicationListeners,
		// moving it to the end of the processor chain (for picking up proxies etc).
		// 最后又注册了一个ApplicationListenerDetector
		beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
	}

2.6.1 、MergedBeanDefinitionPostProcessor

这里在上面的方法中会又单独注册了MergedBeanDefinitionPostProcessor,这个接口是运行时用于合并bean定义的后处理器回调接口,可以实现接口用于创建Bean实例的合并Bean定义,这个其中有一个很重要的实现就是AutowiredAnnotationBeanPostProcessor。

2.6.1 、AutowiredAnnotationBeanPostProcessor#postProcessMergedBeanDefinition

  1. findAutowiringMetadata:先获取注入的依赖
  2. InjectionMetadata#checkConfigMembers:再进行对象检查

image

2.6.1.1 、AutowiredAnnotationBeanPostProcessor#findAutowiringMetadata

这里首先使用双重检查锁来保证线程安全,之后会调用buildAutowiringMetadata方法构建自动装配的metadata
image

2.6.1.1.1 、AutowiredAnnotationBeanPostProcessor#buildAutowiringMetadata

在这个while循环就是一步一步往父类上爬,判断条件是是否到了Object方法,在循环体中,先是反射遍历当前类的属性,并判断上面是否有@Autowired等注解。之后有获取方法上的注解也保存进去。

image

2.6.2、ApplicationListenerDetector

registerBeanPostProcessors最后会又添加了一个后置处理器ApplicationListenerDetector,这个后置处理器就是收集所有的监听器,在他的postProcessAfterInitialization方法中,会去把监听器类型的bean注册到IOC容器中

image

2.7、initMessageSource:初始化MessageSource

这个组件是实现国际化接口的,他的默认实现是DelegatingMessageSource,他的功能:将字符串和参数数组格式化为一个国际化后的消息。

image

2.8、initApplicationEventMulticaster:初始化事件派发器

首先会判断IOC容器中是否有名称为applicationEventMulticaster的bean,如果没有就默认注册一个applicationEventMulticaster,类型是SimpleApplicationEventMulticaster。这个组件是一个事件发布器,用来做事件的发布。

image

2.8.1 SimpleApplicationEventMulticaster

这里最终会调用到ApplicationListener 的 onApplicationEvent方法,根据对应的事件匹配对应的listener。

image
image

2.9、onRefresh:子类扩展刷新(模版方法)

在springBoot中对这个方法进行了一个扩展,我们看下ServletWebServerApplicationContext#Onrefresh方法,这里发现它会创建一个WebServer也就是tomcat

image

2.9.1、createWebServer

image

2.9.1.1、getWebServerFactory:获取嵌入式Servlet容器工厂Bean

怎么一次创建只能运行在一个Servlet容器中,说明一次只能取出一个Bean中,默认的Tomcat创建工厂应该从这里取出:TomcatServletWebServerFactory,他实现了ServletWebServerFactory接口,这个ServletWebServerFactory应该是在自动配置时注册好的。

image

2.9.1.1.1、自动配置下TomcatServletWebServerFactory注册时机

这个自动配置类使用@Import导入了ServletWebServerFactoryConfiguration的三个内部类,这里会创建TomcatServletWebServerFactory。

image

image

2.9.1.2、getWebServer:创建嵌入式Servlet容器

这里其实就是创建并配置tomcat

image

2.10、registerListeners:注册监听器

  1. 这里监听器已经在IOC容器中注册好了,取出来后要放入事件广播器,以方便事件广播器广播事件
  2. 广播早期事件(在之前prepareRefresh方法中会使用earlyApplicationEventsb保存早期事件,这里是没有早期事件的,是留给开发者的,在后置处理器和监听器都被创建好,其余的单实例Bean还没有创建时,提供一个预留的时机来处理一些额外的事情)

image

2.11、finishBeanFactoryInitialization:初始化单实例Bean

这里最重要的就是在最后会调用preInstantiateSingletons方法初始化非懒加载的bean
image

2.11.1、DefaultListableBeanFactory#preInstantiateSingletons

上面会经过一系列判断后,如果不是工厂bean,则会调用getBean方法。
image

2.11.2、DefaultListableBeanFactory#preInstantiateSingletons

下面代码流程较长,下面我们逐一剖析。

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

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

    // 11.2.1 此处是解决别名 -> BeanName的映射,getBean时可以传入bean的别名,此处可以根据别名找到BeanName
    final String beanName = transformedBeanName(name);
    Object bean;

    // Eagerly check singleton cache for manually registered singletons.
    // 先尝试从之前实例化好的Bean中找有没有这个Bean,如果能找到,说明已经被实例化了,可以直接返回
    // 11.2.2 getSingleton
    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 = getObjectForBeanInstance(sharedInstance, name, beanName, null);
    }

    // 11.2.3 上面get不到bean
    else {
        // Fail if we're already creating this bean instance:
        // We're assumably within a circular reference.
        // 如果搜不到,但该Bean正在被创建,说明产生了循环引用且无法处理,只能抛出异常
        if (isPrototypeCurrentlyInCreation(beanName)) {
            throw new BeanCurrentlyInCreationException(beanName);
        }

        // Check if bean definition exists in this factory.
        // 检查这个Bean对应的BeanDefinition在IOC容器中是否存在
        BeanFactory parentBeanFactory = getParentBeanFactory();
        if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
            // Not found -> check parent.
            // 如果检查不存在,看看父容器有没有(Web环境会存在父子容器现象)
            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);
            }
        }

        // 11.2.4 走到这个地方,证明Bean确实要被创建了,标记Bean被创建
        // 该设计是防止多线程同时到这里,引发多次创建的问题
        if (!typeCheckOnly) {
            markBeanAsCreated(beanName);
        }

        try {
            // 11.2.5 合并BeanDefinition
            final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
            checkMergedBeanDefinition(mbd, beanName, args);

            // Guarantee initialization of beans that the current bean depends on.
            // 处理当前bean的bean依赖(@DependsOn注解的依赖)
            // 在创建一个Bean之前,可能这个Bean需要依赖其他的Bean。
            // 通过这个步骤,可以先递归的将这个Bean显式声明的需要的其他Bean先创建出来。
            // 通过bean标签的depends-on属性或@DependsOn注解进行显式声明。
            String[] dependsOn = mbd.getDependsOn();
            if (dependsOn != null) {
                for (String dep : dependsOn) {
                    if (isDependent(beanName, dep)) {
                        throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                                "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
                    }
                    registerDependentBean(dep, beanName);
                    getBean(dep);
                }
            }

            // Create bean instance.
            // 作用域为singleton,单实例Bean,创建
            if (mbd.isSingleton()) {
                // 11.3,7 匿名内部类执行完成后的getSingleton调用
                sharedInstance = getSingleton(beanName, () -> {
                    try {
                        // 11.4 createBean
                        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 = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
            }

            // 作用域为prototype类型
            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);
            }

            // 作用域既不是singleton,又不是prototype,那就按照实际情况来创建吧。
            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;
        }
    }

    // Check if required type matches the type of the actual bean instance.
    // 检查所需的类型是否与实际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;
}

2.11.2.1、transformedBeanName:别名-BeanName的映射

这里就是那aliasMap去一个个的取,找别名映射的BeanName,找不到就返回原始名
image
image

2.11.2.2、getSingleton:尝试获取单实例Bean(解决循环依赖)

这里就是首先尝试通过beanName从IOC容器中获取对应的bean,如果不存在才会走后续的实例化过程,这个流程是为了解决循环依赖,这个后续会做详细剖析,这里就不过多讲解了。

image

2.11.2.3、创建前的检查

这里有个检查循环依赖的方法:isPrototypeCurrentlyInCreation,这个方法是创建原型Bean时会校验的,如果当前线程中在创建一个scope=prototype的Bean,并且当前要创建的Bean跟这个线程中创建的Bean的name一致,则会认为出现了多实例Bean的循环依赖,会引发异常。

image

2.11.2.4、标记准备创建的Bean

这里标记的过程:IOC容器会把所有创建过的Bean的name都缓存起来,这样下次会判断是否是重复创建。
image
image

2.11.2.5、合并BeanDefinition,处理显式依赖

这部分会解析@DependsOn注解标注声明的Bean,并预先的构建它,被依赖的Bean也是通过getBean方法来创建,思路一致。

image

2.11.2.6、准备创建Bean

这里会调用createBean创建单实例Bean,这里createBean方法是通过getSingleton方法传入匿名内部类,调用的createBean方法。
image

2.11.2.6.1、getSingleton

这里就是判断如果当前准备创建的Bean还没有在IOC容重,就标记一下它,把当前准备创建的beanName放入singletonsCurrentlyInCreation中,他的作用是解决循环依赖,这个后续会说。然后会调用singletonFactory.getObject()方法,这个会调用到createBean。

image

2.11.2.6.2、createBean

这里面有两个重要的部分,AOP的入口和真正创建Bean的入口。
image

2.11.2.6.2.1、resolveBeforeInstantiation:AOP

这里会回调InstantiationAwareBeanPostProcessor的postProcessBeforeInstantiation方法,这个接口对应的部分是真正的AOP创建代理对象的部分,后面会详细分析AOP的流程。

image

2.11.2.6.2.2、doCreateBean
  1. createBeanInstance:创建Bean对象
  2. addSingletonFactory:Bean放入缓存(涉及循环依赖)
  3. populateBean:属性复制和自动注入
  4. initializeBean:初始化后处理
	protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
			throws BeanCreationException {

		// Instantiate the bean.
		BeanWrapper instanceWrapper = null;
		//处理FactoryBean的小细节问题
		if (mbd.isSingleton()) {
			//看下这个方法是干嘛的
			//观察 factoryBeanInstanceCache 的使用位置,唯一可以找到的 put 方法调用是在 AbstractAutowireCapableBeanFactory 的 getSingletonFactoryBeanForTypeCheck 方法
			//且不管这个操作是干什么用,借助 IDEA 继续向上找 getSingletonFactoryBeanForTypeCheck 方法的调用,可以发现进入到 getTypeForFactoryBean 中了。不需要深挖这个方法是干嘛用,
			// 且看方法名,就可以知道,它可以获取到 FactoryBean 中生成的 bean 的类型!
			// 可是你获取就获取呗,直接取泛型不好吗?为啥不行?
			//
			//因为。。。泛型可以写抽象类或者接口呀。如果真的这么写,回头框架拿泛型的时候,只能取到接口级别,但具体的实现类可拿不到呀。所以,FactoryBean 中还设计了一个方法:
			// getObjectType ,它可以编程式的返回最终创建出来的对象的类型。不过想要调用 getObjectType 方法,就需要先把 FactoryBean 创建出来。这里面就产生新的问题了:
			// 一旦 FactoryBean 被预先创建出来了,而且这个 FactoryBean 还是单实例的 bean ,那原则上讲就不能再创建第二次了。
			//
			//基于这个原则,SpringFramework 给出的解决方案是:如果提前调用了 getTypeForFactoryBean 确认 FactoryBean 中生成的 bean 的类型,则它会把这个 FactoryBean 本身先存在一个
			// factoryBeanInstanceCache 中(注意此时的 FactoryBean 只会利用 getObjectType 方法,不会调用 getObject 创建 bean );等后续真的需要由 FactoryBean 生成 bean 的时候,
			// 它会直接从 factoryBeanInstanceCache 中取出刚才已经实例化的 FactoryBean ,继续执行 bean 的初始化动作(属性赋值、依赖注入等)
			instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
		}
		if (instanceWrapper == null) {
			//真正的bean对象创建
			instanceWrapper = createBeanInstance(beanName, mbd, args);
		}
		//得到真实的bean对象引用
		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;
			}
		}

		// Eagerly cache singletons to be able to resolve circular references
		// even when triggered by lifecycle interfaces like BeanFactoryAware.

		//earlySingletonExposure的判断 & addSingletonFactory
		//这个判断非常关键,它要同时成立三个条件才能进if结构:
		//这个Bean是一个单实例Bean
		//IOC容器允许循环依赖(默认是true)
		//正在创建的单实例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));
		}

		// Initialize the bean instance.
		Object exposedObject = bean;
		try {
			//注入属性
			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;
				} 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.");
					}
				}
			}
		}

		// Register bean as disposable.
		//这里是注册销毁时的回调
		//如果一个 bean 定义的 class 有实现 DisposableBean 接口,或者声明了
		// @PreDestroy 注解,或者声明了 destroy-method 方法,则会在 doCreateBean 方法的最后一步,注册一个销毁 bean 的回调钩子:
		try {
			registerDisposableBeanIfNecessary(beanName, bean, mbd);
		} catch (BeanDefinitionValidationException ex) {
			throw new BeanCreationException(
					mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
		}

		return exposedObject;
	}


2.11.2.6.2.3、createBeanInstance:真正实例化

这个方法流程比较长,我们下面分流程剖析。

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

		//bean无法被访问,则抛出异常
		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());
		}
		//spring5的新特性
		Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
		if (instanceSupplier != null) {
			return obtainFromSupplier(instanceSupplier, beanName);
		}

		//工厂方法创建
		if (mbd.getFactoryMethodName() != null) {
			return instantiateUsingFactoryMethod(beanName, mbd, args);
		}

		// Shortcut when re-creating the same bean...
		//这一步是为原型bean的一个小优化
		//这部分为什么说它是一个优化呢?注意看后半部分:if (resolved) ,这个判断如果成立,会立即执行注入 / 实例化 bean 的动作(尽管下面还有一些代码没有执行)。
		// 那这个部分的设计缘由是什么呢?来我们考虑一个小小的问题:原型 bean 的创建过程中,每次的执行流程都是一样一样的吧!既然是每次都一样,那这些准备动作就没必要每次都执行一遍吧!
		// 执行一次之后,把这个过程中一些需要的东西都缓存起来就 OK 吧!所以,这个逻辑中,会把 bean 中需要的一些信息都保存起来,以备后续再创建该 bean 时可以直接拿这些信息,去创建 bean 对象。
		boolean resolved = false;
		boolean autowireNecessary = false;
		//这部分缓存的数据主要是解析好的构造器,以及工厂方法。
		if (args == null) {
			synchronized (mbd.constructorArgumentLock) {
				if (mbd.resolvedConstructorOrFactoryMethod != null) {
					resolved = true;
					autowireNecessary = mbd.constructorArgumentsResolved;
				}
			}
		}
		if (resolved) {
			if (autowireNecessary) {
				return autowireConstructor(beanName, mbd, null, null);
			} else {
				return instantiateBean(beanName, mbd);
			}
		}

		// Candidate constructors for autowiring?
		//  // 1. 通过SmartInstantiationAwareBeanPostProcessor找到了构造器
		//    // 2. 配置了注入方式是AUTOWIRE_CONSTRUCTOR
		//    // 3. 定义bean的时候指定了constructor-arg
		//    // 4. 构造bean时传入了args参数
		Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
		if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
				mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
			return autowireConstructor(beanName, mbd, ctors, args);
		}

		// Preferred constructors for default construction?
		ctors = mbd.getPreferredConstructors();
		if (ctors != null) {
			return autowireConstructor(beanName, mbd, ctors, null);
		}

		// No special handling: simply use no-arg constructor.
		//实例话bean
		return instantiateBean(beanName, mbd);
	}

2.11.2.6.2.2.3.1、getInstanceSupplier:特殊的callback回调方法

这两个方法来自AbstractBeanDefinition。

public void setInstanceSupplier(@Nullable Supplier<?> instanceSupplier) {
    this.instanceSupplier = instanceSupplier;
}

@Nullable
public Supplier<?> getInstanceSupplier() {
    return this.instanceSupplier;
}

它只是简单地get和set而已,那它这个 Supplier 又是从哪里来的呢?借助IDEA,发现在 GenericApplicationContext 中有一个调用,发现调用它的地方一般这个Supplier通常是null。

	public final <T> void registerBean(
			Class<T> beanClass, Supplier<T> supplier, BeanDefinitionCustomizer... customizers) {

		registerBean(null, beanClass, supplier, customizers);
	}

2.11.2.6.2.2.3.2、instantiateUsingFactoryMethod:工厂方法

这里在之前的refresh方法中会执行invokeBeanFactoryPostProcessors,在执行BeanFactory时回调一组BeanDefinitionRegistryPostProcessor,他执行了一个很关键的后置处理器ConfigurationClassPostProcessor,在这个后置处理器中处理了@Bean注解标注的方法的解析过程,这里面就有一个工厂方法的设置,这里instantiateUsingFactoryMethod方法就是对这种被@Bean注解标注的Bean进行创建。

image

这里instantiateUsingFactoryMethod方法特别长,但大体上就干了一件事:确定工厂方法+实例化、包装BeanWrapper

	public BeanWrapper instantiateUsingFactoryMethod(
			String beanName, RootBeanDefinition mbd, @Nullable Object[] explicitArgs) {

		//构造BeanWrapper
		BeanWrapperImpl bw = new BeanWrapperImpl();
		this.beanFactory.initBeanWrapper(bw);

		Object factoryBean;
		Class<?> factoryClass;
		boolean isStatic;

		//获取工厂方法名称
		String factoryBeanName = mbd.getFactoryBeanName();
		if (factoryBeanName != null) {
			if (factoryBeanName.equals(beanName)) {
				throw new BeanDefinitionStoreException(mbd.getResourceDescription(), beanName,
						"factory-bean reference points back to the same bean definition");
			}
			//如果工厂方法不为空,则获取工厂实例,并标注该工厂方法不是静态方法
			factoryBean = this.beanFactory.getBean(factoryBeanName);
			if (mbd.isSingleton() && this.beanFactory.containsSingleton(beanName)) {
				throw new ImplicitlyAppearedSingletonException();
			}
			this.beanFactory.registerDependentBean(factoryBeanName, beanName);
			factoryClass = factoryBean.getClass();
			isStatic = false;
		}
		else {
			// It's a static factory method on the bean class.
			//如果获取不到工厂方法名,则这应该是一个静态工厂,需要提供完整的工厂权限定类名,否则会抛出异常。
			if (!mbd.hasBeanClass()) {
				throw new BeanDefinitionStoreException(mbd.getResourceDescription(), beanName,
						"bean definition declares neither a bean class nor a factory-bean reference");
			}
			factoryBean = null;
			factoryClass = mbd.getBeanClass();
			isStatic = true;
		}

		Method factoryMethodToUse = null;
		ArgumentsHolder argsHolderToUse = null;
		Object[] argsToUse = null;

		//这个explicitArgs是从这个方法的参数重传过来的,它是从getBean方法中传过来的。
		// 默认情况下getBean只有BeanName(AbstractBeanFactory的getBean(String name)方法),故这里为null
		if (explicitArgs != null) {
			argsToUse = explicitArgs;
		}
		else {
			Object[] argsToResolve = null;
			synchronized (mbd.constructorArgumentLock) {
				factoryMethodToUse = (Method) mbd.resolvedConstructorOrFactoryMethod;
				if (factoryMethodToUse != null && mbd.constructorArgumentsResolved) {
					// Found a cached factory method...
					argsToUse = mbd.resolvedConstructorArguments;
					if (argsToUse == null) {
						argsToResolve = mbd.preparedConstructorArguments;
					}
				}
			}
			if (argsToResolve != null) {
				argsToUse = resolvePreparedArguments(beanName, mbd, bw, factoryMethodToUse, argsToResolve);
			}
		}

		//上面的东西统统没有,进入下面的结构体中
		if (factoryMethodToUse == null || argsToUse == null) {
			// Need to determine the factory method...
			// Try all methods with this name to see if they match the given arguments.
			factoryClass = ClassUtils.getUserClass(factoryClass);

			List<Method> candidates = null;
			if (mbd.isFactoryMethodUnique) {
				if (factoryMethodToUse == null) {
					factoryMethodToUse = mbd.getResolvedFactoryMethod();
				}
				if (factoryMethodToUse != null) {
					candidates = Collections.singletonList(factoryMethodToUse);
				}
			}
			if (candidates == null) {
				candidates = new ArrayList<>();
				//获取配置类中所有的方法(包括父类),成为候选方法
				Method[] rawCandidates = getCandidateMethods(factoryClass, mbd);
				for (Method candidate : rawCandidates) {
					if (Modifier.isStatic(candidate.getModifiers()) == isStatic && mbd.isFactoryMethod(candidate)) {
						candidates.add(candidate);
					}
				}
			}

			//因为@Bean只对当前要创建的Bean标注了一次,所以这里candidateList的大小必为1
			if (candidates.size() == 1 && explicitArgs == null && !mbd.hasConstructorArgumentValues()) {
				Method uniqueCandidate = candidates.get(0);
				if (uniqueCandidate.getParameterCount() == 0) {
					mbd.factoryMethodToIntrospect = uniqueCandidate;
					synchronized (mbd.constructorArgumentLock) {
						mbd.resolvedConstructorOrFactoryMethod = uniqueCandidate;
						mbd.constructorArgumentsResolved = true;
						mbd.resolvedConstructorArguments = EMPTY_ARGS;
					}
					bw.setBeanInstance(instantiate(beanName, mbd, factoryBean, uniqueCandidate, EMPTY_ARGS));
					return bw;
				}
			}

			if (candidates.size() > 1) {  // explicitly skip immutable singletonList
				candidates.sort(AutowireUtils.EXECUTABLE_COMPARATOR);
			}

			ConstructorArgumentValues resolvedValues = null;
			boolean autowiring = (mbd.getResolvedAutowireMode() == AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR);
			int minTypeDiffWeight = Integer.MAX_VALUE;
			Set<Method> ambiguousFactoryMethods = null;

			int minNrOfArgs;
			if (explicitArgs != null) {
				minNrOfArgs = explicitArgs.length;
			}
			else {
				// We don't have arguments passed in programmatically, so we need to resolve the
				// arguments specified in the constructor arguments held in the bean definition.
				//没有以编程方法在getBean方法中传递参数,因此需要解析在Bean定义中保存的构造函数参数中指定的参数
				if (mbd.hasConstructorArgumentValues()) {
					ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues();
					resolvedValues = new ConstructorArgumentValues();
					minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);
				}
				else {
					minNrOfArgs = 0;
				}
			}

			Deque<UnsatisfiedDependencyException> causes = null;

			for (Method candidate : candidates) {
				int parameterCount = candidate.getParameterCount();

				if (parameterCount >= minNrOfArgs) {
					ArgumentsHolder argsHolder;
					//解析被@Bean标注的方法的参数
					Class<?>[] paramTypes = candidate.getParameterTypes();
					if (explicitArgs != null) {
						// Explicit arguments given -> arguments length must match exactly.
						if (paramTypes.length != explicitArgs.length) {
							continue;
						}
						argsHolder = new ArgumentsHolder(explicitArgs);
					}
					//getBean中没有传入参数,这里需要解析构造方法中的参数
					else {
						// Resolved constructor arguments: type conversion and/or autowiring necessary.
						//解决的构造函数参数:类型转换,自动装配是必需的。
						try {
							String[] paramNames = null;
							ParameterNameDiscoverer pnd = this.beanFactory.getParameterNameDiscoverer();
							if (pnd != null) {
								paramNames = pnd.getParameterNames(candidate);
							}
							//在已经解析的构造函数参数值的情况下,创建一个参数持有者对象
							argsHolder = createArgumentArray(beanName, mbd, resolvedValues, bw,
									paramTypes, paramNames, candidate, autowiring, candidates.size() == 1);
						}
						catch (UnsatisfiedDependencyException ex) {
							if (logger.isTraceEnabled()) {
								logger.trace("Ignoring factory method [" + candidate + "] of bean '" + beanName + "': " + ex);
							}
							// Swallow and try next overloaded factory method.
							if (causes == null) {
								causes = new ArrayDeque<>(1);
							}
							causes.add(ex);
							continue;
						}
					}

					//解析构造方法的参数时使用严格模式还是宽松模式
					int typeDiffWeight = (mbd.isLenientConstructorResolution() ?
							argsHolder.getTypeDifferenceWeight(paramTypes) : argsHolder.getAssignabilityWeight(paramTypes));
					// Choose this factory method if it represents the closest match.
					if (typeDiffWeight < minTypeDiffWeight) {
						factoryMethodToUse = candidate;
						argsHolderToUse = argsHolder;
						argsToUse = argsHolder.arguments;
						minTypeDiffWeight = typeDiffWeight;
						ambiguousFactoryMethods = null;
					}
					// Find out about ambiguity: In case of the same type difference weight
					// for methods with the same number of parameters, collect such candidates
					// and eventually raise an ambiguity exception.
					// However, only perform that check in non-lenient constructor resolution mode,
					// and explicitly ignore overridden methods (with the same parameter signature).
					else if (factoryMethodToUse != null && typeDiffWeight == minTypeDiffWeight &&
							!mbd.isLenientConstructorResolution() &&
							paramTypes.length == factoryMethodToUse.getParameterCount() &&
							!Arrays.equals(paramTypes, factoryMethodToUse.getParameterTypes())) {
						if (ambiguousFactoryMethods == null) {
							ambiguousFactoryMethods = new LinkedHashSet<>();
							ambiguousFactoryMethods.add(factoryMethodToUse);
						}
						ambiguousFactoryMethods.add(candidate);
					}
				}
			}

			//如果发现没有可执行的工厂方法,进行一系列检查后可能会抛出异常
			if (factoryMethodToUse == null || argsToUse == null) {
				if (causes != null) {
					UnsatisfiedDependencyException ex = causes.removeLast();
					for (Exception cause : causes) {
						this.beanFactory.onSuppressedException(cause);
					}
					throw ex;
				}
				List<String> argTypes = new ArrayList<>(minNrOfArgs);
				if (explicitArgs != null) {
					for (Object arg : explicitArgs) {
						argTypes.add(arg != null ? arg.getClass().getSimpleName() : "null");
					}
				}
				else if (resolvedValues != null) {
					Set<ValueHolder> valueHolders = new LinkedHashSet<>(resolvedValues.getArgumentCount());
					valueHolders.addAll(resolvedValues.getIndexedArgumentValues().values());
					valueHolders.addAll(resolvedValues.getGenericArgumentValues());
					for (ValueHolder value : valueHolders) {
						String argType = (value.getType() != null ? ClassUtils.getShortName(value.getType()) :
								(value.getValue() != null ? value.getValue().getClass().getSimpleName() : "null"));
						argTypes.add(argType);
					}
				}
				String argDesc = StringUtils.collectionToCommaDelimitedString(argTypes);
				throw new BeanCreationException(mbd.getResourceDescription(), beanName,
						"No matching factory method found on class [" + factoryClass.getName() + "]: " +
						(mbd.getFactoryBeanName() != null ?
							"factory bean '" + mbd.getFactoryBeanName() + "'; " : "") +
						"factory method '" + mbd.getFactoryMethodName() + "(" + argDesc + ")'. " +
						"Check that a method with the specified name " +
						(minNrOfArgs > 0 ? "and arguments " : "") +
						"exists and that it is " +
						(isStatic ? "static" : "non-static") + ".");
			}
			else if (void.class == factoryMethodToUse.getReturnType()) {
				throw new BeanCreationException(mbd.getResourceDescription(), beanName,
						"Invalid factory method '" + mbd.getFactoryMethodName() + "' on class [" +
						factoryClass.getName() + "]: needs to have a non-void return type!");
			}
			else if (ambiguousFactoryMethods != null) {
				throw new BeanCreationException(mbd.getResourceDescription(), beanName,
						"Ambiguous factory method matches found on class [" + factoryClass.getName() + "] " +
						"(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities): " +
						ambiguousFactoryMethods);
			}

			if (explicitArgs == null && argsHolderToUse != null) {
				mbd.factoryMethodToIntrospect = factoryMethodToUse;
				argsHolderToUse.storeCache(mbd, factoryMethodToUse);
			}
		}
        //实例化Bean,包装BeanWrapper
		bw.setBeanInstance(instantiate(beanName, mbd, factoryBean, factoryMethodToUse, argsToUse));
		return bw;
	}

这里在上面提到了严格模式/宽松模式,默认情况下 lenientConstructorResolution 的值为true, 为严格模式。下面先看一眼这两种模式下的计算规则:

  1. 严格模式下,必须要求参数类型完全一致这个方法的实现涉及到算法,不作细致研究
  2. 宽松模式,只要参数是声明类型或子类型即可
    如果使用宽松模式,会出现一个问题:如果构造方法中传入两个接口,而这两个接口分别有两个实现类,此时IOC容器会觉得这两个对象都可以放到这两个参数中,造成权重一致,出现构造方法歧义。
// 严格模式
public int getTypeDifferenceWeight(Class<?>[] paramTypes) {
    // If valid arguments found, determine type difference weight.
    // Try type difference weight on both the converted arguments and
    // the raw arguments. If the raw weight is better, use it.
    // Decrease raw weight by 1024 to prefer it over equal converted weight.
    // 如果找到有效的参数,请确定类型差异权重。尝试对转换后的参数和原始参数都使用类型差异权重。
    // 如果原始权重更好,请使用它。将原始权重减少1024,以使其优于相等的转换权重。
    
    // 先拿转换之后的参数对比
    int typeDiffWeight = MethodInvoker.getTypeDifferenceWeight(paramTypes, this.arguments);
    // 再拿原始参数对比
    int rawTypeDiffWeight = MethodInvoker.getTypeDifferenceWeight(paramTypes, this.rawArguments) - 1024;
    // 由值确定选哪一个,值越小越接近参数声明类型
    return (rawTypeDiffWeight < typeDiffWeight ? rawTypeDiffWeight : typeDiffWeight);
}

// 宽松模式
public int getAssignabilityWeight(Class<?>[] paramTypes) {
    for (int i = 0; i < paramTypes.length; i++) {
        if (!ClassUtils.isAssignableValue(paramTypes[i], this.arguments[i])) {
            return Integer.MAX_VALUE;
        }
    }
    for (int i = 0; i < paramTypes.length; i++) {
        if (!ClassUtils.isAssignableValue(paramTypes[i], this.rawArguments[i])) {
            return Integer.MAX_VALUE - 512;
        }
    }
    return Integer.MAX_VALUE - 1024;
}

2.11.2.6.2.4、populateBean:属性赋值和自动注入

  1. 这里首先会回调InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation,可以让我们自定义属性的注入,可以控制不进行自动属性赋值和注入。
  2. 回调InstantiationAwareBeanPostProcessor#postProcessProperties,这里其中就包含一个后置处理器,他可以实现@Autowrited、@Value等自动注入。
  3. 如果是通过setter方式进行自动注入,会走最后一个if结构,调用applyPropertyValues方法。
	protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
		if (bw == null) {
			if (mbd.hasPropertyValues()) {
				throw new BeanCreationException(
						mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
			} else {
				// Skip property population phase for null instance.
				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.
		//这里会回调InstantiationAwareBeanPostProcessor
		//在设置属性之前,让任何 InstantiationAwareBeanPostProcessor 都有机会修改 bean 的状态,例如支持属性字段的注入。
		//postProcessAfterInstantiation 方法返回的是 boolean 类型,当 postProcessAfterInstantiation 返回 false 时,
		// 会直接 return 出去,不再执行下面的属性赋值 + 组件依赖注入的逻辑!(通常这个方法一定是返回 true 的,底层默认也是返回 true )
		if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
			for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
				if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
					return;
				}
			}
		}

		PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);

		//解析出当前bean支持的自动注入模式,判断是byName还是byType
		int resolvedAutowireMode = mbd.getResolvedAutowireMode();
		if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
			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;
		}

		boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
		boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);

		if (hasInstAwareBpps) {
			if (pvs == null) {
				pvs = mbd.getPropertyValues();
			}
			//在这里又回调了postProcessProperties方法
			//注意 postProcessProperties 方法会传入 PropertyValues ,也会返回 PropertyValues ,所以这个过程相当于反复给 PropertyValues 封装数据。
			//这个时机的回调是属性赋值和组件依赖注入的核心时机,所以我们需要关注这里面一个非常重要的后置处理器:AutowiredAnnotationBeanPostProcessor 。
			for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
				PropertyValues pvsToUse = bp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
				if (pvsToUse == null) {
					return;
				}
				pvs = pvsToUse;
			}
		}
		if (needsDepCheck) {
			PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
			checkDependencies(beanName, mbd, filteredPds, pvs);
		}

		if (pvs != null) {
			//将PropertyValues应用给bean
			applyPropertyValues(beanName, mbd, bw, pvs);
		}
	}

2.11.2.6.2.4.1、AutowiredAnnotationBeanPostProcessor:@Autowired的自动注入

它集成了 InstantiationAwareBeanPostProcessorAdapter ,而 InstantiationAwareBeanPostProcessorAdapter 又实现了 SmartInstantiationAwareBeanPostProcessor 接口,SmartInstantiationAwareBeanPostProcessor 接口最终继承了 InstantiationAwareBeanPostProcessor 接口。那上面看到的核心回调方法就是 postProcessProperties :
这里findAutowiringMetadata我们之前已经剖析过了,它会构建自动注入的元数据,下面的inject方法是真正的自动注入。
image

这里面最底下调用了element.inject方法,两个子类重写了这个方法,分别是 AutowiredFieldElement 和 AutowiredMethodElement 。很明显它们是给属性注入和方法注入的,我们以属性注入为例分析
image

  1. 这里首先判断这个值有没有在之前的注入中缓存过,如果缓存中存在,直接取缓存
  2. 如果没有缓存,会调用resolveFieldValue找出对应需要注入的值
  3. 解析出对应的值,那么通过反射注入到属性中

image

  1. 首先调用resolveDependency方法找出依赖值
  2. 然后加入缓存中

image

上面的一些判断都是校验被标注@Autowired注解的属性类型,一般都不会用到,会进入最后一个else结构,它调用doResolveDependency方法来解决依赖。

image

这里就是根据判断需要注入的类型,其中包括数组,map等复杂类型,从已经创建好的bean中找匹配上的bean。

	public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName,
			@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {

		InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor);
		try {
			//该方法默认是调用DependencyDescriptor的方法,没有子类,默认实现是返回null
			Object shortcut = descriptor.resolveShortcut(this);
			if (shortcut != null) {
				return shortcut;
			}

			Class<?> type = descriptor.getDependencyType();
			//处理@Value注解
			Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);
			if (value != null) {
				if (value instanceof String) {
					String strVal = resolveEmbeddedValue((String) value);
					BeanDefinition bd = (beanName != null && containsBean(beanName) ?
							getMergedBeanDefinition(beanName) : null);
					value = evaluateBeanDefinitionString(strVal, bd);
				}
				TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
				try {
					return converter.convertIfNecessary(value, type, descriptor.getTypeDescriptor());
				}
				catch (UnsupportedOperationException ex) {
					// A custom TypeConverter which does not support TypeDescriptor resolution...
					return (descriptor.getField() != null ?
							converter.convertIfNecessary(value, type, descriptor.getField()) :
							converter.convertIfNecessary(value, type, descriptor.getMethodParameter()));
				}
			}

			//处理数组,集合,Map等
			Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
			if (multipleBeans != null) {
				return multipleBeans;
			}

			//从现有的已经创建好的Bean实例中找可以匹配到该自动注入的字段上的Bean
			Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
			if (matchingBeans.isEmpty()) {
				if (isRequired(descriptor)) {
					raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
				}
				return null;
			}

			String autowiredBeanName;
			Object instanceCandidate;

			//如果找到了,超过1个,会决定使用哪个Bean更合适,如果真的分辨不出来,则会抛出异常
			if (matchingBeans.size() > 1) {
				autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);
				if (autowiredBeanName == null) {
					if (isRequired(descriptor) || !indicatesMultipleBeans(type)) {
						return descriptor.resolveNotUnique(descriptor.getResolvableType(), matchingBeans);
					}
					else {
						// In case of an optional Collection/Map, silently ignore a non-unique case:
						// possibly it was meant to be an empty collection of multiple regular beans
						// (before 4.3 in particular when we didn't even look for collection beans).
						return null;
					}
				}
				instanceCandidate = matchingBeans.get(autowiredBeanName);
			}
			else {
				// We have exactly one match.
				//匹配不到,要走下面的流程
				Map.Entry<String, Object> entry = matchingBeans.entrySet().iterator().next();
				autowiredBeanName = entry.getKey();
				instanceCandidate = entry.getValue();
			}

			if (autowiredBeanNames != null) {
				autowiredBeanNames.add(autowiredBeanName);
			}
			//关联创建
			if (instanceCandidate instanceof Class) {
				instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this);
			}
			Object result = instanceCandidate;
			if (result instanceof NullBean) {
				if (isRequired(descriptor)) {
					raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
				}
				result = null;
			}
			if (!ClassUtils.isAssignableValue(type, result)) {
				throw new BeanNotOfRequiredTypeException(autowiredBeanName, type, instanceCandidate.getClass());
			}
			return result;
		}
		finally {
			ConstructorResolver.setCurrentInjectionPoint(previousInjectionPoint);
		}
	}

2.11.2.6.2.4.2、applyPropertyValues(setter方法的自动注入)

这里会调用一个核心方法:valueResolver.resolveValueIfNecessary,解析出Bean依赖的属性值

	protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
		//如果没有要应用的bean属性直接返回即可
		if (pvs.isEmpty()) {
			return;
		}

		MutablePropertyValues mpvs = null;
		List<PropertyValue> original;

		if (pvs instanceof MutablePropertyValues) {
			mpvs = (MutablePropertyValues) pvs;
			//判断PropertyValues是否已经解析过了,如果已经解析过了直接应用即可,不需要重复解析
			if (mpvs.isConverted()) {
				// Shortcut: use the pre-converted values as-is.
				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());
		}

		//初始化BeanDefinitionValueResolver
		//BeanDefinitionValueResolver 的初始化需要传入一个 TypeConverter ,而这个 TypeConverter 是 SpringFramework 中内部用于类型转换的核心 API 。简单的来说,
		// 使用 TypeConverter可以将一个 String 类型的数据,转换为特定的所需要的类型的数据。而 BeanDefinitionValueResolver 就利用 TypeConverter ,完成对 bean
		// 实例中需要注入的属性值进行解析,并适配为 bean 属性所需要的类型(如 String → int ,依赖 bean 的名称转为实际 bean 的引用)。
		TypeConverter converter = getCustomTypeConverter();
		if (converter == null) {
			converter = bw;
		}
		BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter);

		// Create a deep copy, resolving any references for values.
		List<PropertyValue> deepCopy = new ArrayList<>(original.size());
		boolean resolveNecessary = false;
		//迭代逐个解析PropertyVlaue
		for (PropertyValue pv : original) {
			//已经解析过的直接添加
			if (pv.isConverted()) {
				deepCopy.add(pv);
			} else {
				String propertyName = pv.getName();
				//此处取出的值是未经过转换的原始value
				Object originalValue = pv.getValue();
				// // 此处是 5.2 的一个扩展,如果编程式使用BeanDefinitionBuilder添加自动注入的属性时,
				//            // 会使用类似于自动注入支持的方式处理该属性
				if (originalValue == AutowiredPropertyMarker.INSTANCE) {
					Method writeMethod = bw.getPropertyDescriptor(propertyName).getWriteMethod();
					if (writeMethod == null) {
						throw new IllegalArgumentException("Autowire marker for property without write method: " + pv);
					}
					originalValue = new DependencyDescriptor(new MethodParameter(writeMethod, 0), true);
				}
				//   // 根据originalValue的类型,解析出bean依赖的属性值
				//            // 此处如果是bean的名称,则最终解析出来的是真正的bean对象
				Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);
				Object convertedValue = resolvedValue;
				boolean convertible = bw.isWritableProperty(propertyName) &&
						!PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName);
				if (convertible) {
					convertedValue = convertForProperty(resolvedValue, propertyName, bw, converter);
				}
				// Possibly store converted value in merged bean definition,
				// in order to avoid re-conversion for every created bean instance.
				//此处要对解析前和解析后的数据进行对比
				// 如果解析之前与解析之后的值完全一致,则代表不需要解析,或已经解析过了,直接保存
				if (resolvedValue == originalValue) {
					if (convertible) {
						pv.setConvertedValue(convertedValue);
					}
					deepCopy.add(pv);
					// 如果String类型转为其他类型(除了集合或数组),则认为它也不需要再解析了
				} 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));
				}
			}
		}
		// 如果所有字段都解析完毕,则当前PropertyValues可以标记为已经解析完成,后续不需要重复解析
		if (mpvs != null && !resolveNecessary) {
			mpvs.setConverted();
		}

		// Set our (possibly massaged) deep copy.
		try {
			//PropertyVlaues应用到bean
			bw.setPropertyValues(new MutablePropertyValues(deepCopy));
		} catch (BeansException ex) {
			throw new BeanCreationException(
					mbd.getResourceDescription(), beanName, "Error setting property values", ex);
		}
	}

这里就是根据依赖的类型来解析出对应的依赖的属性值

	public Object resolveValueIfNecessary(Object argName, @Nullable Object value) {
		// We must check each value to see whether it requires a runtime reference
		// to another bean to be resolved.
		//如果依赖了另外一个Bean时,进入下面的分支
		if (value instanceof RuntimeBeanReference ref) {
			return resolveReference(argName, ref);
		}
		//如果根据另一个Bean的name进行依赖,进入下面的分支
		else if (value instanceof RuntimeBeanNameReference ref) {
			String refName = ref.getBeanName();
			refName = String.valueOf(doEvaluate(refName));
			if (!this.beanFactory.containsBean(refName)) {
				throw new BeanDefinitionStoreException(
						"Invalid bean name '" + refName + "' in bean reference for " + argName);
			}
			return refName;
		}
		//解析BeanDefinitionHolder
		else if (value instanceof BeanDefinitionHolder bdHolder) {
			// Resolve BeanDefinitionHolder: contains BeanDefinition with name and aliases.
			return resolveInnerBean(argName, bdHolder.getBeanName(), bdHolder.getBeanDefinition());
		}
		//解析纯BeanDefinition
		else if (value instanceof BeanDefinition bd) {
			// Resolve plain BeanDefinition, without contained name: use dummy name.
			String innerBeanName = "(inner bean)" + BeanFactoryUtils.GENERATED_BEAN_NAME_SEPARATOR +
					ObjectUtils.getIdentityHexString(bd);
			return resolveInnerBean(argName, innerBeanName, bd);
		}
		//解析DependencyDescriptor
		else if (value instanceof DependencyDescriptor dependencyDescriptor) {
			Set<String> autowiredBeanNames = new LinkedHashSet<>(4);
			Object result = this.beanFactory.resolveDependency(
					dependencyDescriptor, this.beanName, autowiredBeanNames, this.typeConverter);
			for (String autowiredBeanName : autowiredBeanNames) {
				if (this.beanFactory.containsBean(autowiredBeanName)) {
					this.beanFactory.registerDependentBean(autowiredBeanName, this.beanName);
				}
			}
			return result;
		}
		//解析数组
		else if (value instanceof ManagedArray managedArray) {
			// May need to resolve contained runtime references.
			Class<?> elementType = managedArray.resolvedElementType;
			if (elementType == null) {
				String elementTypeName = managedArray.getElementTypeName();
				if (StringUtils.hasText(elementTypeName)) {
					try {
						elementType = ClassUtils.forName(elementTypeName, this.beanFactory.getBeanClassLoader());
						managedArray.resolvedElementType = elementType;
					}
					catch (Throwable ex) {
						// Improve the message by showing the context.
						throw new BeanCreationException(
								this.beanDefinition.getResourceDescription(), this.beanName,
								"Error resolving array type for " + argName, ex);
					}
				}
				else {
					elementType = Object.class;
				}
			}
			return resolveManagedArray(argName, (List<?>) value, elementType);
		}
		//解析List
		else if (value instanceof ManagedList<?> managedList) {
			// May need to resolve contained runtime references.
			return resolveManagedList(argName, managedList);
		}
		//解析Set
		else if (value instanceof ManagedSet<?> managedSet) {
			// May need to resolve contained runtime references.
			return resolveManagedSet(argName, managedSet);
		}
		//解析Map
		else if (value instanceof ManagedMap<?, ?> managedMap) {
			// May need to resolve contained runtime references.
			return resolveManagedMap(argName, managedMap);
		}
		//解析Properties
		else if (value instanceof ManagedProperties original) {
			// Properties original = managedProperties;
			Properties copy = new Properties();
			original.forEach((propKey, propValue) -> {
				if (propKey instanceof TypedStringValue typedStringValue) {
					propKey = evaluate(typedStringValue);
				}
				if (propValue instanceof TypedStringValue typedStringValue) {
					propValue = evaluate(typedStringValue);
				}
				if (propKey == null || propValue == null) {
					throw new BeanCreationException(
							this.beanDefinition.getResourceDescription(), this.beanName,
							"Error converting Properties key/value pair for " + argName + ": resolved to null");
				}
				copy.put(propKey, propValue);
			});
			return copy;
		}
		//解析String
		else if (value instanceof TypedStringValue typedStringValue) {
			// Convert value to target type here.
			Object valueObject = evaluate(typedStringValue);
			try {
				Class<?> resolvedTargetType = resolveTargetType(typedStringValue);
				if (resolvedTargetType != null) {
					return this.typeConverter.convertIfNecessary(valueObject, resolvedTargetType);
				}
				else {
					return valueObject;
				}
			}
			catch (Throwable ex) {
				// Improve the message by showing the context.
				throw new BeanCreationException(
						this.beanDefinition.getResourceDescription(), this.beanName,
						"Error converting typed String value for " + argName, ex);
			}
		}
		else if (value instanceof NullBean) {
			return null;
		}
		else {
			return evaluate(value);
		}
	}

RuntimeBeanReference,这里就是根据依赖的类型取IOC容器中获取对应的Bean。

image

集合类型的注入,如List类型,就是循环调用塞入List中

image

1.2.6.2.5、initializeBean:初始化bean

image

2.11.2.6.2.5.1、invokeAwareMethods:执行注入的功能

这里面是对 BeanName 的注入,BeanClassLoader 的注入,以及 BeanFactory 的注入
image

2.11.2.6.2.5.2、applyBeanPostProcessorsBeforeInitialization:执行后置处理器

这里就是真正执行BeanPostProcessor的postProcessBeforeInitialization方法
image

2.11.2.6.2.5.3、invokeInitMethods:执行初始化Bean的操作

可以发现这里只有执行了 InitializiingBean 接口的 afterPropertiesSet 方法, @PostConstruct 方法会在一个BeanPostProcessor,
InitDestroyAnnotationBeanPostProcessor,在他的postProcessBeforeInitilization方法中会执行 @PostConstruct 方法

image

InitDestroyAnnotationBeanPostProcessor#postProcessBeforeInitialization
image

2.11.2.6.2.6、registerDisposableBeanIfNecessary:注册销毁时的回调

这里会把实现DisposableBean接口或者声明@PreDestroy注解的方法收集起来。

image
image

2.11.2.6.3、匿名内部类执行完成后的getSingleton调用

它会把当前Bean的name从singletonsCurrentlyInCreation(正在被创建的Bean)中清除,最终将这个Bean添加到singletonObjects(一级缓存)中,createBean完成
image

2.11.2、DefaultListableBeanFactory#preInstantiateSingletons

最后回到preInstantiateSingletons,发现它在最后又回调了一组类型为 SmartInitializingSingleton 的组件,来回调它们的 afterSingletonsInstantiated 方法。它是 InitializingBean 的替代方案,但通过上面的代码也了解,它的执行时机是:所有单实例Bean都创建完毕。

image

2.12、finishRefresh:完成容器的创建工作

  1. 清除资源缓存
  2. 初始化生命周期处理器也就是DefaultLifecycleProcessor
  3. getLifecycleProcessor().onRefresh()会从IOC容器中找出所有的Lifecycle类型的Bean,遍历回调start方法
  4. publishEvent(new ContextRefreshedEvent(this))发布ContextRefreshedEvent事件,代表IOC容器已经刷新完毕

image

原文链接:https://blog.csdn.net/ZXMSH/article/details/125587779

posted @ 2023-10-17 17:13  Lafite-1820  阅读(701)  评论(0编辑  收藏  举报