zoukankan      html  css  js  c++  java
  • springboot如何一步步启动内置的tomcat(工厂模式的典型应用)

    下面跟随源码一步步找到如何启动内置的tomcat(springboot版本为2.1.2):

    1、启动类

    @EnableTransactionManagement
    @SpringBootApplication(exclude = { DataSourceAutoConfiguration.class })
    public class RuoYiApplication
    {
        public static void main(String[] args)
        {
            SpringApplication.run(RuoYiApplication.class, args);
        }
    }

    2、跟入run方法:

    public static ConfigurableApplicationContext run(Class<?> primarySource,
                String... args) {
            return run(new Class<?>[] { primarySource }, args);
        }
    public static ConfigurableApplicationContext run(Class<?>[] primarySources,
                String[] args) {
            return new SpringApplication(primarySources).run(args);
        }
    public ConfigurableApplicationContext run(String... args) {
                ...
                refreshContext(context);
                ...
        }

    3、跟入refreshContext方法:

    private void refreshContext(ConfigurableApplicationContext context) {
            refresh(context);
            if (this.registerShutdownHook) {
                try {
                    context.registerShutdownHook();
                }
                catch (AccessControlException ex) {
                    // Not allowed in some environments.
                }
            }
        }
    protected void refresh(ApplicationContext applicationContext) {
            Assert.isInstanceOf(AbstractApplicationContext.class, applicationContext);
            ((AbstractApplicationContext) applicationContext).refresh();
        }
    public void refresh() throws BeansException, IllegalStateException {
                    ...
                    // Initialize other special beans in specific context subclasses.
                    onRefresh();
                    ...
        }

    4、进入子类(ServletWebServerApplicationContext)的onRefresh方法:

        @Override
        protected void onRefresh() {
            super.onRefresh();
            try {
                createWebServer();
            }
            catch (Throwable ex) {
                throw new ApplicationContextException("Unable to start web server", ex);
            }
        }

    5、进入createWebServer方法:

        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();
        }

    6、进入getWebServerFactory方法:

    protected ServletWebServerFactory getWebServerFactory() {
            // Use bean names so that we don't consider the hierarchy
            String[] beanNames = getBeanFactory()
                    .getBeanNamesForType(ServletWebServerFactory.class);
            if (beanNames.length == 0) {
                throw new ApplicationContextException(
                        "Unable to start ServletWebServerApplicationContext due to missing "
                                + "ServletWebServerFactory bean.");
            }
            if (beanNames.length > 1) {
                throw new ApplicationContextException(
                        "Unable to start ServletWebServerApplicationContext due to multiple "
                                + "ServletWebServerFactory beans : "
                                + StringUtils.arrayToCommaDelimitedString(beanNames));
            }
            return getBeanFactory().getBean(beanNames[0], ServletWebServerFactory.class);
        }

    7、springboot中默认注入了tomcat的工厂,即TomcatServletWebServerFactory,继续,进入factory.getWebServer(getSelfInitializer()):

    public WebServer getWebServer(ServletContextInitializer... initializers) {
            Tomcat tomcat = new Tomcat();
            File baseDir = (this.baseDirectory != null) ? this.baseDirectory
                    : createTempDir("tomcat");
            tomcat.setBaseDir(baseDir.getAbsolutePath());
            Connector connector = new Connector(this.protocol);
            tomcat.getService().addConnector(connector);
            customizeConnector(connector);
            tomcat.setConnector(connector);
            tomcat.getHost().setAutoDeploy(false);
            configureEngine(tomcat.getEngine());
            for (Connector additionalConnector : this.additionalTomcatConnectors) {
                tomcat.getService().addConnector(additionalConnector);
            }
            prepareContext(tomcat.getHost(), initializers);
            return getTomcatWebServer(tomcat);
        }

    8、最终返回TomcatWebServer。

    总结:

    基本启动流程如上所述。

    另外获取server工厂,并使用具体的工厂创建tomcatserver的方式是一个典型的工厂设计模式。

  • 相关阅读:
    P1378 油滴扩展
    P1219 [USACO1.5]八皇后 Checker Challenge
    P1126 机器人搬重物
    Mac鼠标和触控板完美使用
    B词
    一个开发狗的时间线
    快速排序
    TikTok直播研发校招专属内推
    Jupyter Lab + anaconda 环境搭建
    React环境搭建
  • 原文地址:https://www.cnblogs.com/silenceshining/p/14924842.html
Copyright © 2011-2022 走看看