Spring Boot 的启动流程 Run方法

Spring Boot 的启动流程

1 - 先简单介绍一下run方法的过程

// 在spring boot中run方法才是启动应用的实际方法 最终返回的是一个ConfigurableApplicationContext容器
ConfigurableApplicationContext context = SpringApplication.run(SpringbootdemoApplication.class, args);
// 在run方法中 创建了容器 并作了一系列的初始化处理
context = createApplicationContext(); // 创建一个容器对象
context.setApplicationStartup(this.applicationStartup);// 创建一个应用程序监视器
prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner);// 准备上下文
refreshContext(context);// 刷新上下文 
afterRefresh(context, applicationArguments);// 上下文刷新后

2 -- 首先是 createApplicationContext() 创建一个容器

// 通过调试可以看到最终返回的是 实现了它的 AnnotationConfigServletWebServerApplicationContext web容器
// 之所以是 AnnotationConfigServletWebServerApplicationContext 也是有选择的 在run方法创建应用容器的时候 根据应用类型来进行创建
switch (webApplicationType) {// 根据的应用程序的类型来进行选择的 webApplicationType
    case SERVLET:
        return new AnnotationConfigServletWebServerApplicationContext();
    case REACTIVE:
        return new AnnotationConfigReactiveWebServerApplicationContext();
    default:
        return new AnnotationConfigApplicationContext();
}

// 首先进入的是 AnnotationConfigServletWebServerApplicationContext 的构造方法
public AnnotationConfigServletWebServerApplicationContext() {
    this.reader = new AnnotatedBeanDefinitionReader(this); // 首先创建了一个Bean定义阅读器
    this.scanner = new ClassPathBeanDefinitionScanner(this);// 然后创建了一个Bean扫描器
}// 初次之外没做别的了

3 -- 其次是 refreshContext(context); 刷新上下文

// 可以看出来 refreshContext 实际上就是调用的容器的refresh方法
private void refreshContext(ConfigurableApplicationContext context) {
    if (this.registerShutdownHook) {
        try {
            context.registerShutdownHook();
        }
        catch (AccessControlException ex) {
            // Not allowed in some environments.
        }
    }
    refresh(context);
}
protected void refresh(ConfigurableApplicationContext applicationContext) {
    applicationContext.refresh();
}
// 而AnnotationConfigServletWebServerApplicationContext 中没有 refresh方法
// 所以实际上refreshContext调用的是ServletWebServerApplicationContext的refresh方法
// 而ServletWebServerApplicationContext也并没有refresh方法
public final void refresh() throws BeansException, IllegalStateException {
    try {
        super.refresh();
    }
    catch (RuntimeException ex) {
        WebServer webServer = this.webServer;
        if (webServer != null) {
            webServer.stop();
        }
        throw ex;
    }
}// 最终调用的还是 老朋友 ApplicationContext 的refresh (refresh 方法就不同介绍了吧)

到此为止 run方法中需要着重介绍的东西也就没了

简单整理一下:其实spring boot的启动流程就是一个创建容器的过程

下面就是根据这个过程整理的一个简单的流程图:

posted @ 2021-09-02 00:28  熏晴微穗  阅读(858)  评论(1编辑  收藏  举报