之前一直感觉存在这样一个问题:很多视频教程都有说到这样一件事,我们的配置要优先于springboot的自动配置,这样springboot配置的自动配置类就能根据配置情况来判定是否生效的问题。那么spring是怎样保证这件事情的呢?换句话说,就是为什么我们的配置要优先于springboot的自动配置,就是加入我们配置了一个bean,springboot会取注入我们的bean,而springboot为我们自动配置的bean就无效。所以那些教程只说springboot就是这样去设计的,这样感觉还是不能放心的使用这个东西。
我们知道spring先读取成beanDefinition,然后根据bd来为我们创建bean。那么这个过程肯定是在处理beanDefinition的这个阶段,而在这个阶段的后置处理器接口是BeanDefintionRegistryBeanPostProcessor,spring为我们写了这样的接口的实现类ConfigurationClassPostProcessor。
我们还要注意到ImportSelect这个接口还有一个它的子接口叫做DeferredImportSelector接口,而观察到@SpringBootApplication注解上的@EnableAutoConfiguration注解中有这样一个注解@Import(AutoConfigurationImportSelector.class) ,这个AutoConfigurationImportSelector继承自DeferredImportSelector接口,而DeferredImportSelector接口又继承自ImportSelector接口,在ConfigurationClassParser的processImports方法中有对这个DeferredImportSelector作特别处理,把这样的类放到了最后再做处理。最开始的触发点在ConfigurationClassPostProcessor,这个后置处理器使用了ConfigurationClassParser的parse方法,我们可以看到这个parse方法里面再调用parse完所有的BeanDefinitionHolder之后,再调用this.deferredImportSelectorHandler.process()处理的,所以这也就是为什么我们写的配置要优先于springboot的自动配置的原因。
总之一句话:@springbootApplication的注解引入的@EnableAutoConfiguration注解,里面引入的那个importSelect就是延迟selector,spring先处理我们的,然后再处理自动装配的,那些自动配置类上的那些条件就可以根据我们的配置情况来判断是否应该生效