SpringBoot简化配置分析总结
在SpringBoot启动类中,该主类被@SpringBootApplication所修饰,跟踪该注解类,除元注解外,该注解类被如下自定注解修饰。
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan
让我们简单叙述下它们各自的功能:
- @ComponentScan:扫描需要被IoC容器管理下需要管理的Bean,默认当前根目录下的
- @EnableAutoConfiguration:装载所有第三方的Bean
- @SpringBootConfiguration 作用等同于@Configuration
我们来看下@SpringBootConfiguration
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration
public @interface SpringBootConfiguration {
@AliasFor(
annotation = Configuration.class
)
boolean proxyBeanMethods() default true;
}
可以看到该注解类内包含与@Configuration,其作用与@Configuration并无太大区别,只是多了层属性嵌套。
故: @SpringBootConfiguration + @ComponentScan
将根目录下所有被**@Controller、@Service、@Repository、@Component**等所修饰的类交给IoC容器管理。
那么重点来了,@EnableAutoConfiguration是如何装载第三方Bean的呢?让我们跟踪下它的源码。
首先我们可以看到该类被如下注解修饰:
@AutoConfigurationPackage
@Import({AutoConfigurationImportSelector.class})
我们先关注下AutoConfigurationImportSelector这个组件。
// 批量导入第三方的一些Bean
@Import({AutoConfigurationImportSelector.class})
其中该组件的selectImports(AnnotationMetadata annotationMetadata)方法,扫描所有需要被管理的第三方Bean并交给IoC容器进行管理。
那么SpringBoot又是如何取感知第三方的Bean文件呢?
SpringBoot和第三方Bean之间存在一定的规定。即通过对于相应依赖的Jar包中可能存在一个spring.factories文件,在该文件中就记录了需要被IoC容器管理的Bean文件路径,SpringBoot通过该文件确定需要IoC管理的Bean文件位置。对于spring-boot-autoconfiguration的spring.factories文件中,记录着大量xxxAutoConfiguration的类文件位置,这些类都被@Configuration注解标识,即这些配置类会配置多个Bean从而解决spring.factories可能产生的臃肿问题。
Tomcat的加载时机
对于SpringBoot来说它特点不仅是简化配置,还有内嵌容器等特点。那么就有必要探讨Tomcat容器的加载时机。在spring-boot-autoconfiguration的spring.factories文件中存在ServletWebServerFactoryAutoConfiguration配置类的路径,该类会在项目启动时将默认的Tomcat容器已@Bean的方式加载入IoC容器内部。
SpringBoot是如何集中配置呢?
谈论这个问题前我们不妨先按照之前yml或properties的文件配置下
server:
port: 8080
通过IDE,跟踪到port所配置的成员变量所在类,发现该类被@ConfigurationProperties所修饰,该注解就是将yml或properties中配置按照对应前缀注入到指定类的成员变量。该注解具体实现感兴趣的小伙伴们可以去如下链接学习。@ConfigurationProperties实现原理与实战
@ConfigurationProperties(prefix = "server", ignoreUnknownFields = true)
public class ServerProperties {
private Integer port;
*******
}
下面两个代码和前述作用大致相同
environment.getProperty("xxx");
@Value("${xxx}")
已经知道了SpringBoot如何简化配置,那么我们也可以自己来实现一个starter交给SpringBoot来使用,只要在对应Jar包中添加spring.factories文件,在其中添加如下代码。
org.springframework.boot.autoconfigure.EnableAutoConfiguration=xxxAutoConfiguration
大家若有时间还请实现下自己的starter依赖,对加深这部分理解还是很有帮助的。
最后我们在说下最后@SpringBootApplication中@AutoConfigurationPackage这个注解类,发现其中导入了Registrar组件。
@Import({Registrar.class})
让我们重点关注registerBeanDefinitions这个方法,该方法最终会来到DefaultListableBeanFactory中registerBeanDefinition(String beanName, BeanDefinition beanDefinition)方法,将AutoConfigurationPackages.Registrar.class导入到IoC容器中,然后将主配置类所在包下所有组件导入到SpringIoC容器中
怎么样,在为我们简化了配置的同时,SpringBoot居然帮我们做了如此多的事情,而我们只需要简单地集中配置其中一部分的属性。关于SpirngBoot我们就探讨到这里,这些内容是阅读一些文章,观看部分讲解和源码的总结,若有错误还请接纳与指教。最后感谢各位的阅读。