Spring Boot的启动过程&自动化配置
导读
在看了Spring Boot的启动过程源码后,对整个启动的过程有了一个简单的了解,在这做一个简单的、粗略的记录。
启动过程
Spring Boot的启动过程从代码层面可分为两部分,第一,执行SpringApplication构造函数;第二,执行run()方法,完成整个Spring Boot的启动。
构造函数
初始化上下文的各种接口–ApplicationContextInitializer以及各种监听器–ApplicationListener,这些上下文初始化器和监听器都以文件的形式存储在META-INF/spring.factories文件中,初始化的过程即通过SpringFactoriesLoader工具类提供的静态方法从META-INF/spring.factories文件中进行类加载并完成实例化的过程。
run方法
做完一些初始化的工作之后就进到了run方法,run方法完成了所有Spring的整个启动过程:准备好Environment——发布事件——创建上下文、bean——刷新上下文——结束,总的来说就是完成环境的配置、各种自动化配置任务、创建实例化好容器对象,其中的好多实现是通过事件监听机制完成。
自动化配置
自动化配置即Spring Boot在启动的过程中自动的完成程序资源文件的加载、读取,当程序需要使用时达到直接用的地步,而不需要我们在程序中做对应的加载读取操作。下面用一个例子来说明自动化配置的过程。
案例:
一般我们的Spring Boot项目中会有application.properties配置文件,我们会在这里设置一些项目相关的配置信息,只要在这里做了配置,我们的项目就能够识别使用这些配置信息,但你不觉得奇怪吗,我们只是做了配置而已,并没有写对应的文件加载、解析工作,但我们的项目确可以自动的识别,这其实就是Spring Boot在启动的过程中帮助我们完成了配置文件的加载读取工作,Spring Boot帮我们实现的过程就是自动化配置的过程。
自动化配置的思想就是 约定大于配置,我们只要保证按照Spring Boot制定的规则来做配置,那么Spring Boot就能够为我们完成自动化配置,我们自己无需再做其他任何工作就可以使用我们的配置。
自动化配置的实现过程
前置概念
1、Spring Boot自动化配置需要代码来支撑,Spring Boot关于自动配置的源码在spring-boot-autoconfigure-x.x.x.x.jar中,这里有各种自动化配置的实现代码。
2、自动化配置在Spring Boot启动的过程中完成。
3、自动化配置的实现借助注解来完成。
过程实现
启动类上的@SpringBootApplication注解是一个复合注解,它上边有个@EnableAutoConfiguration注解,该注解的意思是开启自动化配置,这个注解本身也是一个复合注解,定义如下:
@EnableAutoConfiguration的关键功能由@Import提供,其导入的AutoConfigurationImportSelector的selectImports()方法通过SpringFactoriesLoader.loadFactoryNames()扫描所有具有META-INF/spring.factories的jar包,它会将所有的XXXAutoConfiguration的自动化配置类加载到容器中。
导入的这些类称为自动化配置类(也称JavaConfig自动配置类),它们的任务就是完成具体bean的实例化并将其装载到容器中,这里我们分析其中的一个,ServletWebServerFactoryAutoConfiguration。
它的上边有@EnableConfigurationProperties(ServerProperties.class)这个注解,该注解的意思表示开启配置属性,并且参数里有ServerProperties这个类,表示用这个类来和属性做映射。这个类上边有@ConfigurationProperties(prefix = “server”, ignoreUnknownFields = true)注解,@ConfigurationProperties这类注解实现从配置文件中绑定属性到具体的bean上,它的参数prefix就是我们在配置文件中定义属性时用到的前缀,例如 server.port=8080。
总结
1、@ConfigurationProperties注解实现将配置文件中的具体属性绑定到它所修饰的相应的XXXProperties 的bean中;
2、@EnableConfigurationProperties(XXXProperties.class)表示开启自动配置属性,并将具体的配置类XXXProperties加载,XXXProperties类上有@ConfigurationProperties注解修饰,因此能完成bean初始化。
3、@EnableAutoConfiguration表示开启自动化配置,它的主要功能由@Import来完成,利用@Import导入自动配置选择器AutoConfigurationImportSelector,让AutoConfigurationImportSelector去META-INF/spring.factories中加载自动化配置类。
4、在Spring Boot启动时会根据主类上的@SpringApplication注解找到开启自动配置功能的@EnableAutoConfiguration,再根据@EnableAutoConfiguration找到它的辅助注解@Import,根据@Import导入自动配置选择器AutoConfigurationImportSelector,利用该选择器完成META-INF/spring.factories中的自动化配置类的加载,而这些自动配置类都是以AutoConfiguration结尾来命名的,它实际上就是一个JavaConfig形式的Spring容器配置类(关于JavaConfig后面有介绍),它能通过以Properties结尾命名的类取得在全局配置文件中配置的属性如:server.port(这些类上有@EnableConfigurationProperties(XXXProperties.class)注解修饰,表示开启属性配置,并指明具体的Properties类),而XxxxProperties类是通过@ConfigurationProperties注解与全局配置文件中对应的属性进行绑定的。
JavaConfig
我们知道,Spring容器运行时,需要有一个提供Bean定义的载体,在3.0前,这个载体主要是xml配置文件,而从Spring 3.0开始,一个新的@Configuration注解被添加进框架,使用该注解可以快速标识一个类成为Spring的Java Class配置类,官方称这种方式为JavaConfig,这种方式旨在使用Java类对Spring框架进行配置,提供Bean定义,是xml配置文件的一种替代或协同工作的形式。
现在Spring中定义一个Bean,我们就有了三种方式:
第一,通过XML配置文件的形式标签
第二,添加对应的注解和包扫描,@Component加包扫描
第三,JavaConfig形式,即@Configuration注解与@Bean注解
@Configuration的使用