[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获取经历重重筛选过滤后的简约配置集合。

又经历一系列的流程

最后所有配置被加载到容器当中

经验分享 程序员 微信小程序 职场和发展