spring-boot内置tomcat启动(四)

    1.上两编曲讲启动过程,好像并没有涉及到内置tomcat的启动,tomcat是怎么启动的呢?回去看看容器最先初始化的动作

        private void initialize(Object[] sources) {
            if (sources != null && sources.length > 0) {
                this.sources.addAll(Arrays.asList(sources));
            }
            //检测是否存在web环境
            this.webEnvironment = deduceWebEnvironment();
            setInitializers((Collection) getSpringFactoriesInstances(
                    ApplicationContextInitializer.class));
            setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
            this.mainApplicationClass = deduceMainApplicationClass();
        }
    
        private boolean deduceWebEnvironment() {
    // private static final String[] WEB_ENVIRONMENT_CLASSES = { "javax.servlet.Servlet",
    // "org.springframework.web.context.ConfigurableWebApplicationContext" };
            //判断以上两个类是否都存在,如果都存在,webEnviroment设为true
            for (String className : WEB_ENVIRONMENT_CLASSES) {
                if (!ClassUtils.isPresent(className, null)) {
                    return false;
                }
            }
            return true;
        }

    如果是webEnviroment环境又会怎么做呢?在SpringApplication.run方法中,最终可以跟到这么一段代码

    protected ConfigurableApplicationContext createApplicationContext() {
        Class<?> contextClass = this.applicationContextClass;
        if (contextClass == null) {
    
            try {
                //如果是web环境则创建AnnotationConfigEmbeddedWebApplicationContext,
                //否则创建AnnotationConfigApplicationContext
                contextClass = Class.forName(this.webEnvironment
                        ? DEFAULT_WEB_CONTEXT_CLASS : DEFAULT_CONTEXT_CLASS);
            }
            catch (ClassNotFoundException ex) {
                throw new IllegalStateException(
                        "Unable create a default ApplicationContext, "
                                + "please specify an ApplicationContextClass",
                        ex);
            }
        }
        return (ConfigurableApplicationContext) BeanUtils.instantiate(contextClass);
    }

    据AnnotationConfigEmbeddedWebApplicationContext名称可以看出这个是可web容器context,那么接下来就看该类及其相关父类就差不多了

    直接观察,发现tomcat的启动实现并没有在AnnotationConfigEmbeddedWebApplicationContext,而是在其上一及父类EmbeddedWebApplicationContext

    protected void onRefresh() {
        super.onRefresh();
        try {
            //观察不难发现,这里就是创建servlet容器的开始的地方
            createEmbeddedServletContainer();
        }
        catch (Throwable ex) {
            throw new ApplicationContextException("Unable to start embedded container",
                    ex);
        }
    }
    
    
    private void createEmbeddedServletContainer() {
        EmbeddedServletContainer localContainer = this.embeddedServletContainer;
        ServletContext localServletContext = getServletContext();
        if (localContainer == null && localServletContext == null) {
            //通过工厂模式,创建内置的servlet容器,他建完在哪里启动?大概跟applicationcontext生命周期方法就可以跟到了
            EmbeddedServletContainerFactory containerFactory = getEmbeddedServletContainerFactory();
            this.embeddedServletContainer = containerFactory
                    .getEmbeddedServletContainer(getSelfInitializer());
        }
        else if (localServletContext != null) {
            try {
                getSelfInitializer().onStartup(localServletContext);
            }
            catch (ServletException ex) {
                throw new ApplicationContextException("Cannot initialize servlet context",
                        ex);
            }
        }
        initPropertySources();
    }
    
    @Override
    protected void finishRefresh() {
        super.finishRefresh();
        //启动servlet容器,到此基本是tomcat启动全过程了
        EmbeddedServletContainer localContainer = startEmbeddedServletContainer();
        if (localContainer != null) {
            publishEvent(
                    new EmbeddedServletContainerInitializedEvent(this, localContainer));
        }
    }
        原文作者:Spring Boot
        原文地址: https://blog.csdn.net/yangyangiud/article/details/79797348
        本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
    点赞