spring-boot启动源码
1 运行SpringApplication.run()方法
--- org.springframework.boot.SpringApplication.SpringApplication(org.springframework.core.io.ResourceLoader, java.lang.Class<?>...)
2 确定应用程序类型
this.webApplicationType = WebApplicationType.deduceFromClasspath();
3 加载所有的初始化器
配置在spring-boot-autoconfigure 和 spring-boot 的spring.factories里
自定义初始化器:
a)实现 ApplicationContextInitializer接口 b)META-INF/spring.factories 配置文件
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.ConfigurableApplicationContext;
/**
* 初始化器
*/
public class MyApplicationContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
@Override
public void initialize(ConfigurableApplicationContext configurableApplicationContext) {
System.out.println("我是初始化的 MyApplicationContextInitializer...");
}
}
配置
org.springframework.context.ApplicationContextInitializer=\ com.application.MyApplicationContextInitializer
4、加载所有的监听器
配置在spring-boot-autoconfigure 和 spring-boot 的spring.factories里
监听器加载的是实现了ApplicationListener 接口的类
5 设置运行的主类
--- org.springframework.boot.SpringApplication.run(java.lang.String...)
public ConfigurableApplicationContext run(String... args) {
//开启计时器
StopWatch stopWatch = new StopWatch();
stopWatch.start();
ConfigurableApplicationContext context = null;
Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();
configureHeadlessProperty();
//获取并启动监听器
SpringApplicationRunListeners listeners = getRunListeners(args);
listeners.starting();
try {
//设置应用程序参数,main方法里面执行静态run方法传入的参数
ApplicationArguments applicationArguments = new DefaultApplicationArguments(
args);
//准备环境变量,将maven和系统的环境变量都加载进来了
ConfigurableEnvironment environment = prepareEnvironment(listeners,
applicationArguments);
configureIgnoreBeanInfo(environment);
Banner printedBanner = printBanner(environment);
//反射创建应用程序上下文
context = createApplicationContext();
//*实例化异常报告器。自定义异常报告器:继承 SpringBootExceptionReporter 接口
//*1 开启异常报警器
exceptionReporters = getSpringFactoriesInstances(
SpringBootExceptionReporter.class,
new Class[] { ConfigurableApplicationContext.class }, context);
//*2 以下代码中发生异常都会执行异常报警器
//准备上下文环境,为下一步刷新作准备:postProcessApplicationContext、applyInitializers、registerSingleton
prepareContext(context, environment, listeners, applicationArguments,
printedBanner);
//刷新上下文,属于spring范畴,自动装配和启动tomcat
refreshContext(context);
//后置处理,留给用户扩展使用
afterRefresh(context, applicationArguments);
//结束计时器
stopWatch.stop();
if (this.logStartupInfo) {
new StartupInfoLogger(this.mainApplicationClass)
.logStarted(getApplicationLog(), stopWatch);
}
//发布上下文准备就绪事件
listeners.started(context);
//扩展功能,启动自定义的run方法
callRunners(context, applicationArguments);
}
catch (Throwable ex) {
//3 捕获异常并调用异常报警器方法
handleRunFailure(context, ex, exceptionReporters, listeners);
throw new IllegalStateException(ex);
}
try {
listeners.running(context);
}
catch (Throwable ex) {
handleRunFailure(context, ex, exceptionReporters, null);
throw new IllegalStateException(ex);
}
return context;
}
* 自定义异常报告器
配置在spring.factories里
监听器加载的是实现了 SpringBootExceptionReporter 接口的类
自定义异常报告器
import org.springframework.boot.SpringBootExceptionReporter;
import org.springframework.context.ConfigurableApplicationContext;
public class MyExceptionReporter implements SpringBootExceptionReporter {
private ConfigurableApplicationContext context;
// 必须要有一个有参的构造函数,否则启动会报错
MyExceptionReporter(ConfigurableApplicationContext context) {
this.context = context;
}
@Override
public boolean reportException(Throwable failure) {
System.out.println("进入异常报告器");
failure.printStackTrace();
// 返回false会打印详细springboot错误信息,返回true则只打印异常信息
return false;
}
}
配置
org.springframework.boot.SpringBootExceptionReporter=\ com.baoyun.iyb.config.application.MyExceptionReporter
* 执行自定义的run方法
1。实现 ApplicationRunner 接口
2。实现 CommandLineRunner 接口
com.init.MyRunner
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.boot.CommandLineRunner;
public class MyRunner implements ApplicationRunner, CommandLineRunner {
@Override
public void run(ApplicationArguments args) throws Exception {
System.out.println(" 我是自定义的run方法1,实现 ApplicationRunner 接口既可运行" );
}
@Override
public void run(String... args) throws Exception {
System.out.println(" 我是自定义的run方法2,实现 CommandLineRunner 接口既可运行" );
}
}

浙公网安备 33010602011771号