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容器已经刷新完毕
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)