延伸阅读:Spring Boot启动MVC的流程
main启动
SpringApplication
1
public ConfigurableApplicationContext run(String... args)try { //准备环境,并确认classpath是否拥有web环境 ConfigurableEnvironment environment = this.prepareEnvironment(listeners, applicationArguments); //... //根据当前环境创建Spring应用上下文 //web的则为(此处应为)o.s.b.c.e.AnnotationConfigEmbeddedWebApplicationContext //普通则为o.s.c.a.AnnotationConfigApplicationContext context = this.createApplicationContext(); //... //刷新Spring应用上下文--->2 this.refreshContext(context); //... } catch (Throwable var9) { //.. }2
private void refreshContext(ConfigurableApplicationContext context)
private void refreshContext(ConfigurableApplicationContext context) {
        this.refresh(context);
        if (this.registerShutdownHook) {
            try {
                context.registerShutdownHook();
            } catch (AccessControlException var3) {
                ;
            }
        }
    }
- 3
protected void refresh(ApplicationContext applicationContext) 
 protected void refresh(ApplicationContext applicationContext) {
    // 判断是否是AbstractApplicationContext的实例
     Assert.isInstanceOf(AbstractApplicationContext.class, applicationContext);
    // 上转,此处执行的是AnnotationConfigEmbeddedWebApplicationContext的父类的refresh
    ((AbstractApplicationContext)applicationContext).refresh();
    }
EmbeddedWebApplicationContext
- 1 执行父类
AbstractApplicationContext的refresh(),再该方法中执行到this.onRefresh();,再返回EmbeddedWebApplicationContext的onRefresh() 
protected void onRefresh() {
        super.onRefresh();
        try {
            //创建嵌入式servlet容器
            this.createEmbeddedServletContainer();
        } catch (Throwable var2) {
            throw new ApplicationContextException("Unable to start embedded container", var2);
        }
    }
- 2 
private void createEmbeddedServletContainer() 
private void createEmbeddedServletContainer() {
        //...
        if (localContainer == null && localServletContext == null) {
            //auto-configuration 已经给你配置好了EmbeddedServletContainerFactory 
            //默认使用Tomcat,则containerFactory为TomcatEmbeddedServletContainerFactory
            EmbeddedServletContainerFactory containerFactory = this.getEmbeddedServletContainerFactory();
            //此处传入一个只有一个o.s.b.w.s.ServletContextInitializer实现的内部类
            //ServletContextInitializer是用来配置ServletContext的
            this.embeddedServletContainer = containerFactory.getEmbeddedServletContainer(new ServletContextInitializer[]{this.getSelfInitializer()});
        }
        //...
}
private ServletContextInitializer getSelfInitializer() {
        return new ServletContextInitializer() {
            public void onStartup(ServletContext servletContext) throws ServletException {
                EmbeddedWebApplicationContext.this.selfInitialize(servletContext);
            }
        };
}
TomcatEmbeddedServletContainerFactory
由
EmbeddedServletContainerAutoConfiguration提供实例化
- 1 
public EmbeddedServletContainer getEmbeddedServletContainer(ServletContextInitializer... initializers)、 
public EmbeddedServletContainer getEmbeddedServletContainer(ServletContextInitializer... initializers) {
        /*配置tomcat,容器是层次结构的,最外层是tomcat,然后是server->service->host*/
        /*Server为StandardServer Service为StandardService Host为StandardHost*/
        Tomcat tomcat = new Tomcat();
        File baseDir = this.baseDirectory != null ? this.baseDirectory : this.createTempDir("tomcat");
        tomcat.setBaseDir(baseDir.getAbsolutePath());
        Connector connector = new Connector(this.protocol);
        tomcat.getService().addConnector(connector);
        this.customizeConnector(connector);
        tomcat.setConnector(connector);
        tomcat.getHost().setAutoDeploy(false);
        this.configureEngine(tomcat.getEngine());
        Iterator var5 = this.additionalTomcatConnectors.iterator();
        while(var5.hasNext()) {
            Connector additionalConnector = (Connector)var5.next();
            tomcat.getService().addConnector(additionalConnector);
        }
        /*配置tomcat结束*/
        this.prepareContext(tomcat.getHost(), initializers);
        return this.getTomcatEmbeddedServletContainer(tomcat);
    }
- 2 
protected void prepareContext(Host host, ServletContextInitializer[] initializers) 
protected void prepareContext(Host host, ServletContextInitializer[] initializers) {
        /*配置context,相当于server.xml文件中<engine>-><host>-><context>节点*/
        File docBase = this.getValidDocumentRoot();
        docBase = docBase != null ? docBase : this.createTempDir("tomcat-docbase");
        //注意 context类型为 TomcatEmbeddedContext 
        final TomcatEmbeddedContext context = new TomcatEmbeddedContext();
        context.setName(this.getContextPath());
        context.setDisplayName(this.getDisplayName());
        context.setPath(this.getContextPath());
        context.setDocBase(docBase.getAbsolutePath());
        context.addLifecycleListener(new FixContextListener());
        context.setParentClassLoader(this.resourceLoader != null ? this.resourceLoader.getClassLoader() : ClassUtils.getDefaultClassLoader());
        this.resetDefaultLocaleMapping(context);
        this.addLocaleMappings(context);
        //...
        /**配置context结束*/
        //将传入的ServletContextInitializer(EmbeddedWebApplicationContext的一个匿名内部类)与初始化TomcatEmbeddedServletContainerFactory时传入的ServletContextInitializer进行整合(ServerProperties.SessionConfiguringInitializer和InitParameterConfiguringServletContextInitializer)
        // 以上两个ServletContextInitializer来自于ServerProperties,
        // ServerProperties的bean由ServerPropertiesAutoConfiguration自动产生,由于ServerProperties实现了EmbeddedServletContainerCustomizer接口,内部的customize方法将由IoC框架执行
        ServletContextInitializer[] initializersToUse = this.mergeInitializers(initializers);
        //调用下文---->3
        this.configureContext(context, initializersToUse);
        //context配置完后,添加到host的子中
        host.addChild(context);
        this.postProcessContext(context);
}
protected final ServletContextInitializer[] mergeInitializers(ServletContextInitializer... initializers) {
        List<ServletContextInitializer> mergedInitializers = new ArrayList();
        mergedInitializers.addAll(Arrays.asList(initializers));
        mergedInitializers.addAll(this.initializers);
        return (ServletContextInitializer[])mergedInitializers.toArray(new ServletContextInitializer[mergedInitializers.size()]);
}
3
protected void configureContext(Context context, ServletContextInitializer[] initializers)protected void configureContext(Context context, ServletContextInitializer[] initializers) { //创建一个TomcatStarter来包裹ServletContextInitializer //TomcatStarter实现了ServletContainerInitializer接口 //以后会在其onStartup中调用ServletContextInitializer的onStartup //相当于容器的初始化器,会初始化ServletContext TomcatStarter starter = new TomcatStarter(initializers); //将容器的初始化器TomcatStarter 添加给TomcatEmbeddedContext(server.xml里的<context>,对应一个应用) context.addServletContainerInitializer(starter, NO_CLASSES); //做更详细的配置 }4
protected TomcatEmbeddedServletContainer getTomcatEmbeddedServletContainer(Tomcat tomcat)
执行完3后,一层层返回,最后回到1,然后调用4这个方法
protected TomcatEmbeddedServletContainer getTomcatEmbeddedServletContainer(Tomcat tomcat) {
        return new TomcatEmbeddedServletContainer(tomcat, this.getPort() >= 0);
    }
TomcatEmbeddedServletContainer
- 1 
public TomcatEmbeddedServletContainer(Tomcat tomcat, boolean autoStart)调用构造函数 - 2  
private void initialize() throws EmbeddedServletContainerException构造函数内,执行了此方法 
private void initialize() throws EmbeddedServletContainerException {
//这一步算是完成了tomcat的初始化了
logger.info("Tomcat initialized with port(s): " + this.getPortsDescription(false));
        Object var1 = this.monitor;
        synchronized(this.monitor) {
            try {
                this.addInstanceIdToEngineName();
                try {
                    this.removeServiceConnectors();
                    //启动tomcat
                    this.tomcat.start();
                    this.rethrowDeferredStartupExceptions();
                    Context context = this.findContext();
                    try {
                        ContextBindings.bindClassLoader(context, this.getNamingToken(context), this.getClass().getClassLoader());
                    } catch (NamingException var5) {
                        ;
                    }
                    this.startDaemonAwaitThread();
                } catch (Exception var6) {
                    containerCounter.decrementAndGet();
                    throw var6;
                }
            } catch (Exception var7) {
                throw new EmbeddedServletContainerException("Unable to start embedded Tomcat", var7);
            }
        }
}
StandardServer StandardService StandardEngine
依次调用StandardServer.start()->LifecycleBase.start()->StandardServer.startInternal()
-> StandardService.start()->LifecycleBase.start()->StandardService.startInternal()
-> StandardService.start()->LifecycleBase.start()->StandardService.startInternal()
-> StandardEngine.start()->LifecycleBase.start()->StandardEngine.startInternal()->ContainerBase.startInternal()
- 1 
ContainerBase.startInternal() 
protected synchronized void startInternal() throws LifecycleException {
 Container[] children = this.findChildren();
         //...
         //children 为StandardEngine的children ,当前只有一个StandardHost
         Container[] children = this.findChildren();
         List<Future<Void>> results = new ArrayList();
        //为每个host启动一个进程,使用future模型,可以回掉的
        for(int i = 0; i < children.length; ++i) {
            results.add(this.startStopExecutor.submit(new ContainerBase.StartChild(children[i])));
        }
        boolean fail = false;
        Iterator i$ = results.iterator();
        while(i$.hasNext()) {
            Future result = (Future)i$.next();
            try {
               //启动future,调用StandardHost的start方法
                result.get();
            } catch (Exception var9) {
                log.error(sm.getString("containerBase.threadedStartFailed"), var9);
                fail = true;
            }
        }
        //...
}
-> StandardHost.start()->LifecycleBase.start()->StandardHost.startInternal()->ContainerBase.startInternal()
同理启动-> TomcatEmbeddedContext .start()->LifecycleBase.start()->TomcatEmbeddedContext .startInternal()
- 2 
TomcatEmbeddedContext protected synchronized void startInternal() throws LifecycleException 
protected synchronized void startInternal() throws LifecycleException {
            //...
            /*挨个启动之前放在TomcatStart里的ServletContainerInitializer*/
            Iterator i$ = this.initializers.entrySet().iterator();
            while(i$.hasNext()) {
                Entry entry = (Entry)i$.next();
                try {
                    ((ServletContainerInitializer)entry.getKey()).onStartup((Set)entry.getValue(), this.getServletContext());
                } catch (ServletException var22) {
                    log.error(sm.getString("standardContext.sciFail"), var22);
                    ok = false;
                    break;
                }
            }
            //...
}
综上完成全部内容