您现在的位置是:首页 >学无止境 >Spring Boot自动装配网站首页学无止境

Spring Boot自动装配

book多得 2023-06-12 20:00:03
简介Spring Boot自动装配

目录

是什么?

自动装配的原理

进入@SpringBootApplication注解

点击进入@EnableAutoConfiguration注解

AutoConfigurationImportSelector(核心)

点进getAutoConfigurationEntry()方法:

点进getCandidateConfigurations()

流程图


是什么?

Spring Boot自动装配(Automatic Configuration)是指Spring Boot框架中的一种特性,它可以根据应用程序中的依赖关系和配置来自动配置Spring应用程序的各个部分。在Spring Boot中,自动装配通过使用条件化的配置和智能配置来实现(如:condition),这样可以根据应用程序的环境和需要来自动配置不同的组件,例如spring-boot-starter-redis等。自动装配能够大大减少Spring应用程序的配置量,并且使得应用程序更易于维护和升级。

自动装配的原理

进入@SpringBootApplication注解

其中通过@EnableAutoConfiguration注解实现了自动装配。

@Target({ElementType.TYPE}) // 该注解作用于接口、类、枚举
@Retention(RetentionPolicy.RUNTIME) // 注解不仅被保存到class文件中,jvm加载class文件之后,仍然存在
@Documented // 有了该注释后,如果有接口使用了该注解,生成的javadoc文件中,会把该注解展示出来
@Inherited // 如果一个类用上了@Inherited修饰的注解,那么其子类也会继承这个注解
@SpringBootConfiguration // 标识它是一个Spring Boot配置类
@EnableAutoConfiguration // 主要是通过这个注解实现自动装配
@ComponentScan(  // 配置类上添加 @ComponentScan 注解。该注解默认会扫描该类所在的包下所有的配置类
    excludeFilters = {@Filter(
    type = FilterType.CUSTOM,
    classes = {TypeExcludeFilter.class}
), @Filter(
    type = FilterType.CUSTOM,
    classes = {AutoConfigurationExcludeFilter.class}
)})
public @interface SpringBootApplication {
。。。
}

点击进入@EnableAutoConfiguration注解

@Target({ElementType.TYPE}) // 该注解作用于接口、类、枚举
@Retention(RetentionPolicy.RUNTIME) // 注解不仅被保存到class文件中,jvm加载class文件之后,仍然存在
@Documented // 有了该注释后,如果有接口使用了该注解,生成的javadoc文件中,会把该注解展示出来
@Inherited // 如果一个类用上了@Inherited修饰的注解,那么其子类也会继承这个注解
@AutoConfigurationPackage // 记录使用了该注释的类所在的包以及子包的路径,以便后序读取
@Import({AutoConfigurationImportSelector.class})
public @interface EnableAutoConfiguration{...}

AutoConfigurationImportSelector(核心)

@Override
	public String[] selectImports(AnnotationMetadata annotationMetadata) {
		if (!isEnabled(annotationMetadata)) {
			return NO_IMPORTS;
		}
		AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(annotationMetadata);
		return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
	}

点进getAutoConfigurationEntry()方法:

protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
        if (!isEnabled(annotationMetadata)) {
            return EMPTY_ENTRY;
        }
        //@EnableAutoConfiguration中的exclude、excludeName等
        AnnotationAttributes attributes = getAttributes(annotationMetadata);
        //获取所有自动装配的配置类,也就是读取spring.factories文件
        List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);
        //去除重复的配置项。
        configurations = removeDuplicates(configurations);
        //根据@EnableAutoConfiguration中的exclude、excludeName移除不需要的配置类。
        Set<String> exclusions = getExclusions(annotationMetadata, attributes);
        checkExcludedClasses(configurations, exclusions);
        configurations.removeAll(exclusions);
        configurations = getConfigurationClassFilter().filter(configurations);
        //广播事件
        fireAutoConfigurationImportEvents(configurations, exclusions);
        return new AutoConfigurationEntry(configurations, exclusions);
    }
  • getAttributes获取@EnableAutoConfiguration中的exclude、excludeName等。
  • getCandidateConfigurations获取所有自动装配的配置类,也就是读取spring.factories文件,后面会再次说明。
  • removeDuplicates去除重复的配置项。
  • getExclusions根据@EnableAutoConfiguration中的exclude、excludeName移除不需要的配置类。
  • fireAutoConfigurationImportEvents 广播事件
     

点进getCandidateConfigurations()

这里通过loadFactoryNames方法,扫描classpath下的META-INF/spring.factories文件,里面是以key=value形式存储,我们读取其中key=EnableAutoConfiguration,value就是需要装配的配置类,也就是getCandidateConfigurations返回的值。
 

protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
     List<String> configurations = SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.getBeanClassLoader());
     Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you are using a custom packaging, make sure that file is correct.");
     return configurations;
}

流程图

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。