springboot中如何啟動tomcat


springboot啟動時,會自動識別出當前環境是否是web環境還是非web環境。

默認的web環境的context(DEFAULT_WEB_CONTEXT_CLASS):org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext
默認的非web環境的context(
DEFAULT_CONTEXT_CLASS):org.springframework.context.annotation.AnnotationConfigApplicationContext

以下代碼為springboot啟動類springApplication創建context代碼:
ConfigurableApplicationContext org.springframework.boot.SpringApplication.createApplicationContext():
 
        
    /**
     * Strategy method used to create the {@link ApplicationContext}. By default this
     * method will respect any explicitly set application context or application context
     * class before falling back to a suitable default.
     * @return the application context (not yet refreshed)
     * @see #setApplicationContextClass(Class)
     */
    protected ConfigurableApplicationContext createApplicationContext() {
        Class<?> contextClass = this.applicationContextClass;
        if (contextClass == null) {
            try {
                switch (this.webApplicationType) {
                case SERVLET:
                    contextClass = Class.forName(DEFAULT_WEB_CONTEXT_CLASS);
                    break;
                case REACTIVE:
                    contextClass = Class.forName(DEFAULT_REACTIVE_WEB_CONTEXT_CLASS);
                    break;
                default:
                    contextClass = Class.forName(DEFAULT_CONTEXT_CLASS);
                }
            }
            catch (ClassNotFoundException ex) {
                throw new IllegalStateException(
                        "Unable create a default ApplicationContext, "
                                + "please specify an ApplicationContextClass",
                        ex);
            }
        }
        return (ConfigurableApplicationContext) BeanUtils.instantiateClass(contextClass);
    }

 

那么我們來詳細看下默認的web環境的AnnotationConfigServletWebServerApplicationContext的具體實現:

public class AnnotationConfigServletWebServerApplicationContext extends ServletWebServerApplicationContext implements AnnotationConfigRegistry

發現AnnotationConfigServletWebServerApplicationContext繼承了org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext,

我們看AnnotationConfigServletWebServerApplicationContext的代碼,發現並沒有和webServer(tomcat,jetty....)相關的代碼。那么我們繼續來看下父類ServletWebServerApplicationContext的實現:

ServletWebServerApplicationContext:發現這個類是boot包下的,繼承了GenericWebApplicationContext是spring-web這個jar包,推斷springboot嵌入webServer的邏輯很有可能是在這個ServletWebServerApplicationContext

類結構:public class ServletWebServerApplicationContext extends GenericWebApplicationContext implements ConfigurableWebServerApplicationContext

 

我們終於在org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext看到了和webServer相關的代碼:

    @Override
    protected void onRefresh() {
        super.onRefresh();
        try {
            createWebServer();
        }
        catch (Throwable ex) {
            throw new ApplicationContextException("Unable to start web server", ex);
        }
    }
@Override
    protected void finishRefresh() {
        super.finishRefresh();
        WebServer webServer = startWebServer();
        if (webServer != null) {
            publishEvent(new ServletWebServerInitializedEvent(webServer, this));
        }
    }

 

其中onRefresh方法會在void org.springframework.context.support.AbstractApplicationContext.refresh() 中會在context注冊BeanFactoryPostProcessor、執行BeanFactoryPostProcessor、注冊BeanPostProcessor之后調用,

finishRefresh方法會在void org.springframework.context.support.AbstractApplicationContext.finishRefresh()中會在context完成各種初始化(初始化bean)后被調用到,從而在context啟動完成后,啟動WebServer(tomcat、jetty)...

 

接下來我們看下創建WebServer和啟動WebServer的邏輯:

private void createWebServer() {
        WebServer webServer = this.webServer;
        ServletContext servletContext = getServletContext();
        if (webServer == null && servletContext == null) {
            ServletWebServerFactory factory = getWebServerFactory();
            this.webServer = factory.getWebServer(getSelfInitializer());
        }
        else if (servletContext != null) {
            try {
                getSelfInitializer().onStartup(servletContext);
            }
            catch (ServletException ex) {
                throw new ApplicationContextException("Cannot initialize servlet context",
                        ex);
            }
        }
        initPropertySources();
    }

 

private WebServer startWebServer() {
        WebServer webServer = this.webServer;
        if (webServer != null) {
            webServer.start();
        }
        return webServer;
    }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM