[Spring boot]源码分析——Spring Boot自动装配原理
[Spring boot]源码分析——Spring Boot自动装配原理
author:陈镇坤27
创建日期:2022年1月25日
————————————————————————————————
前言
建议随源码debug一遍。
所选start版本为2.1.6.RELEASE,不同版本的源码执行链不一。
Spring Boot的自动配置
下面是Spring Boot项目的引导类
@SpringBootApplication
public class helloWordMainApplication {
public static void main(String[] args) {
SpringApplication.run(helloWordMainApplication.class,args);
}
}
@SpringBootApplication注解配置的类,会成为启动服务的主程序。
该注解主要内部包含注解核心是**@SpringBootConfiguration和@EnableAutoConfiguration**
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration // 核心1
@EnableAutoConfiguration // 核心2
@ComponentScan(excludeFilters = {
@Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
核心1:@SpringBootConfiguration注解代码如下:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration //是spring的配置类注解,将所注解类解释为配置类
public @interface SpringBootConfiguration {
}
核心2:@EnableAutoConfiguration注解代码如下:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage // 核心2.1 获取包扫描路径
@Import(AutoConfigurationImportSelector.class) // 核心2.2 判定加载哪些组件
public @interface EnableAutoConfiguration {
String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
Class<?>[] exclude() default {
};
String[] excludeName() default {
};
}
核心2.1:@AutoConfigurationPackage注解代码如下:(作用:找出容器组件扫描路径范围)
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Import(AutoConfigurationPackages.Registrar.class) // 核心2.1.1
public @interface AutoConfigurationPackage {
}
核心2.1.1:@Import(AutoConfigurationPackages.Registrar.class)所引入的类源码如下
static class Registrar implements ImportBeanDefinitionRegistrar, DeterminableImports {
@Override
public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
// metadata为注解所标类元数据
// 注册包
// new PackageImport(metadata).getPackageName()获取元数据所在包路径
register(registry, new PackageImport(metadata).getPackageName());
// 该路径及路径下的所有组件,都会被容器扫描
}
@Override
public Set<Object> determineImports(AnnotationMetadata metadata) {
return Collections.singleton(new PackageImport(metadata));
}
}
核心2.2:@Import(AutoConfigurationImportSelector.class)所引入的类源码先按下不表
先看服务器启动后,会执行的一个流程
从helloWordmainApplication执行到SpringFactoriesLoader,会执行loadSpringFactories方法,将"META-INF/spring.factories"路径下的路径加载封装成URL,并计入cache缓存中。
然后再经历一系列的执行,到ConfigurationClassParser,1:获取能够装配的配置;2:开始装配。
而这两个方法都来自接口
执行进入process方法。实现类为AutoConfigurationGroup,是AutoConfigurationImportSelector的内部类。
由于我们注解配置import 了AutoConfigurationImportSelector,所以相当于激活了此处的装配功能。
process方法会获取此前cache中缓存的配置类全路径集合,并再之后由ConfigurationClassParser调用selectImports获取经历重重筛选过滤后的简约配置集合。
又经历一系列的流程
最后所有配置被加载到容器当中
