SpringBoot 启动流程

SpringBoot 启动流程(基于2.2.6.RELEASE)

首先分为两部分

  1. 启动类上面的注解@SpringBootApplication
  2. main方法
public static void main(String[] args) {
	SpringApplication.run(DemoSpringApplication.class, args);
}
  1. 从@SpringBootApplication这个注解看起

    四个元注解不看,还剩下@SpringBootConfiguration,@EnableAutoConfiguration,@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })

    首先看@SpringBootConfiguration

            点开发现被@Configuration注解了,并且成员方法proxyBeanMethods已经被@AliasFor(annotation = Configuration.class)注解,说明了@SpringBootConfiguration和@Configuration中的proxyBeanMethods互为别名(虽然它们的名字就是一致的,滑稽)。
            那么就像注释提到的[Can be used as an alternative to the Spring`s standard @Configuration annotation so that configuration can be found automatically (for example in tests).],翻译过来就是可以用作Spring的标准@Configuration注释的替代,以便可以自动找到配置 (例如在测试中)。

            反正不知道都和@Configuration重复了,还有啥意义,不过注释中还提到了应用程序应该只包含一个@SpringBootConfiguration配置,大多数惯用的Spring Boot应用程序将从 @SpringBootApplication继承它。

    再看@EnableAutoConfiguration

            经过波澜不惊的@SpringBootConfiguration,还是迎来了@EnableAutoConfiguration这个大头,Spring中有一大串@Enable开头的注解,其实都是代表了一种能力,最终干活的还是@EnableXXX注解上面的@Import里面的Selector。
            @EnableAutoConfiguration就是代表了开启了自动配置能力,啥意思呢,就是所有@Configuration的类会被扫到,并且把里面@Bean的方法转化为Bean放到spring容器中。然而不光是如此,@EnableAutoConfiguration配套的Selector叫AutoConfigurationImportSelector,这个Selector里面还藏了亿点点小知识。

            下面都用[Selector]来代指[AutoConfigurationImportSelector]

            大家都知道SpringBoot有个减少配置文件的特点,是通过自动配置来实现的,可能还有小伙伴知道META-INF下面有个spring.factories,自动配置加载就是的这个文件下的bean定义,包含了很多常见的bean。但是大家有没有想过具体执行流程,还有比方说我明明没有用到es,但是spring.factories中有啊,并且还有很多我用不到的Config类,是不是浪费了?
            首先看执行时机,前面说到了Selector被@Import带入了Spring容器中,并且看继承关系,这个Selector实现了ImportSelectorselectImports方法,那么好像答案呼之欲出了,直接给Selector的selectImports方法打上断点,奥里给,DEBUG启动,结果,并没有发生什么,?!,wtf,看来并不是这个方法被调用
            后来经过尝试,发现了入口是Selector中内部类AutoConfigurationGroupprocess方法。说下尝试的大致的思路就是getAutoConfigurationEntry方法肯定会被调用,因为在这个方法读取了spring.factories
            看到堆栈得知整个调用链路开端是ConfigurationClassPostProcessor,这个类实现了BeanDefinitionRegistryPostProcessorpostProcessBeanDefinitionRegistry方法,不用我多说了吧,自己去百度refresh方法。
            顺带说一句,把内部类AutoConfigurationGroup暴露出去的途径是Selector实现了DeferredImportSelectorgetImportGroup方法。
            再看自动配置是否会冗余的问题,加载spring.factories的方法是Selector中的getAutoConfigurationEntry方法,点进去看到有不少行,直接读取spring.factories执行链路是

    getAutoConfigurationEntry
    getCandidateConfigurations
    SpringFactoriesLoader.loadFactoryNames

            我们先不拓展开原理,直接上DEBUG,发现刚开始读取完spring预置好的配置文件的数量是124个Config类Bean,但是经过Selector方法中filter方法逻辑后变成了23个。
            大致原理是这些配置类上有@ConditionalOnClass,以ElasticsearchAutoConfiguration为例,我并没有导入es相关的依赖,所以不会实例化,就很nice
    阿巴阿巴

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值