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 配置文件
1
2
3
4
5
6
7
8
9
10
11
12
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...");
    }
}

  配置

1
2
org.springframework.context.ApplicationContextInitializer=\
com.application.MyApplicationContextInitializer

  

4、加载所有的监听器
配置在spring-boot-autoconfigure 和 spring-boot 的spring.factories里
监听器加载的是实现了ApplicationListener 接口的类


5 设置运行的主类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
--- 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 接口的类

自定义异常报告器
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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;
    }
}

  配置

1
2
org.springframework.boot.SpringBootExceptionReporter=\
com.baoyun.iyb.config.application.MyExceptionReporter

 

* 执行自定义的run方法
1。实现 ApplicationRunner 接口
2。实现 CommandLineRunner 接口
com.init.MyRunner
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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 接口既可运行"        );
    }
}

  



posted @   hy叶子  阅读(89)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
点击右上角即可分享
微信分享提示