前言
本文主要通过 @SpringBootApplication 启动类注解来分析一下 Springboot 的自动配置原理,话不多说直接上源码。
源码分析
@SpringBootApplication的源码如下:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
- 看第一个注解:@SpringBootConfiguration 的源码
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration
public @interface SpringBootConfiguration {
省略具体内容......
}
主要的注解就一个 @Configuration 代表当前是一个配置类
2.先看第三个注解
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
分析:
- @ComponentScan:指定扫描注解内容
- excludeFilters:指定扫描的时候按照什么规则排除那些组件(格式:excludeFilters = Filter[])
- @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class):type = FilterType.CUSTOM 表示按照自定义方式排除组件,classes = TypeExcludeFilter.class) 具体的方式实现类
3.最后看第二个注解也是实现自动配置的关键 @EnableAutoConfiguration,先看源码
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
省略具体内容......
}
源码中加入了两个注解:@AutoConfigurationPackage 和 @Import(AutoConfigurationImportSelector.class)
a. 先看第一个注解 @AutoConfigurationPackage 的源码
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Import(AutoConfigurationPackages.Registrar.class)
public @interface AutoConfigurationPackage {
}
可以看到有 @Import 注解导入了 AutoConfigurationPackages.Registrar.class 这个类。再看一下这个类的内部类 Registrar 的实现
通过上面的截图可以看到 Registrar 的 registerBeanDefinitions 方法中注册了对应包扫描的路径。这也是为什么我们写在对应包下的注解能够被扫描生效的原因。
b. 再看第二个注解 @Import(AutoConfigurationImportSelector.class) 这个注解也是导入了 AutoConfigurationImportSelector.class 这个类。 这个类的具体调用链如下图
最终 classLoader.getResources(FACTORIES_RESOURCE_LOCATION) 获取了 FACTORIES_RESOURCE_LOCATION 这个资源文件
public static final String FACTORIES_RESOURCE_LOCATION = "META-INF/spring.factories";
即在springboot启动的时候会去加载 "META-INF/spring.factories" 文件。
通过上图可以看见:springboot的jar中存在这个文件,其中定义了所有的启动时就要给容器中加载的所有配置类。这也是为什么springboot能够实现自动装配的原因,当然了这些配置也不是全是都是开启,有些需要我们主动的去开启。
总结
本文通过 @SpringBootApplication 的3个注解源码解析了自动装配的原理,希望大家通过这篇文章能对此有个大致的概念。
finally
public void isLike(){
boolean 喜欢 = true;
if(喜欢){
"关注公众号:程序猿自来也 ";
"扫他 ↓↓↓↓↓↓"
}
}