SpringBoot自动配置类解析源码流程
2023-11-16 15:22:04 0 举报
SpringBoot自动配置解析流程图
作者其他创作
大纲/内容
这一步会构建ConfigurationClassParser,调用ConfigurationClassParser.parse方法去解析run方法中传入的启动配置类,我这里就是CqzxkAdminApplication
configurations表示满足条件的自动配置类exclusions表示需要排除的自动配置类
分完组之后,执行DeferredImportSelectorGroupingHandler的handler.processGroupImports()方法,遍历groupings(相当于分组执行)
1、运行main方法
执行SpringApplication.run方法->SpringApplication#run(java.lang.String...) -> 执行一些springboot启动过程中其它的步骤,包括创建spring容器、发布启动事件、解析入参、配置环境变量、打印banner等操作 -> SpringApplication#refreshContext(刷新Spring容器,会解析配置类、扫描、启动WebServer) -> SpringApplication#refresh ->ConfigurableApplicationContext#refresh -> 根据应用类型执行ConfigurableApplicationContext具体实现类的refresh方法,如果是一个servletweb应用则执行ServletWebServerApplicationContext#refresh -> org.springframework.context.support.AbstractApplicationContext#refresh
接下来用DeferredImportSelectorHandler去处理DeferredImportSelectorHolder,这一步deferredImportSelectors值为上图
org.springframework.context.annotation.ConfigurationClassParser#parse(java.util.Set<org.springframework.beans.factory.config.BeanDefinitionHolder>)方法,会先解析启动配置类上的注解,把@Import注解导入的deferredImportSelector(延迟导入选择器)类型的类解析出来封装成DeferredImportSelectorHolder类型放入deferredImportSelectors中,然后执行方法的this.deferredImportSelectorHandler.process()代码deferredImportSelectorHandler = new ConfigurationClassParser.DeferredImportSelectorHandler(),也就是执行DeferredImportSelectorHandler拦截器的process方法
执行org.springframework.boot.autoconfigure.AutoConfigurationImportSelector#getAutoConfigurationEntry方法,获取spring.factories文件中的自动配置类并过滤获取满足条件的自动配置类,getAutoConfigurationEntry方法详情请看上面1.1.4
执行ConfigurationClassParser.DeferredImportSelectorGrouping的getImports方法,遍历每个组的导入选择器去执行组的process方法,把这个组里面所有的导入选择器需要导入的类都拿到
org.springframework.context.support.AbstractApplicationContext#invokeBeanFactoryPostProcessors
org.springframework.context.annotation.ConfigurationClassPostProcessor#postProcessBeanDefinitionRegistry
获取BeanFactoryPostProcessor对beanfactory进行处理,此时BeanFactoryPostProcessor有3个:
当这一组的所有导入选择器都遍历执行完组的process方法之后,执行AutoConfigurationImportSelector.AutoConfigurationGroup#selectImports方法,把上一步的autoConfigurationEntries常量取出来,把满足条件的自动配置类再根据exclusions(需要排除的自动配置类)进行过滤,得到最后满足条件的自动配置类,把满足条件的自动配置类进行排序,再组装成Entry实体(两个成员变量metadata=启动类元数据、importClassName=自动配置类全限定名)返回
总结:1、@Import(AutoConfigurationImportSelector.class) 会通过AutoConfigurationImportSelector延迟且分组的向Spring容器导入需要自动装配的组件的配置类,从而在解析这些配置类的时候能够将自动装配的组件的bean注册到容器中;2、所谓的延迟,是因为AutoConfigurationImportSelector实现了DeferredImportSelector接口,其逻辑会在Springboot启动类被解析完毕后才会执行。AutoConfigurationImportSelector属于AutoConfigurationGroup这个组,并且其分组执行时也会进行排序,AutoConfigurationGroup永远是排在最后执行的;3、所谓的分组,是因为处理DeferredImportSelector是一组一组的进行的,只要DeferredImportSelector的实现类实现的getImportGroup() 方法返回的Class对象一样,那么这样的DeferredImportSelector的实现类就属于同一组;4、AutoConfigurationImportSelector获取到需要自动装配的组件的配置类的全限定名,是通过SpringFactoriesLoader完成的,而SpringFactoriesLoader就是Spring中的SPI机制的实现。5、自动配置类的解析节点是在SpringBoot启动过程中在SpringApplication#refreshContext方法中进行的。refreshContext会调用到AbstractApplicationContext.refresh方法,这个方法是执行spring的流程,会对BeanFactory进行增强、执行BeanFactoryPostProcessor,其中就会通过ConfigurationClassPostProcessor去解析配置类,扫描@Component修饰的类生成BeanDefinition,并注册到beanFactory中。大概流程是会先解析启动配置类,通过解析@ComponentScan注解拿到扫描路径进行扫描,也会解析@Import注解导入的类,会处理自动配置类(只是筛选拿到满足条件的自动配置类),这些自动配置类会在启动配置类解析完成以及程序员自定义的bean注入spring之后才会去一个个的解析自动配置类看是否满足条件,再把自动配置类里面的bean注入spring简而言之:refreshContext这一步会刷新Spring容器,解析配置类(包括启动配置类)、扫描、生成非懒加载的单例bean、启动WebServer6、需注意ASM技术的使用
执行run方法流程
执行DeferredImportSelectorHandler拦截器的process方法,这个方法会对deferredImportSelectors进行排序,然后再遍历,调用DeferredImportSelectorGroupingHandler的register方法对每个导入选择器进行分组。这个时候deferredImportSelectors中就有@EnableAutoConfiguration注解导入的AutoConfigurationImportSelector类。
得到BeanDefinitionRegistryPostProcessor,调用postProcessor.postProcessBeanDefinitionRegistry(registry)去注册bean,此时BeanDefinitionRegistryPostProcessor为ConfigurationClassPostProcessor
遍历满足条件的自动配置类,再调用ConfigurationClassParser.this.processImports方法去解析自动配置类上面是否有通过@Importd导入的类,递归调用直到把所有导入的类解析完成。在此期间都是通过ASM技术直接操作class文件,通过自动配置类的全限定名拿到自动配置类的元数据信息(SimpleAnnotationMetadata)注解、方法。可能解析自动配置类并把满足条件的bean注入到spring中就是在这个循环里面完成的,因为我跟了一下代码,到这一步的时候,都是把AutoConfigurationGroup这个组排到最后,相当于是最后才会执行AutoConfigurationImportSelector去处理自动配置类,在此之前会先把启动配置类解析完成,把自定义的bean解析到spring中去。总之一句话到这个循环的时候springboot已经把该做的都做了才来解析自动配置类
org.springframework.context.annotation.ConfigurationClassPostProcessor#processConfigBeanDefinitions
org.springframework.context.support.PostProcessorRegistrationDelegate#invokeBeanDefinitionRegistryPostProcessors
这个就是自动配置tomcat、jetty、undertom的自动配置类
refresh方法逻辑跟spring源码逻辑类似,就是去扫描、注册beandefinition,生成bean、解析配置类、程序员自定义的配置文件解析完成之后才会去一个个的解析满足条件的自动配置类,这样能保证优先使用程序员自定义的一些bean,而不是用自动配置类自动配置的bean
执行org.springframework.boot.autoconfigure.AutoConfigurationImportSelector.AutoConfigurationGroup#process方法,把结果(封装得有满足条件的自动配置类的AutoConfigurationEntry实体)放入autoConfigurationEntries常量中
执行DeferredImportSelectorGroupingHandler的register方法。deferredImport.getImportSelector().getImportGroup(),这一步会调用AutoConfigurationImportSelector的getImportGroup方法,把AutoConfigurationImportSelector分到AutoConfigurationGroup这个组,并把AutoConfigurationGroup组以及AutoConfigurationImportSelector封装的DeferredImportSelectorHolder再次封装成DeferredImportSelectorGrouping对象添加到DeferredImportSelectorGroupingHandler的groupings常量中
0 条评论
下一页