Spring Boot是基于规约的开发方式,本文以Spring Boot 3.2.9对其进行源码解析。
1 环境准备
JDK:OpenJDK 17 下载地址:Java Platform, Standard Edition 17 ReferenceImplementations
Maven:3.9.9 下载地址:Download Apache Maven – Maven
Spring Boot:3.2.9 源码下载(GitCode镜像):GitCode - 全球开发者的开源社区,开源代码托管平台
2 启动和配置
Spring Boot是基于规约的开发方式,启动和配置都非常简单,不需要像传统Spring进行大量的配置。
pom文件的配置:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>${spring-boot.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>${spring-boot.version}</version>
</dependency>
application.yml配置:
server:
port: 8810
servlet:
context-path: /demo-server
Spring Boot启动类:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@SpringBootApplication
@EnableDiscoveryClient
public class ServerApplication {
public static void main(String[] args) {
SpringApplication.run(ServerApplication.class, args);
}
}
Spring Boot启动的核心就是@SpringBootApplication注解和SpringApplication.run()方法。
3 @SpringBootApplication注解
@SpringBootApplication是Spring Boot的一个组合注解,用于标记一个类为 Spring Boot的主配置类,并启用自动配置、组件扫描等功能,使得 Spring Boot 能够自动构建应用上下文并管理 Bean。
查看@SpringBootApplication注解类源码,里面包含注解:
-
@SpringBootConfiguration:表示这是一个配置类,Spring容器会处理这个类中的Bean定义;
-
@EnableAutoConfiguration:启用Spring Boot的自动配置机制;
-
@ComponentScan:自动扫描并注册Bean。默认会扫描当前主类所在包及其子包下的所有带有以下注解的类:@Component、@Service、@Repository、@Controller、@RestController等。
3.1 @EnableAutoConfiguration注解
@EnableAutoConfiguration注解有2个主要作用:
-
通过@AutoConfigurationPackage注解标记需要被自动注册的配置包;
-
通过@Import注解导入AutoConfigurationImportSelector类,负责Spring Boot中所有自动配置类的加载。
3.1.1 @AutoConfigurationPackage注解
@AutoConfigurationPackage注解通过@Import导入AutoConfigurationPackages.Registrar类,将自动注册包路径信息进行注册。
自动注册包路径优先取注解属性basePackages的值,如果取不到,默认取主类所在的包路径,对主类所在的包及其子包下的组件自动注册为Bean。这也是一般@SpringBootApplication注解都没配置basePackages属性的原因。
3.1.2 AutoConfigurationImportSelector类
AutoConfigurationImportSelector类负责加载Spring Boot中的所有自动配置类,从META-INF/spring/*.imports文件中读取所有配置好的自动配置类。
查看AutoConfigurationImportSelector的内部类AutoConfigurationGroup的process方法,跟踪自动配置类的读取。
注意:Spring Boot从3.2.X版本使用META-INF/spring/*.imports的方式读取自动类配置文件,默认不再支持早期的META-INF/spring.factories文件读取,如果过渡阶段仍然需要从spring.factories文件读取,可通过spring-boot-properties-migrator启用。
4 SpringApplication.run()方法
4.1 SpringApplication构造方法
SpringApplication构造方法主要初始化应用加载类型、bootstrapRegistryInitializers、initializers、listeners。
初始化应用加载类型:通过判断加载的jar中是否包含对应启动类来识别应用加载类型。
跟踪getSpringFactoriesInstances方法的源码可以发现,bootstrapRegistryInitializers、initializers、listeners的配置都是在META-INF/spring.factories文件里面。
4.2 SpringApplication.run()方法
SpringApplication.run()方法的主要作用:
-
初始化启动环境
-
创建并准备 Spring 应用上下文(ApplicationContext)
-
刷新上下文(加载 Bean 定义并初始化 Bean)
-
调用 ApplicationRunner 和 CommandLineRunner
-
通知监听器整个启动过程完成
Spring Boot应用启动早期阶段(创建ApplicationContext之前),通过BootstrapRegistryInitializer提前注册一些必要的组件或配置(例如:配置属性、条件评估缓存、自定义的BeanDefinition或BeanFactoryPostProcessor、外部配置的位置解析器等),为后续的 ApplicationContext 初始化做准备。
Spring Boot通过SpringApplicationRunListener进行启动时不同阶段的事件发布,包括starting、environmentPrepared、contextPrepared、contextLoaded、ready等。默认通过EventPublishingRunListener加载监听器。
SpringApplication.run()里面最核心的是refreshContext(context),本质上调用的是Spring Framework的方法,Web应用调用的是ServletWebServerApplicationContext的refresh方法。执行的事项包括:
-
加载Bean定义(BeanDefinition)
-
实例化单例Bean
-
自动装配依赖
-
调用Aware接口回调
-
初始化Bean(init-method)
-
发布ContextRefreshedEvent
总结
通过阅读Spring Boot的源码可以清晰地看到:Spring Boot是以Spring Framework为核心,Spring应用在启动前按照约定的格式进行文件解析,进行环境准备。以此来简化项目开发配置。