创建SpringBoot项目
pom.xml 文件
xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.1.2</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>3.1.0</version>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
启动程序类【DemoApplication】
java
package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
// @param args JAR运行时传入的自定义参数
SpringApplication.run(DemoApplication.class, args);
}
}
java
public static ConfigurableApplicationContext run(Class<?>[] primarySources, String[] args) {
return new SpringApplication(primarySources).run(args);
}
SpringBootApplication复合注解
【自动配置Bean】@EnableAutoConfiguration,对start依赖包中被@Configuration注解修饰的类进行自动装配
【自动扫描Bean】@ComponentScan自动扫描DemoApplication启动类同级目录下的所有符合条件的组件
【基于JavaConfig创建Bean】@SpringBootConfiguration等同于@Configuration,将当前类标记为配置类并加载到容器
- 创建 SpringApplication 对象
初始化 SpringApplication对象的相关变量
java
public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
// 【添加资源加载器】ResourceLoader接口实例对象
this.resourceLoader = resourceLoader;
// 【设置主方法类】当前SpringBoot应用启动类的class对象
Assert.notNull(primarySources, "PrimarySources must not be null");
this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));
// 推断应用类型:SERVLET、REACTIVE、NONE,默认SERVLET类型
this.webApplicationType = WebApplicationType.deduceFromClasspath();
// 初始化bootstrapRegistryInitializers变量
// private final List<BootstrapRegistryInitializer> bootstrapRegistryInitializers;
this.bootstrapRegistryInitializers =
new ArrayList<>(getSpringFactoriesInstances(BootstrapRegistryInitializer.class));
// 初始initializers变量
// private List<ApplicationContextInitializer<?>> initializers;
setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));
// 初始化listeners变量
// private List<ApplicationListener<?>> listeners;
setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
// 推断当前main方法所属的类的类型:SpringBoot启动类
this.mainApplicationClass = deduceMainApplicationClass();
}
- 通过run方法创建 ConfigurableApplicationContext 对象
java
/**
* Run the Spring application, creating and refreshing a new {@link ApplicationContext}.
* @param args the application arguments (usually passed from a Java main method)
* @return a running {@link ApplicationContext}
*/
public ConfigurableApplicationContext run(String... args) {
long startTime = System.nanoTime();
// 创建 启动上下文 对象
DefaultBootstrapContext bootstrapContext = createBootstrapContext();
// 允许无输入设备也可以启动服务
configureHeadlessProperty();
// 获取 SpringApplicationRunListeners 监听器并启动,启动流程中接收不同执行事件通知的监听者
// SpringApplicationRunListener接口规定了SpringBoot的生命周期,在各个生命周期广播相应事件,调用实际的ApplicationListener类
SpringApplicationRunListeners listeners = getRunListeners(args);
listeners.starting(bootstrapContext, this.mainApplicationClass);
ConfigurableApplicationContext context = null;
try {
// 初始化自定义启动参数
ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
// 准备运行环境
ConfigurableEnvironment environment = prepareEnvironment(listeners, bootstrapContext, applicationArguments);
Banner printedBanner = printBanner(environment);
// 创建Spring容器
context = createApplicationContext();
context.setApplicationStartup(this.applicationStartup);
// Spring容器前置处理
prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner);
// 刷新Spring容器
refreshContext(context);
// Spring容器后置处理
afterRefresh(context, applicationArguments);
Duration timeTakenToStartup = Duration.ofNanos(System.nanoTime() - startTime);
if (this.logStartupInfo) {
new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), timeTakenToStartup);
}
// 启动完成事件
listeners.started(context, timeTakenToStartup);
// 回调自定义实现的Runner接口,处理一些执行后的定制化需求
callRunners(context, applicationArguments);
} catch (Throwable ex) {
if (ex instanceof AbandonedRunException) {
throw ex;
}
handleRunFailure(context, ex, listeners);
throw new IllegalStateException(ex);
}
try {
if (context.isRunning()) {
Duration timeTakenToReady = Duration.ofNanos(System.nanoTime() - startTime);
listeners.ready(context, timeTakenToReady);
}
} catch (Throwable ex) {
if (ex instanceof AbandonedRunException) {
throw ex;
}
handleRunFailure(context, ex, null);
throw new IllegalStateException(ex);
}
return context;
}