springboot自动装配
从主启动类开始
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class MainApplication {
public static void main(String[] args) {
SpringApplication.run(MainApplication.class, args);
}
}
上述代码,是一个springboot的web应用程序的入口类,想要了解springboot是如何装配的,我们需要了解@SpringBootApplication这个注解。
1.@SpringBootApplication
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {
1.1.@ComponentScan
指定扫描的包路径,value是一个数组,可以同时指定多个包路径,详细说明略。
1.2.@SpringBootConfiguration
@Configuration
public @interface SpringBootConfiguration {
其实就是一个配置类,也就是说,入口类本身就被标识为一个配置类,没什么可说的。
1.3.@EnableAutoConfiguration
这个注解,表面意思为:开启自动配置。顾名思义,springboot的自动装配机制应该与这个注解有关。
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
点开这个注解我们可以看到,注解头上有含义的两行,做了两件事情:
- @AutoConfigurationPackage:扫描并注册我们自己写的java类到spring容器
- @Import(AutoConfigurationImportSelector.class):注册springboot提供的自动配置类到spring容器
1.3.1.@AutoConfigurationPackage
@Import(AutoConfigurationPackages.Registrar.class)
public @interface AutoConfigurationPackage {
可以看到,@AutoConfigurationPackage注解其实是向容器中导入了一个AutoConfigurationPackages.Registrar的实例对象,那么这个实例对象有哪些作用呢?接着看。
1.3.1.1.AutoConfigurationPackages.Registrar
static class Registrar implements ImportBeanDefinitionRegistrar, DeterminableImports {
@Override
public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
register(registry, new PackageImports(metadata).getPackageNames().toArray(new String[0]));
}
...
}
其中
register(registry, new PackageImports(metadata).getPackageNames().toArray(new String[0]));
这个代码中,其实就是完成了我们自己写的类的扫描。new PackageImports(metadata).getPackageNames().toArray(new String[0])
获取到的是指定扫描包的路径,如果未明确指定,默认为主启动类所在的包名。
在debug模式下就可以轻松看到。
具体的注册细节暂时不深究。
1.3.2.@Import(AutoConfigurationImportSelector.class)
这个注解,很明显,作用是向spring容器中注入了一个AutoConfigurationImportSelector的对象。
1.3.2.3.AutoConfigurationImportSelector
这个类所做的,是将springboot提供好的自动配置装载进spring容器。
这个类中有一个方法:
protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
这个方法是获取所有的自动配置类的实体,debug看一下,实际上就是获取了springboot写好的127个自动配置类实体。
这127个类是在spring-boot-autoconfigure模块下定义的,如下图所示
spring-boot在启动时,默认就装载了这些自动配置类,但是并没有启用,只有在引入相关依赖包的时候,这些自动配置才真正被启用,这种按需加载的原理是基于条件注解实现的,如下图所示:
条件注解功能强大,这里不详细展开,请自行探索或参阅其它文章。
还没有评论,来说两句吧...