springboot源码分析——启动流程分析
前言
本文剖析SpringBoot启动时候做了哪些事情。
1、SpringBoot启动流程分析
1.1、 main方法进入
1.2、new SpringApplication&SpringApplication#run方法
- 首先new SpringApplication(primarySources)创建SpringApplication
- 调用其run方法
1.2.1、new SpringApplication(primarySources)创建SpringApplication
这里会调用其重载构造方法,构造方法执行步骤如下:
- 保存主启动类
- WebApplicationType#deduceFromClasspath:判断当前应用环境,从classpath下判断当前SpringBoot应用应该使用哪种环境启动。
- 设置初始化器(会将一组类型为ApplicationContextInitializer的初始化器放入SpringApplication中)
- 设置监听器(加载类型为ApplicationListener的监听器,和上面初始化器一样)
- 确定主配置类(找到有main方法的类)
1.2.1.1、WebApplicationType#deduceFromClasspath
从当前的classpath下面判断有没有一些类来确定当前应用的运行环境。
- 第一个if结构先判断是否是 Reactive 环境,发现有 WebFlux 的类但没有 WebMvc 的类,则判定为 Reactive 环境
- 之后的for循环要检查是否有跟 Servlet 相关的类,如果有任何一个类没有,则判定为非Web环境
- 如果for循环走完了,证明所有类均在当前 classpath 下,则为 Servlet(WebMvc) 环境
1.2.1.2、setInitializers& getSpringFactoriesInstances(ApplicationContextInitializer.class)
这个接口会加载ApplicationContextInitializer列表,ApplicationContextInitializer的作用是用于在刷新容器之前初始化Spring ConfigurableApplicationContext 的回调接口,我们也可以实现ApplicationContextInitializer接口来在容器刷新之前做一些我们的初始化逻辑。
这里SpringFactoriesLoader.loadFactoryNames之前文章已经讲解过了,这里他会通过SPI机制从META-INFO下的spring.factories加载所有类型为ApplicationContextInitializer并且创建对应的实例返回。
通过反射创建ApplicationContextInitializer实例
在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属性中
1.2.2.3、setListeners&getSpringFactoriesInstances(ApplicationListener.class))
这个流程和上面加载ApplicationContextInitializer一样,流程:
- 通过SPI机制加载所有类型为ApplicationListener的组件,并创建对应的实例
- 把创建出来的实例设置到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方法,方法对应的类就是主配置类,就返回这个类。
1.2.2、SpringApplication#run
方法步骤如下:
- StopWatch:创建时间性能监控器
- 创建空的IOC容器,和一组异常报告器
- configureHeadlessProperty():配置与awt相关的信息
- getRunListeners:获取SpringApplicationRunListeners
- prepareEnvironment:准备运行时环境
- configureIgnoreBeanInfo:配置系统参数
- printBanner:打印Banner
- createApplicationContext:创建IOC容器
- prepareContext:初始化IOC容器
- refreshContext:刷新IOC容器
- afterRefresh:刷新后的处理
- listeners.started:发布started时间
- callRunners:运行器回调
1.2.2.1、new StopWatch()
这个就是一个计时器,用来监控启动耗时的,不重要
1.2.2.2、创建空的IOC容器和一组异常报告器
这里SpringBootExceptionReporter是启动错误报告的报告器,并且也是用SpringFactoriesLoader加载,实现类只有一个:FailureAnalyzers
1.2.2.3、configureHeadlessProperty:设置awt相关
这里从System中取出一个配置,然后又给设置回去了,这里大家可以不用关注,这里的作用是:设置应用在启动时,即使没有检测到显示器也允许其继续运行。
1.2.2.4、getRunListeners:获取SpringApplicationRunListeners
这里又是使用SPI机制加载SpringApplicationRunListener的实现类,默认加载的listener只有一个,类型为EventPublishingRunListener。
SpringApplicationRunListener的回调方法以及回调时机。
1.2.2.5、prepareEnvironment:准备运行时环境
- 这里在执行prepareEnvironment之前调用了listeners.starting()进行事件回调。
- 这里可以把Environment理解为IOC容器的运行环境,包括Profile和Properties两大部分,他可由一个到几个激活的Profile共同配置,他的配置可在应用级bean中获取。
下面方法步骤如下:
- getOrCreateEnvironment:创建运行时环境
- configureEnvironment:配置运行时环境
- bindToSpringApplication:环境与应用绑定
- 这里也会回调listeners.environmentPrepared方法。
1.2.2.5.1、getOrCreateEnvironment:创建运行时环境
这里就是根据当前的应用运行环境类型,创建不同的Environment,默认SpringBoot环境下会创建StandardServletEnvironment。
1.2.2.5.2、configureEnvironment:配置运行时环境
- 这里ConversionService是类型转换的根接口,它是用来在SpringWebMvc中用来做参数转换的。
- 配置PropertySource和Profile
1.2.2.5.3、configureEnvironment:环境与应用绑定
这里逻辑比较深,但是作用是:把配置内容绑定到指定的属性配置类中(类似@ConfigurationProperties)
1.2.2.6、configureIgnoreBeanInfo:设置系统参数
这里是控制是否跳过BeanInfo类的搜索(spring.beaninfo.ignore),默认是true。
1.2.2.7、printBanner:打印Banner
这里就是控制SpringBoot启动时候打印的图案,默认情况下是打印在控制台的Banner。
1.2.2.8、createApplicationContext:创建IOC容器
这里根据不同的环境创建不同的IOC容器,但是创建的都是基于Annotation的ApplicationContext.
IOC容器类型:
- Servlet - StandardServletEnvironment - AnnotationConfigServletWebServerApplicationContext
- Reactive - StandardReactiveWebEnvironment - AnnotationConfigReactiveWebServerApplicationContext
- None - StandardEnvironment - AnnotationConfigApplicationContext
1.2.2.9、prepareContext:初始化IOC容器
- 将创建好的Environment设置到IOC容器中
- 执行IOC容器的后置处理
- 执行Initializer
- 执行listeners#contextPrepared回调方法
- 创建两个组件用来在控制台打印Banner
- 加载和注册主启动类
- 回调listeners#contextLoaded方法
1.2.2.9.1、postProcessApplicationContext:IOC容器的后置处理
这里设置了几个组件:
- 如果 beanNameGenerator 不为空,则把它注册到IOC容器中。 BeanNameGenerator 是Bean的name生成器。
- 设置ResourceLoader 和 ClassLoader,这个之前已经准备好了
- 设置ConversionService,这个之前已经准备好了,并且还做了容器共享。
1.2.2.9.2、applyInitializers:执行Initializer
这里会获取到所有的ApplicationContextInitializer,然后调用其initialize方法。
1.2.2.9.2、getAllSources:获取主启动类
这里会获取primarySources和sources,之前分析的时候知道primarySources已经被设置为主启动类,sources目前是空的,所以这个方法最终返回的是主启动类。
1.2.2.9.3、load:注册主启动类
- getBeanDefinitionRegistry获取到IOC容器,然后执行createBeanDefinitionLoader创建一个> BeanDefinitionLoader
- 给leader设置BeanName生成器、资源加载器、运行时环境
- 调用BeanDefinitionLoader#load方法。
1.2.2.9.3.1、BeanDefinitionLoader#load
这里会根据传入的source类型,来决定用哪种方式加载,这里我们的主启动类是属于Class类型,所以继续调用重载的lead方法
这里上面Groovy相关的判断我们不关心,下面会判断source是否是一个Component,因为我们的主启动类上标记了@SpringBootApplication注解,而 @SpringBootApplication 组合了一个 @SpringBootConfiguration,它又组合了一个 @Configuration 注解,@Configuration 的底层就是一个 @Component 。所以这里会调用annotatedReader#register方法
1.2.2.9.3.1、AnnotatedBeanDefinitionReader#register
这里会调用到doRegisterBean,在doRegisterBean方法中会把启动类包装成BeanDefinition,然后把BeanDefinition注册到容器中。
1.2.2.10、refreshContext:刷新容器上下文
- 这里调用了refresh方法,这个是最重要的方法了
- 这里注册了一个关闭的钩子,这个钩子是监听JVM关闭时销毁IOC容器和里面的Bean,这里面有一个很经典的应用:应用停止和释放数据库连接池里面的连接。
1.2.2.10.1 、SpringApplication#refreshContext:刷新容器上下文
这里会直接强转成AbstractApplicationContext并调用其refresh方法。AbstractApplicationContext的refresh方法是IOC容器启动最核心的方法,我们在下面单起一小节讲IOC容器的刷新方法。
1.2.2.11、afterRefresh:刷新后的处理
空方法,目前没有实现。
1.2.2.12、listeners.started:发布started事件
1.2.2.12.1、EventPublishingRunListener#started
这里就是调用ConfigurableApplicationContext来发布ApplicationReadyEvent事件
1.2.2.12、callRunners:运行器回调
这里会回调CommandLineRunner和ApplicationRunner的run方法,这个也是回调使用的,可以实现它用来扩展。
至此,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:初始化前的预处理
- 记录启动时间,标记IOC容器状态,之后初始化属性
- 保存容器的早期事件(这个时候事件广播器还没初始化,所以需要保存需要广播的事件)
2.2 、obtainFreshBeanFactory:获取BeanFactory,加载所有bean定义信息
先刷新后获取
2.2.1、GenericApplicationContext#refreshBeanFactory
refreshBeanFactory是一个抽象方法,留给子类重写,对于XML配置的IOC容器和注解配置的IOC容器非别有一种实现GenericApplicationContext 和 AbstractRefreshableApplicationContext 重写了它。根据前面的分析,AnnotationConfigServletWebServerApplicationContext 继承了 GenericApplicationContext。AbstractRefreshableApplicationContext就不进行分析了,因为现在都是基于注解驱动,很少用xml配置了。
GenericApplicationContext#refreshBeanFactory只是简单设置了序列化ID,
2.2.2、GenericApplicationContext#getBeanFactory
这里getBeanFactory也是一个抽象方法,我们看下GenericApplicationContext#getBeanFactory的实现就是把beanFactory直接返回
2.3 、prepareBeanFactory:BeanFactory的预处理配置
- 首先配置了一个ApplicationContextAwareProcessor,然后又忽略了一些Aware接口。
- 然后就是自动注入的支持
- 又注册一个后置处理器ApplicationListenerDetector,它是用来收集ApplicationListener的。
2.3.1、ApplicationContextAwareProcessor
首先我们注册了ApplicationContextAwareProcessor到IOC容器,并且忽略了一些Ware接口。我们发现注入的后置处理作用就是在挨个判断Ware类型,然后注入需要的数据。
2.3.2、ApplicationListenerDetector
addBeanPostProcessor(new ApplicationListenerDetector(this))注册了一个ApplicationListenerDetector的后置处理器,这个后置处理器会收集所有的监听器,把监听器挂载到applicationContext中,这样这些监听器后续才可以被事件广播器广播到。
2.4 、postProcessBeanFactory:BeanFactory的后置处理
这个方法是个抽象方法,子类AnnotationConfigServletWebServerApplicationContext重写了这个方法
2.4.1、ServletWebServerApplicationContext#postProcessBeanFactory
首先调用了父类ServletWebServerApplicationContext#postProcessBeanFactory方法,这里往IOC容器中注册了WebApplicationContextServletContextAwareProcessor,并且忽略了ServletContextAware。
这里就是和上面之前处理aware接口一样,她会把ServletContext和ServletConfig注入到组件中。
2.4.2、registerWebApplicationScopes
registerWebApplicationScopes方法,这里就不细看了,逻辑就是把Web的request域和session域注册到IOC容器中,让IOC容器知道这两种作用域(Bean的作用域)
2.4.3、包扫描
这里如果debug的话if是不进来的,在后续的refresh#invokeBeanFactoryPostProcessors会调用到,我们这里先讲一下ClassPathBeanDefinitionScanner#scan方法执行流程
2.4.3.1、ClassPathBeanDefinitionScanner#doCcan
这里发现首先会调用findCandidateComponents方法,这里返回的是beanDefinition,然后后续对beanDefinition做一些处理然后调用registerBeanDefinition注册到IOC容器中
2.4.3.1.1、findCandidateComponents
这里会来到父类ClassPathScanningCandidateComponentProvider#findCandidateComponents方法,然后这里会进入scanCandidateComponents方法
2.4.3.1.2、scanCandidateComponents
首先它将要扫描的包和一些前缀进行拼接:首先它将要扫描的包和一些前缀进行拼接:前缀是 classpath*: ,后缀默认扫 **/.class ,中间部分调了一个 resolveBasePackage 方法,这个方法其实不看也能猜出来是把这个包名转换成文件路径。这里拼接出来的包路径是: classpath:/com/example/demo/xx/x.class。然后后面会调用getResources方法执行包扫描逻辑。
2.4.3.1.3、PathMatchingResourcePatternResolver#getResources方法
整个方法的大if结构中,先判断要扫描的包路径是否有 classpath*: ,有则截掉,之后判断路径是否能匹配扫描规则。而这个规则的匹配器,通过IDEA发现 PathMatcher 只有一个实现类: AntPathMatcher ,由此也解释了 SpringFramework 支持的是ant规则声明包。
如果规则匹配,则会进入下面的 findPathMatchingResources 方法
2.4.3.1.3.1、findPathMatchingResources方法
首先它会截取扫描根路径,就是启动类所在的包classpath*:com/example/demo/ ,截取完成之后,又把根路径传入了getResources方法,这次没有后缀,只有根路径,然后在getResources方法中会进入findAllClassPathResources方法中
2.4.3.1.3.2、findAllClassPathResources方法
这里真正进行扫描获取包的工作会交给doFindAllClassPathResources方法
2.4.3.1.3.3、doFindAllClassPathResources方法
这里它做的工作就是使用类加载器,把传入的根包以Resource的形式加载出来,以便后续的文件读取。
2.4.3.1.4、解析Component
在scanCandidateComponents方法中,获取所有的Resources,那么后续它使用了一个 MetadataReader 来解析.class文件,它就可以读取这个class的类定义信息、注解标注信息。之后要用 MetadataReader 来判断这个class是否为一个 Component。isCandidateComponent方法会判断class是否被@Component/@ManagedBean标注,如果判断为Component后,会将这个class封装成beanDefinition
2.4.3.2、ClassPathBeanDefinitionScanner#doScan
在上面方法中我们已经解析出来了路径中包含的Componet的组件,并且生成了BeanDefinition。然后后续就是遍历这些BeanDefinition然后生成BeanName,处理一些bean的元信息,然后注册到IOC容器中
2.5 、invokeBeanFactoryPostProcessors:创建BeanFactory创建后的后置处理器
BeanFactoryPostProcessor是一个接口,它提供一个方法,可以在BeanDefinition已经被加载,但没有Bean被实例化,可以对BeanFactory进行后置处理。他还有一个字接口BeanDefinitionRegistryPostProcessor,执行时机是在所有Bean的定义信息即将被加载但未实例化时,也就是咸鱼BeanFactoryPostProcessor,可以实现往容器中添加BeanDefinition。
我们看下下面这个方法,它会去调用invokeBeanFactoryPostProcessors方法。
2.5.1 、PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors:回调后置处理器
- 首先遍历一次,把BeanDefinitionRegistryPostProcessor的后置处理器单独挑出来,直接回调postProcessBeanDefinitionRegistry方法
- 把BeanFactory中所有的BeanDefinitionRegistryPostProcessor分成三部分:实现 PriorityOrdered 接口的、实现 Ordered 接口的,普通的。下面的流程是先进行筛选,然后进行排序,然后注册,最后执行回调,再清除
- 最后也会筛选出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方法。
2.5.2.1、ConfigurationClassPostProcessor#processConfigBeanDefinitions
- 首先获取所有的配置类和组件,然后对配置类排序
- 构造默认的Bean名称的生成器
- 调用ConfigurationClassParser#parse方法解析配置类
- 调用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方法。
2.5.2.2.1、ConfigurationClassParser#processConfigurationClass
重载的方法会调用processConfigurationClass方法,在processConfigurationClass判断下是否已经重复处理了,最终会调用processConfigurationClass方法。
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。
2.5.2.2.1、loadBeanDefinitionsForConfigurationClass
之前已经解析过configClass,所以在这里会区分不同的类型,@Import,@Bean等,区分处理,构造BeanDefinition然后注册到容器中。
2.6 、registerBeanPostProcessors:注册BeanPostProcessor
- 首先从IOC容器中获取了所有实现了BeanPostProcessor的beanName
- 这里和之前逻辑一样,按照规则给所有后置处理器,首先注册所有实现了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
- findAutowiringMetadata:先获取注入的依赖
- InjectionMetadata#checkConfigMembers:再进行对象检查
2.6.1.1 、AutowiredAnnotationBeanPostProcessor#findAutowiringMetadata
这里首先使用双重检查锁来保证线程安全,之后会调用buildAutowiringMetadata方法构建自动装配的metadata
2.6.1.1.1 、AutowiredAnnotationBeanPostProcessor#buildAutowiringMetadata
在这个while循环就是一步一步往父类上爬,判断条件是是否到了Object方法,在循环体中,先是反射遍历当前类的属性,并判断上面是否有@Autowired等注解。之后有获取方法上的注解也保存进去。
2.6.2、ApplicationListenerDetector
registerBeanPostProcessors最后会又添加了一个后置处理器ApplicationListenerDetector,这个后置处理器就是收集所有的监听器,在他的postProcessAfterInitialization方法中,会去把监听器类型的bean注册到IOC容器中
2.7、initMessageSource:初始化MessageSource
这个组件是实现国际化接口的,他的默认实现是DelegatingMessageSource,他的功能:将字符串和参数数组格式化为一个国际化后的消息。
2.8、initApplicationEventMulticaster:初始化事件派发器
首先会判断IOC容器中是否有名称为applicationEventMulticaster的bean,如果没有就默认注册一个applicationEventMulticaster,类型是SimpleApplicationEventMulticaster。这个组件是一个事件发布器,用来做事件的发布。
2.8.1 SimpleApplicationEventMulticaster
这里最终会调用到ApplicationListener 的 onApplicationEvent方法,根据对应的事件匹配对应的listener。
2.9、onRefresh:子类扩展刷新(模版方法)
在springBoot中对这个方法进行了一个扩展,我们看下ServletWebServerApplicationContext#Onrefresh方法,这里发现它会创建一个WebServer也就是tomcat
2.9.1、createWebServer
2.9.1.1、getWebServerFactory:获取嵌入式Servlet容器工厂Bean
怎么一次创建只能运行在一个Servlet容器中,说明一次只能取出一个Bean中,默认的Tomcat创建工厂应该从这里取出:TomcatServletWebServerFactory,他实现了ServletWebServerFactory接口,这个ServletWebServerFactory应该是在自动配置时注册好的。
2.9.1.1.1、自动配置下TomcatServletWebServerFactory注册时机
这个自动配置类使用@Import导入了ServletWebServerFactoryConfiguration的三个内部类,这里会创建TomcatServletWebServerFactory。
2.9.1.2、getWebServer:创建嵌入式Servlet容器
这里其实就是创建并配置tomcat
2.10、registerListeners:注册监听器
- 这里监听器已经在IOC容器中注册好了,取出来后要放入事件广播器,以方便事件广播器广播事件
- 广播早期事件(在之前prepareRefresh方法中会使用earlyApplicationEventsb保存早期事件,这里是没有早期事件的,是留给开发者的,在后置处理器和监听器都被创建好,其余的单实例Bean还没有创建时,提供一个预留的时机来处理一些额外的事情)
2.11、finishBeanFactoryInitialization:初始化单实例Bean
这里最重要的就是在最后会调用preInstantiateSingletons方法初始化非懒加载的bean
2.11.1、DefaultListableBeanFactory#preInstantiateSingletons
上面会经过一系列判断后,如果不是工厂bean,则会调用getBean方法。
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,找不到就返回原始名
2.11.2.2、getSingleton:尝试获取单实例Bean(解决循环依赖)
这里就是首先尝试通过beanName从IOC容器中获取对应的bean,如果不存在才会走后续的实例化过程,这个流程是为了解决循环依赖,这个后续会做详细剖析,这里就不过多讲解了。
2.11.2.3、创建前的检查
这里有个检查循环依赖的方法:isPrototypeCurrentlyInCreation,这个方法是创建原型Bean时会校验的,如果当前线程中在创建一个scope=prototype的Bean,并且当前要创建的Bean跟这个线程中创建的Bean的name一致,则会认为出现了多实例Bean的循环依赖,会引发异常。
2.11.2.4、标记准备创建的Bean
这里标记的过程:IOC容器会把所有创建过的Bean的name都缓存起来,这样下次会判断是否是重复创建。
2.11.2.5、合并BeanDefinition,处理显式依赖
这部分会解析@DependsOn注解标注声明的Bean,并预先的构建它,被依赖的Bean也是通过getBean方法来创建,思路一致。
2.11.2.6、准备创建Bean
这里会调用createBean创建单实例Bean,这里createBean方法是通过getSingleton方法传入匿名内部类,调用的createBean方法。
2.11.2.6.1、getSingleton
这里就是判断如果当前准备创建的Bean还没有在IOC容重,就标记一下它,把当前准备创建的beanName放入singletonsCurrentlyInCreation中,他的作用是解决循环依赖,这个后续会说。然后会调用singletonFactory.getObject()方法,这个会调用到createBean。
2.11.2.6.2、createBean
这里面有两个重要的部分,AOP的入口和真正创建Bean的入口。
2.11.2.6.2.1、resolveBeforeInstantiation:AOP
这里会回调InstantiationAwareBeanPostProcessor的postProcessBeforeInstantiation方法,这个接口对应的部分是真正的AOP创建代理对象的部分,后面会详细分析AOP的流程。
2.11.2.6.2.2、doCreateBean
- createBeanInstance:创建Bean对象
- addSingletonFactory:Bean放入缓存(涉及循环依赖)
- populateBean:属性复制和自动注入
- 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进行创建。
这里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, 为严格模式。下面先看一眼这两种模式下的计算规则:
- 严格模式下,必须要求参数类型完全一致这个方法的实现涉及到算法,不作细致研究
- 宽松模式,只要参数是声明类型或子类型即可
如果使用宽松模式,会出现一个问题:如果构造方法中传入两个接口,而这两个接口分别有两个实现类,此时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:属性赋值和自动注入
- 这里首先会回调InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation,可以让我们自定义属性的注入,可以控制不进行自动属性赋值和注入。
- 回调InstantiationAwareBeanPostProcessor#postProcessProperties,这里其中就包含一个后置处理器,他可以实现@Autowrited、@Value等自动注入。
- 如果是通过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方法是真正的自动注入。
这里面最底下调用了element.inject方法,两个子类重写了这个方法,分别是 AutowiredFieldElement 和 AutowiredMethodElement 。很明显它们是给属性注入和方法注入的,我们以属性注入为例分析
- 这里首先判断这个值有没有在之前的注入中缓存过,如果缓存中存在,直接取缓存
- 如果没有缓存,会调用resolveFieldValue找出对应需要注入的值
- 解析出对应的值,那么通过反射注入到属性中
- 首先调用resolveDependency方法找出依赖值
- 然后加入缓存中
上面的一些判断都是校验被标注@Autowired注解的属性类型,一般都不会用到,会进入最后一个else结构,它调用doResolveDependency方法来解决依赖。
这里就是根据判断需要注入的类型,其中包括数组,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。
集合类型的注入,如List类型,就是循环调用塞入List中
1.2.6.2.5、initializeBean:初始化bean
2.11.2.6.2.5.1、invokeAwareMethods:执行注入的功能
这里面是对 BeanName 的注入,BeanClassLoader 的注入,以及 BeanFactory 的注入
2.11.2.6.2.5.2、applyBeanPostProcessorsBeforeInitialization:执行后置处理器
这里就是真正执行BeanPostProcessor的postProcessBeforeInitialization方法
2.11.2.6.2.5.3、invokeInitMethods:执行初始化Bean的操作
可以发现这里只有执行了 InitializiingBean 接口的 afterPropertiesSet 方法, @PostConstruct 方法会在一个BeanPostProcessor,
InitDestroyAnnotationBeanPostProcessor,在他的postProcessBeforeInitilization方法中会执行 @PostConstruct 方法
InitDestroyAnnotationBeanPostProcessor#postProcessBeforeInitialization
2.11.2.6.2.6、registerDisposableBeanIfNecessary:注册销毁时的回调
这里会把实现DisposableBean接口或者声明@PreDestroy注解的方法收集起来。
2.11.2.6.3、匿名内部类执行完成后的getSingleton调用
它会把当前Bean的name从singletonsCurrentlyInCreation(正在被创建的Bean)中清除,最终将这个Bean添加到singletonObjects(一级缓存)中,createBean完成
2.11.2、DefaultListableBeanFactory#preInstantiateSingletons
最后回到preInstantiateSingletons,发现它在最后又回调了一组类型为 SmartInitializingSingleton 的组件,来回调它们的 afterSingletonsInstantiated 方法。它是 InitializingBean 的替代方案,但通过上面的代码也了解,它的执行时机是:所有单实例Bean都创建完毕。
2.12、finishRefresh:完成容器的创建工作
- 清除资源缓存
- 初始化生命周期处理器也就是DefaultLifecycleProcessor
- getLifecycleProcessor().onRefresh()会从IOC容器中找出所有的Lifecycle类型的Bean,遍历回调start方法
- publishEvent(new ContextRefreshedEvent(this))发布ContextRefreshedEvent事件,代表IOC容器已经刷新完毕