# springboot_autoconfig **Repository Path**: coder_chenjun/springboot_autoconfig ## Basic Information - **Project Name**: springboot_autoconfig - **Description**: spring boot的自动配置模仿实现 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2021-11-08 - **Last Updated**: 2021-11-08 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 各模块说明 1. starter-with-mini-springboot: 模拟的是spring boot自带的模块 2. mini-springboot-autoconfigure-and-core :模拟的是spring boot框架的实现,类似于springboot框架中的spring-boot与spring-boot-autoconfigure 3. starter-user-custom:模拟的是第三方的starter 4. bootstrap:模拟的是一个spring boot项目,包含入口方法(main) > 一个典型的spring boot web依赖图如下: > > ![image-20181122144118158](https://ws3.sinaimg.cn/large/006tNbRwgy1fxgu30lgwyj30bb07hq3m.jpg) > > > > spring boot各个artifact的作用 > > 1. spring-boot-starter-parent: 作为spring-boot-dependencies的子模块,没有很核心的功能,在这里的dependencyManagement里面有添加一个依赖,这些依赖主要是一些spring boot内部未公开的依赖.而对一些重要的artifact的依赖配置是在spring-boot-dependencies模块中进行配置的.spring-boot-starter-parent中没什么代码. > 2. spring-boot-starter: 里面也没什么代码,主要是用添加各种各样的依赖,比如spring-boot,spring-boot-autoconfigure等 > 3. spring-boot:核心代码所在地,如SpringApplication类,springboot自带的一个starter的自动配置代码在spring-boot-autoconfigure里面 > 4. spring-boot-autoconfigure: 自动配置相关的代码,比如EnableAutoConfiguration等 # Spring Boot自动配置原理 修饰了@SpringBootApplication后就等于修饰了@EnableAutoConfiguration,修饰了@EnableAutoConfiguration等于在导入(Import)AutoConfigurationImportSelector此类确定的所有配置类,见下面的代码: ```java @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) }) public @interface SpringBootApplication ``` ```java @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited @AutoConfigurationPackage @Import(AutoConfigurationImportSelector.class) public @interface EnableAutoConfiguration{} ``` 而我编写的AutoConfigurationImportSelector读取配置分为2类。 - 一类是spring boot官方提供的一些配置类,在\META-INF\spring-autoconfigure-metadata.properties文件中, 利用spring boot提供的AutoConfigurationMetadataLoader来读取,此文件直接指明了自带starter的配置类的全称 - 一类是第三方提供的一些配置类,主要是在开发自定义starter时使用, 这些第三方的配置类就在第三方jar文件下的META-INF/spring.factories文件中, 利用SpringFactoriesLoader来读取,第三方的配置类读取称之为候选配置(Candidate). 在此文件中配置为: 有多个配置类时用逗号分隔 ```properties com.edu.annotation.EnableAutoConfiguration=config.SimpleStarterAutoConfig ``` 在AutoConfigurationImportSelector的selectImports方法中有下面的代码 ```java AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader .loadMetadata(this.beanClassLoader); AnnotationAttributes attributes = getAttributes(annotationMetadata); List configurations = getCandidateConfigurations(annotationMetadata, attributes); ``` loadMetadata方法的核心部分如下: ```java protected static final String PATH = "META-INF/" + "spring-autoconfigure-metadata.properties"; static AutoConfigurationMetadata loadMetadata(ClassLoader classLoader, String path) {} ``` getCandidateConfigurations方法代码如下: ```java protected List getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) { List configurations = SpringFactoriesLoader.loadFactoryNames( getSpringFactoriesLoaderFactoryClass(), 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; } ``` # 额外说明 - @Import注解等价于在xml文件中配置时导入其它的spring配置文件,它支持两种情况 - 直接指定配置类 - 指定实现了ImportSelector接口的类型,用来确定哪些是可用的配置类 - 自定义spring boot starter的一份参考文档https://www.jianshu.com/p/45538b44e04e