SpringBoot 的自动配置
SpringBoot 是基于 SpringFramework 的上层工具, 为 Spring 应用的开发提供了极大的便捷, 其最核心的功能是自动配置 (AutoConfiguration).
这里的 AutoConfiguration 指的是对 IoC 中 bean 的配置, 即: How to define a Bean。
配置方式
在 Spring 中共有三种配置方式:
- XML-based Configuration
- Annotation-based Container Configuration
- Java-based Container Configuration
在早期的 Spring 应用开发中 XML-based Configuration 是最主流的配置方法, 当时经典的 SSH 和 SSM 应用框架方案就是基于这种配置方法搭建的, 这种配置方案的做法是使用 xml 文件定义 bean 的 Clas
、Name
、Scope
、Constructor arguments
、Properties
、Autowiring mode
、Lazy initialization mode
、Initialization method
、Destruction method
,并由 servlet 中的 web.xml 引导 Spring 应用,使用起来较为繁琐,现在这种用法已经被淘汰了。
不依赖于 servlet 的 spring 应用也可以通过 ClassPathXmlApplicationContext
来引导启动:
fun main() {
val xmlApplicationContext = ClassPathXmlApplicationContext("spring.xml")
}
接下来就是 Annotation-based Container Configuration,其核心注解是:@Component
及其衍生注解 @Controller
、@Service
、@Repository
,它们通过与 @ComponentScan
、@Autowired
等注解的配合使用可以完全代替繁琐的 xml 配置。
然后就是 Java-based Container Configuration,它与 Annotation-based Container Configuration 的区别是:后者都是针对一个类来实现的配置,而 Java-based Container Configuration 则可以通过 @Configuration
、@Bean
、@Import
和代码来实现更加灵活的配置。
Annotation-based Container Configuration 和 Java-based Container Configuration 都可以通过 AnnotationConfigApplicationContext
来引导启动:
@ComponentScan
@Configuration(proxyBeanMethods = false)
class SpringApp {
@Bean
fun myBean(): MyBean {
return MyBean()
}
}
class MyBean
fun main() {
val applicationContext = AnnotationConfigApplicationContext(SpringApp::class.java)
}
自动装配
在上述的配置方式中基本都需要依赖于 @ComponentScan
来加载 component,或者手动调用 register 方法注册 componentClasses,它们都属于主动注册的方案,当你加载了一个第三方提供的 lib 时,需要手动为 lib 中的 component 进行注册。所以 SpringBoot 就提供了一种更加便捷的配置方案:AutoConfiguration。
AutoConfiguration 的原理就是通过 AutoConfigurationImportSelector
和 AutoConfigurationPackages.Registrar
来加载特定位置的配置文件,从而完成 component 的注册。(约定大于配置)
AutoConfigurationImportSelector:加载 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 文件中的 componentClasses
AutoConfigurationPackages.Registrar:解决 @ComponentScan
无法扫描 Spring Data repositories(它们是接口)的问题
在SpringBoot 中 @SpringBootApplication
通过继承 @EnableAutoConfiguration
来实现了对约定配置方案的装配,同时还继承了 @ComponentScan
和 @Configuration
,从而实现全自动装配,SpringBoot 生态中的 starter 也全都是依赖于 AutoConfiguration 来实现的。