目录
铁器时代:AutoConfigurationImportSelector
Spring Boot的出现与微服务架构有关,它是Spring Framework的一部分,旨在简化开发独立的、可执行的Java应用程序。Spring Boot解决了传统Java应用程序开发中的繁琐配置问题,使开发人员能够更快速地构建微服务和独立应用程序。
如果要快速入门,这个传送门一定很有帮助------->Spring | Quickstart
Spring入门详解的部分诸君可以看一下这篇文章:
- "1.0" encoding="UTF-8"?>
- <beans xmlns="http://www.springframework.org/schema/beans"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://www.springframework.org/schema/beans
- http://www.springframework.org/schema/beans/spring-beans.xsd">
-
-
- <bean id="myBean" class="com.elaine.MyBean">
- <property name="name" value="elaine"/>
- bean>
-
- beans>
- @Configuration
- public class MyConfiguration {
-
- @Bean
- public MyBean myBean() {
- MyBean bean = new MyBean();
- bean.setName("Elaine");
- return bean;
- }
- }
SpringBoot开启自动配置的注解是@EnableAutoConfiguration,但是自动配置的核心功能是通过AutoConfigurationImportSelector实现的。
- @Target({ElementType.TYPE})
- @Retention(RetentionPolicy.RUNTIME)
- @Documented
- @Inherited
- @AutoConfigurationPackage
- @Import({AutoConfigurationImportSelector.class})
- public @interface EnableAutoConfiguration {
- String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
-
- Class>[] exclude() default {};
-
- String[] excludeName() default {};
- }
AutoConfigurationImportSelector实现ImportSelector接口,收集需要导入的配置类,配合@Import将相应的类导入到Spring容器中。
获取注⼊类的⽅法是 selectImports(),它实际调⽤的是 getAutoConfigurationEntry ,这个⽅法是获取⾃动装配类的关键,主要流程可以分为这么⼏步:
获取注解的属性,用于后面的排除
获取所有需要⾃动装配的配置类的路径:这⼀步是最关键的,从 META-INF/spring.factories 获取⾃动 配置类的路径
去掉重复的配置类和需要排除的重复类,把需要⾃动加载的配置类的路径存储起来
- public String[] selectImports(AnnotationMetadata annotationMetadata) {
- if (!this.isEnabled(annotationMetadata)) {
- return NO_IMPORTS;
- } else {
- AutoConfigurationEntry autoConfigurationEntry = this.getAutoConfigurationEntry(annotationMetadata);
- return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
- }
- }
-
- protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
- if (!this.isEnabled(annotationMetadata)) {
- return EMPTY_ENTRY;
- } else {
- // 1.获取注解的属性
- AnnotationAttributes attributes = this.getAttributes(annotationMetadata);
- // 2.获取需要⾃动装配的所有配置类,读取META-INF/spring.factories,获取⾃动配置类路径
- List
configurations = this.getCandidateConfigurations(annotationMetadata, attributes); - // 3.1.移除重复的配置
- configurations = this.removeDuplicates(configurations);
- // 3.2.处理需要排除的配置
- Set
exclusions = this.getExclusions(annotationMetadata, attributes); - this.checkExcludedClasses(configurations, exclusions);
- configurations.removeAll(exclusions);
- configurations = this.getConfigurationClassFilter().filter(configurations);
- this.fireAutoConfigurationImportEvents(configurations, exclusions);
- return new AutoConfigurationEntry(configurations, exclusions);
- }
- }
在了解自动配置的原理后,就简单地创建一个自定义的spring-boot-starter吧。
文件目录贴一下:
创建自动配置类和需要定义的bean。
- @Configuration
- public class MyUserAutoConfiguration {
- @Bean
- public UserManager userManager(){
- return new UserManager();
- }
- }
- public class UserManager {
- public String sayHello() {
- return "own-starter:hello.";
- }
- }
在 src/main/resources/META-INF/
目录下创建一个 spring.factories
文件
- org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
- com.lloyd.user.MyUserAutoConfiguration
创建一个spring-web的SpringBoot项目,添加自定义Starter的依赖。
-
-
-
org.springframework.boot -
spring-boot-starter-web -
-
-
-
com.lloyd -
springboot_06_own_starter -
0.0.1-SNAPSHOT -
-
-
org.springframework.boot -
spring-boot-starter-test -
test -
-
创建一个Rest接口进行验证
- @RestController
- public class UserController {
- @Autowired
- private UserManager userManager;
-
- @GetMapping("/user")
- public String sayHello(){
- return userManager.sayHello();
- }
- }
浏览器结果:
SpringApplication 这个类主要做了以下四件事情:
推断应⽤的类型是普通的项⽬还是 Web 项⽬
查找并加载所有可⽤初始化器 , 设置到 initializers 属性中
找出所有的应⽤程序监听器,设置到 listeners 属性中
推断并设置 main ⽅法的定义类,找到运⾏的主类
大致流程如下(图片来自于网络):