SpringBoot如何扫描启动类所在包及子包

2年前 (2022) 程序员胖胖胖虎阿
357 0 0

前言

当初学习SpringBoot框架的时候发现他只会扫描启动类所在包下和子包。最近刚好在学源码,想要探究为什么是默认扫描启动类所在包,而不是其他路径?我从run方法开始debug。SpringApplication的run方法可以找到SpringBoot的大致启动流程。
SpringBoot如何扫描启动类所在包及子包

多的不说,SpringBoot实际上也是依托与Spring的。而注解扫描不可能会放在创建应用上下文阶段的,debug发现在createApplicationContext和prepareContext方法调用后IOC容器中并没有扫描到我们自己定义的bean。但是我们的主启动类被加载了。
SpringBoot如何扫描启动类所在包及子包
进入refreshContext方法,发现实际上调用的是Spring框架中的refresh方法。refresh方法贯穿了整个Spring框架的启动过程,内容有点多我就不详细介绍了。想要了解的可以去学习一下Spring源码。我只会大致说一下内容。
SpringBoot如何扫描启动类所在包及子包
值得注意的是,obtainFreshBeanFactory在Spring中确实是创建ioc容器的。不过SpringBoot在调用refresh方法前就以及创建了,所以SpringBoot是不会重新创建容器的,我在具体的实现打断点结果并没有进入断点。
SpringBoot如何扫描启动类所在包及子包
其他的方法我就不详细介绍了,SpringBoot的扫描重点是在invokeBeanFactoryPostProcessors方法中。invokeBeanFactoryPostProcessors方法就是调用各个BeanFactoryPostProcessor,不过调用过程也分优先级,它是优先调用@PriorityOrdered注解和@Ordered修饰的处理器。其中有一个关键的类:ConfigurationClassPostProcessor。顾名思义,翻译过来就是配置类后置处理器。
SpringBoot如何扫描启动类所在包及子包

==============================================================================SpringBoot如何扫描启动类所在包及子包
ConfigurationClassPostProcessor类就是负责扫描标记了@Configuration等注解,这就是为什么它要被第一个调用。只有它被调用了才能扫描到注解导入的Bean。在processConfigBeanDefinitions中会调用ConfigurationClassParser类的parse方法对启动类进行解析。
SpringBoot如何扫描启动类所在包及子包
启动类上带了SpringBootApplication注解,结果为true。SpringBoot如何扫描启动类所在包及子包
进入parse方法后会调用processConfigurationClass处理配置类。SpringBoot做事的一般都是do开头的,所以直接进入doProcessConfigurationClass方法。
SpringBoot如何扫描启动类所在包及子包
终于在doProcessConfigurationClass方法中见到了熟悉的东西。在方法中会判断类上是否有@CompomentScan注解,而SpringBootApplication是个组合注解,点进去查看实际上是由@CompomentScan组合来的。
SpringBoot如何扫描启动类所在包及子包
SpringBoot如何扫描启动类所在包及子包
在parse方法中会对这个@CompomentScan注解的信息进行解析,比如拿到我们要扫描的包路径,但是默认是没有路径的,那SpringBoot是怎么处理的呢?SpringBoot会默认以启动类所在包为路径调用doScan进行扫描。
SpringBoot如何扫描启动类所在包及子包
实际上到这里大家应该都以及知道了。有了包路径接下来就是扫描所有的Bean并解析成BeanDefinition放入ioc容器的map中。其中findCandidateCompoments就是进行字符串拼接,将刚才的包路径拼接上+/**/*.class,扫描对应的Bean。SpringBoot如何扫描启动类所在包及子包
SpringBoot如何扫描启动类所在包及子包

版权声明:程序员胖胖胖虎阿 发表于 2022年9月24日 上午1:08。
转载请注明:SpringBoot如何扫描启动类所在包及子包 | 胖虎的工具箱-编程导航

相关文章

暂无评论

暂无评论...