当前位置: 首页>后端>正文

tomcat(7)加载spring项目

tomcat的启动过程就是
脚本->catalina.jar->catalina->standardServer->standardService->standardEngine(Catalina加载web组件)/connector(启动监听请求)
我们发布到tomcat webapp下的项目将会在Engine中加载,下面说说加载过程

先是解析过程,在engine启动时,有一步 findChildren找到Catalina的子容器 StandardHost[localhost],在这里开启了一个线程池 startStopExecutor,这个只有一个核心线程,也就是说我们的StandardHost加载时是串行加载的

StandardHost中的start()方法就从这个线程池开始异步执行,传入了不同的context,可以看成webapp下的项目参数

public void start() {

        if (log.isDebugEnabled()) {
            log.debug(sm.getString("hostConfig.start"));
        }

        try {
            ObjectName hostON = host.getObjectName();
            oname = new ObjectName
                (hostON.getDomain() + ":type=Deployer,host=" + host.getName());
            Registry.getRegistry(null, null).registerComponent
                (this, oname, this.getClass().getName());
        } catch (Exception e) {
            log.warn(sm.getString("hostConfig.jmx.register", oname), e);
        }

        if (!host.getAppBaseFile().isDirectory()) {
            log.error(sm.getString("hostConfig.appBase", host.getName(),
                    host.getAppBaseFile().getPath()));
            host.setDeployOnStartup(false);
            host.setAutoDeploy(false);
        }

        if (host.getDeployOnStartup()) {
            deployApps();
        }
    }
···

hostConfig/contextConfig 继承了 LifecycleListener ,在项目启动早些时候解析server.xml时 digester中加入了两个监听器

在host和context启动时会触发响应的事件,hostConfig#start方法会启动一个线程池执行的子类DeployDirectory#run方法中调用了deployDirectory方法,向host和context注入子类并启动,前面的组件都是在tomcat中配好的,从这里开始就跟我们的开发部署相关了,在context的 LifecycleListener 启动中configureStart()方法被调用,其中最重要的方法就是webConfig()

protected synchronized void configureStart() {
// Called from StandardContext.start()

    if (log.isDebugEnabled()) {
        log.debug(sm.getString("contextConfig.start"));
    }

    if (log.isDebugEnabled()) {
        log.debug(sm.getString("contextConfig.xmlSettings",
                context.getName(),
                Boolean.valueOf(context.getXmlValidation()),
                Boolean.valueOf(context.getXmlNamespaceAware())));
    }

    webConfig();

    if (!context.getIgnoreAnnotations()) {
        applicationAnnotationsConfig();
    }
    if (ok) {
        validateSecurityRoles();
    }

    // Configure an authenticator if we need one
    if (ok) {
        authenticatorConfig();
    }

    // Dump the contents of this pipeline if requested
    if (log.isDebugEnabled()) {
        log.debug("Pipeline Configuration:");
        Pipeline pipeline = context.getPipeline();
        Valve valves[] = null;
        if (pipeline != null) {
            valves = pipeline.getValves();
        }
        if (valves != null) {
            for (Valve valve : valves) {
                log.debug("  " + valve.getClass().getName());
            }
        }
        log.debug("======================");
    }

    // Make our application available if no problems were encountered
    if (ok) {
        context.setConfigured(true);
    } else {
        log.error(sm.getString("contextConfig.unavailable"));
        context.setConfigured(false);
    }

}
webConfig就是解析context项目的web.xml方法,该方法将系统默认的参数先创建好,然后调用merge方法将项目启动的所有参数加载
在解析web.xml的过程中,会解析listener标签,将其中的监听器注册到context里面

for (String listener : listeners) {
context.addApplicationListener(listener);
}

随后standardContext在 listenerStart()方法中启动了listener,监听器调用了contextInitialized方法,以ContextLoaderListener为例,使用了contextLoader#initWebApplicationContext(event.getServletContext())方法就启动了spring容器

**整个过程就是,tomcat组件的启动,加载配置文件web.xml,从配置文件中获取监听器注册应用监听,事件触发启动spring,然后再spring容器中解析spring-configloaction,加载spring组件**

https://www.xamrdz.com/backend/3k41920646.html

相关文章: