tomcat源码研读笔记—tomcat的启动之五 StandardContext的启动

我们首先看下StandardContext的继承关系:


然后查看starndardContext的start方法源码:

public synchronized void start() throwsLifecycleException {

       if (started)

           throw new LifecycleException

               (sm.getString("containerBase.alreadyStarted", logName()));

 

       if (debug >= 1)

           log("Starting");

 

       // Notify our interested LifecycleListeners

       lifecycle.fireLifecycleEvent(BEFORE_START_EVENT, null);

 

       if (debug >= 1)

           log("Processing start(), current available=" +getAvailable());

       setAvailable(false);

       setConfigured(false);

       boolean ok = true;

 

       // Add missing components as necessary

       if (getResources() == null) {   //(1) Required by Loader

           if (debug >= 1)

                log("Configuring defaultResources");

           try {

                if ((docBase != null)&& (docBase.endsWith(".war")))

                    setResources(newWARDirContext());

                else

                    setResources(newFileDirContext());

           } catch (IllegalArgumentException e) {

                log("Error initializingresources: " + e.getMessage());

                ok = false;

           }

       }

       if (ok && (resources instanceof ProxyDirContext)) {

           DirContext dirContext =

                ((ProxyDirContext)resources).getDirContext();

           if ((dirContext != null)

                && (dirContextinstanceof BaseDirContext)) {

                ((BaseDirContext)dirContext).setDocBase(getBasePath());

               ((BaseDirContext)dirContext).allocate();

           }

       }

       if (getLoader() == null) {      //(2) Required by Manager

           if (getPrivileged()) {

                if (debug >= 1)

                    log("Configuringprivileged default Loader");

                setLoader(newWebappLoader(this.getClass().getClassLoader()));

           } else {

                if (debug >= 1)

                    log("Configuringnon-privileged default Loader");

                setLoader(new WebappLoader(getParentClassLoader()));

           }

       }

       if (getManager() == null) {     //(3) After prerequisites

           if (debug >= 1)

                log("Configuring defaultManager");

           setManager(new StandardManager());

       }

 

       // Initialize character set mapper

       getCharsetMapper();

 

       // Post work directory

       postWorkDirectory();

 

       // Reading the "catalina.useNaming" environment variable

       String useNamingProperty = System.getProperty("catalina.useNaming");

       if ((useNamingProperty != null)

           && (useNamingProperty.equals("false"))) {

           useNaming = false;

       }

 

       if (ok && isUseNaming()) {

           if (namingContextListener == null) {

               namingContextListener =new NamingContextListener();

               namingContextListener.setDebug(getDebug());

               namingContextListener.setName(getNamingContextName());

               addLifecycleListener(namingContextListener);

            }

       }

 

       // Binding thread

       ClassLoader oldCCL = bindThread();

 

       // Standard container startup

       if (debug >= 1)

           log("Processing standard container startup");

 

       if (ok) {

 

           try {

 

               addDefaultMapper(this.mapperClass);

                started = true;

 

                // Start our subordinatecomponents, if any

                if ((loader != null) &&(loader instanceof Lifecycle))

                    ((Lifecycle) loader).start();

                if ((logger != null) &&(logger instanceof Lifecycle))

                    ((Lifecycle)logger).start();

 

                // Unbinding thread

                unbindThread(oldCCL);

 

                // Binding thread

                oldCCL = bindThread();

 

                if ((cluster != null)&& (cluster instanceof Lifecycle))

                    ((Lifecycle)cluster).start();

                if ((realm != null) &&(realm instanceof Lifecycle))

                    ((Lifecycle) realm).start();

                if ((resources != null)&& (resources instanceof Lifecycle))

                    ((Lifecycle)resources).start();

 

                // Start our Mappers, if any

                Mapper mappers[] =findMappers();

                for (int i = 0; i <mappers.length; i++) {

                    if (mappers[i] instanceofLifecycle)

                        ((Lifecycle)mappers[i]).start();

                }

 

                // Start our child containers,if any

               Container children[] =findChildren();

                for (int i = 0; i <children.length; i++) {

                    if (children[i] instanceofLifecycle)

                        ((Lifecycle)children[i]).start();

                }

 

                // Start the Valves in our pipeline(including the basic),

                // if any

                if (pipeline instanceofLifecycle)

                    ((Lifecycle)pipeline).start();

 

                // Notify our interestedLifecycleListeners

                lifecycle.fireLifecycleEvent(START_EVENT,null);

 

                if ((manager != null)&& (manager instanceof Lifecycle))

                    ((Lifecycle)manager).start();

 

           } finally {

                // Unbinding thread

               unbindThread(oldCCL);

           }

 

       }

       if (!getConfigured())

           ok = false;

 

       // We put the resources into the servlet context

       if (ok)

           getServletContext().setAttribute

                (Globals.RESOURCES_ATTR,getResources());

 

       // Binding thread

       oldCCL = bindThread();

 

       // Create context attributes that will be required

       if (ok) {

           if (debug >= 1)

                log("Posting standardcontext attributes");

           postWelcomeFiles();

       }

 

       // Configure and call application event listeners and filters

       if (ok) {

           if (!listenerStart())

                ok = false;

       }

       if (ok) {

           if (!filterStart())

                ok = false;

       }

 

       // Load and initialize all "load on startup" servlets

       if (ok)

           loadOnStartup(findChildren());

 

       // Unbinding thread

       unbindThread(oldCCL);

 

       // Set available status depending upon startup success

       if (ok) {

           if (debug >= 1)

                log("Startingcompleted");

           setAvailable(true);

       } else {

           log(sm.getString("standardContext.startFailed"));

           try {

                stop();

           } catch (Throwable t) {

               log(sm.getString("standardContext.startCleanup"), t);

           }

           setAvailable(false);

       }

 

       // Notify our interested LifecycleListeners

       lifecycle.fireLifecycleEvent(AFTER_START_EVENT, null);

 

}

 

我们看这个start方法的时候,可以结合之前StandardEngine,StandardHost的分析经过来进行剖析:

第一,  利用了lifecycle的监听者模式,我们从digester机制中可以知道,其实调用的就是ContextConfig类的lifecycleEvent方法,这个方法的源码如下:

publicvoid lifecycleEvent(LifecycleEvent event) {

 

        // Identify the context we areassociated with

        try {

            context = (Context)event.getLifecycle();

            if (context instanceofStandardContext) {

                int contextDebug = ((StandardContext)context).getDebug();

                if (contextDebug >this.debug)

                    this.debug = contextDebug;

            }

        } catch (ClassCastException e) {

           log(sm.getString("contextConfig.cce", event.getLifecycle()),e);

            return;

        }

 

        // Process the event that has occurred

        if(event.getType().equals(Lifecycle.START_EVENT))

            start();

        else if(event.getType().equals(Lifecycle.STOP_EVENT))

            stop();

 

}

 

根据源码可以知道,它再次调用了本类的stat方法:

privatesynchronized void start() {

 

        if (debug > 0)

           log(sm.getString("contextConfig.start"));

        context.setConfigured(false);

        ok = true;

 

        // Set properties based onDefaultContext

        Container container =context.getParent();

        if( !context.getOverride() ) {

            if( container instanceof Host ) {

               ((Host)container).importDefaultContext(context);

                container =container.getParent();

            }

            if( container instanceof Engine ) {

               ((Engine)container).importDefaultContext(context);

            }

        }

 

        // Process the default and applicationweb.xml files

        defaultConfig();

        applicationConfig();

       if (ok) {

            validateSecurityRoles();

        }

 

        // Scan tag library descriptor filesfor additional listener classes

        if (ok) {

            try {

                tldScan();

            } catch (Exception e) {

                log(e.getMessage(), e);

                ok = false;

            }

        }

 

        // Configure a certificates exposervalve, if required

        if (ok)

            certificatesConfig();

 

        // Configure an authenticator if weneed one

        if (ok)

            authenticatorConfig();

 

        // Dump the contents of this pipelineif requested

        if ((debug >= 1) && (contextinstanceof ContainerBase)) {

            log("PiplineConfiguration:");

            Pipeline pipeline = ((ContainerBase)context).getPipeline();

            Valve valves[] = null;

            if (pipeline != null)

                valves = pipeline.getValves();

            if (valves != null) {

                for (int i = 0; i <valves.length; i++) {

                    log("  " + valves[i].getInfo());

                }

            }

           log("======================");

        }

 

        // Make our application available if noproblems were encountered

        if (ok)

            context.setConfigured(true);

        else {

           log(sm.getString("contextConfig.unavailable"));

            context.setConfigured(false);

        }

 

    }

 

在这start方法,我们特别要注意的是defaultConfig和applicationConfig方法,在这2个方法中,其实利用了Digester的机制去解析了我们项目中的web.xml,

          private void applicationConfig() {

 

       // Open the application web.xml file, if it exists

       InputStream stream = null;

       ServletContext servletContext = context.getServletContext();

       if (servletContext != null)

           stream = servletContext.getResourceAsStream

                (Constants.ApplicationWebXml);

       if (stream == null) {

           log(sm.getString("contextConfig.applicationMissing"));

           return;

       }

 

       // Process the application web.xml file

       synchronized (webDigester) {

           try {

                URL url =

                   servletContext.getResource(Constants.ApplicationWebXml);

 

                InputSource is = new InputSource(url.toExternalForm());

                is.setByteStream(stream);

               webDigester.setDebug(getDebug());

                if (context instanceofStandardContext) {

                    ((StandardContext)context).setReplaceWelcomeFiles(true);

                }

                webDigester.clear();

                webDigester.push(context);

                webDigester.parse(is);

           } catch (SAXParseException e) {

               log(sm.getString("contextConfig.applicationParse"), e);

               log(sm.getString("contextConfig.applicationPosition",

                                 "" +e.getLineNumber(),

                                 "" +e.getColumnNumber()));

                ok = false;

           } catch (Exception e) {

               log(sm.getString("contextConfig.applicationParse"), e);

                ok = false;

           } finally {

                try {

                    if (stream != null) {

                        stream.close();

                    }

                } catch (IOException e) {

                   log(sm.getString("contextConfig.applicationClose"), e);

                }

           }

       }

 

}

 

我们要了解Digester的解析机制,要看看本类的webDigester这个属性的赋值

    private static Digester webDigester =createWebDigester();

 

查看createWebDigesert()方法源码:

    private static Digester createWebDigester(){

 

        URL url = null;

        Digester webDigester = new Digester();

        webDigester.setValidating(true);

        url =ContextConfig.class.getResource(Constants.WebDtdResourcePath_22);

       webDigester.register(Constants.WebDtdPublicId_22,

                             url.toString());

        url =ContextConfig.class.getResource(Constants.WebDtdResourcePath_23);

        webDigester.register(Constants.WebDtdPublicId_23,

                             url.toString());

        webDigester.addRuleSet(newWebRuleSet());

        return (webDigester);

 

    }

 

在这个源码里边,我们主要下webDigester.addRuleSet(newWebRuleSet()); 查看下WebRuleSet类中的addRuleInstances源码

public void addRuleInstances(Digesterdigester) {

 

        digester.addRule(prefix +"web-app",

                         newSetPublicIdRule(digester, "setPublicId"));

 

        digester.addCallMethod(prefix +"web-app/context-param",

                               "addParameter",2);

        digester.addCallParam(prefix +"web-app/context-param/param-name", 0);

        digester.addCallParam(prefix +"web-app/context-param/param-value", 1);

 

        digester.addCallMethod(prefix +"web-app/display-name",

                               "setDisplayName", 0);

 

        digester.addRule(prefix +"web-app/distributable",

                         newSetDistributableRule(digester));

 

        digester.addObjectCreate(prefix +"web-app/ejb-local-ref",

                                 "org.apache.catalina.deploy.ContextLocalEjb");

        digester.addSetNext(prefix +"web-app/ejb-local-ref",

                           "addLocalEjb",

                           "org.apache.catalina.deploy.ContextLocalEjb");

 

        digester.addCallMethod(prefix +"web-app/ejb-local-ref/description",

                              "setDescription", 0);

        digester.addCallMethod(prefix +"web-app/ejb-local-ref/ejb-link",

                              "setLink", 0);

        digester.addCallMethod(prefix +"web-app/ejb-local-ref/ejb-ref-name",

                              "setName", 0);

        digester.addCallMethod(prefix +"web-app/ejb-local-ref/ejb-ref-type",

                              "setType", 0);

        digester.addCallMethod(prefix +"web-app/ejb-local-ref/local",

                              "setLocal", 0);

        digester.addCallMethod(prefix +"web-app/ejb-local-ref/local-home",

                              "setHome", 0);

 

        digester.addObjectCreate(prefix +"web-app/ejb-ref",

                                "org.apache.catalina.deploy.ContextEjb");

        digester.addSetNext(prefix +"web-app/ejb-ref",

                            "addEjb",

                           "org.apache.catalina.deploy.ContextEjb");

 

        digester.addCallMethod(prefix +"web-app/ejb-ref/description",

                              "setDescription", 0);

        digester.addCallMethod(prefix +"web-app/ejb-ref/ejb-link",

                              "setLink", 0);

        digester.addCallMethod(prefix +"web-app/ejb-ref/ejb-ref-name",

                              "setName", 0);

        digester.addCallMethod(prefix +"web-app/ejb-ref/ejb-ref-type",

                              "setType", 0);

        digester.addCallMethod(prefix +"web-app/ejb-ref/home",

                              "setHome", 0);

        digester.addCallMethod(prefix +"web-app/ejb-ref/remote",

                              "setRemote", 0);

 

        digester.addObjectCreate(prefix +"web-app/env-entry",

                                "org.apache.catalina.deploy.ContextEnvironment");

        digester.addSetNext(prefix +"web-app/env-entry",

                           "addEnvironment",

                            "org.apache.catalina.deploy.ContextEnvironment");

 

        digester.addCallMethod(prefix +"web-app/env-entry/description",

                              "setDescription", 0);

        digester.addCallMethod(prefix +"web-app/env-entry/env-entry-name",

                              "setName", 0);

        digester.addCallMethod(prefix +"web-app/env-entry/env-entry-type",

                              "setType", 0);

        digester.addCallMethod(prefix +"web-app/env-entry/env-entry-value",

                              "setValue", 0);

 

        digester.addObjectCreate(prefix +"web-app/error-page",

                                "org.apache.catalina.deploy.ErrorPage");

        digester.addSetNext(prefix +"web-app/error-page",

                            "addErrorPage",

                           "org.apache.catalina.deploy.ErrorPage");

 

        digester.addCallMethod(prefix +"web-app/error-page/error-code",

                              "setErrorCode", 0);

        digester.addCallMethod(prefix +"web-app/error-page/exception-type",

                              "setExceptionType", 0);

        digester.addCallMethod(prefix +"web-app/error-page/location",

                              "setLocation", 0);

 

        digester.addObjectCreate(prefix +"web-app/filter",

                                "org.apache.catalina.deploy.FilterDef");

        digester.addSetNext(prefix +"web-app/filter",

                           "addFilterDef",

                            "org.apache.catalina.deploy.FilterDef");

 

        digester.addCallMethod(prefix +"web-app/filter/description",

                              "setDescription", 0);

        digester.addCallMethod(prefix +"web-app/filter/display-name",

                               "setDisplayName", 0);

        digester.addCallMethod(prefix +"web-app/filter/filter-class",

                              "setFilterClass", 0);

        digester.addCallMethod(prefix +"web-app/filter/filter-name",

                               "setFilterName", 0);

        digester.addCallMethod(prefix +"web-app/filter/large-icon",

                              "setLargeIcon", 0);

        digester.addCallMethod(prefix +"web-app/filter/small-icon",

                               "setSmallIcon",0);

 

        digester.addCallMethod(prefix +"web-app/filter/init-param",

                              "addInitParameter", 2);

        digester.addCallParam(prefix +"web-app/filter/init-param/param-name",

                              0);

        digester.addCallParam(prefix +"web-app/filter/init-param/param-value",

                              1);

 

        digester.addObjectCreate(prefix +"web-app/filter-mapping",

                                "org.apache.catalina.deploy.FilterMap");

        digester.addSetNext(prefix +"web-app/filter-mapping",

                           "addFilterMap",

                           "org.apache.catalina.deploy.FilterMap");

 

        digester.addCallMethod(prefix +"web-app/filter-mapping/filter-name",

                              "setFilterName", 0);

        digester.addCallMethod(prefix +"web-app/filter-mapping/servlet-name",

                              "setServletName", 0);

        digester.addCallMethod(prefix +"web-app/filter-mapping/url-pattern",

                              "setURLPattern", 0);

 

        digester.addCallMethod(prefix +"web-app/listener/listener-class",

                              "addApplicationListener", 0);

 

        digester.addObjectCreate(prefix +"web-app/login-config",

                                "org.apache.catalina.deploy.LoginConfig");

        digester.addSetNext(prefix +"web-app/login-config",

                           "setLoginConfig",

                           "org.apache.catalina.deploy.LoginConfig");

 

        digester.addCallMethod(prefix +"web-app/login-config/auth-method",

                              "setAuthMethod", 0);

        digester.addCallMethod(prefix +"web-app/login-config/realm-name",

                              "setRealmName", 0);

        digester.addCallMethod(prefix +"web-app/login-config/form-login-config/form-error-page",

                              "setErrorPage", 0);

        digester.addCallMethod(prefix +"web-app/login-config/form-login-config/form-login-page",

                              "setLoginPage", 0);

 

        digester.addCallMethod(prefix +"web-app/mime-mapping",

                              "addMimeMapping", 2);

        digester.addCallParam(prefix +"web-app/mime-mapping/extension", 0);

        digester.addCallParam(prefix +"web-app/mime-mapping/mime-type", 1);

 

        digester.addCallMethod(prefix +"web-app/resource-env-ref",

                              "addResourceEnvRef", 2);

        digester.addCallParam(prefix +"web-app/resource-env-ref/resource-env-ref-name", 0);

        digester.addCallParam(prefix +"web-app/resource-env-ref/resource-env-ref-type", 1);

 

        digester.addObjectCreate(prefix +"web-app/resource-ref",

                                "org.apache.catalina.deploy.ContextResource");

        digester.addSetNext(prefix +"web-app/resource-ref",

                           "addResource",

                           "org.apache.catalina.deploy.ContextResource");

 

        digester.addCallMethod(prefix +"web-app/resource-ref/description",

                              "setDescription", 0);

        digester.addCallMethod(prefix +"web-app/resource-ref/res-auth",

                              "setAuth", 0);

        digester.addCallMethod(prefix +"web-app/resource-ref/res-ref-name",

                              "setName", 0);

        digester.addCallMethod(prefix +"web-app/resource-ref/res-sharing-scope",

                              "setScope", 0);

        digester.addCallMethod(prefix +"web-app/resource-ref/res-type",

                              "setType", 0);

 

        digester.addObjectCreate(prefix +"web-app/security-constraint",

                                "org.apache.catalina.deploy.SecurityConstraint");

        digester.addSetNext(prefix +"web-app/security-constraint",

                           "addConstraint",

                           "org.apache.catalina.deploy.SecurityConstraint");

 

        digester.addRule(prefix +"web-app/security-constraint/auth-constraint",

                         new SetAuthConstraintRule(digester));

        digester.addCallMethod(prefix +"web-app/security-constraint/auth-constraint/role-name",

                              "addAuthRole", 0);

        digester.addCallMethod(prefix +"web-app/security-constraint/display-name",

                              "setDisplayName", 0);

        digester.addCallMethod(prefix +"web-app/security-constraint/user-data-constraint/transport-guarantee",

                              "setUserConstraint", 0);

 

        digester.addObjectCreate(prefix +"web-app/security-constraint/web-resource-collection",

                                "org.apache.catalina.deploy.SecurityCollection");

        digester.addSetNext(prefix +"web-app/security-constraint/web-resource-collection",

                            "addCollection",

                           "org.apache.catalina.deploy.SecurityCollection");

        digester.addCallMethod(prefix +"web-app/security-constraint/web-resource-collection/http-method",

                              "addMethod", 0);

        digester.addCallMethod(prefix +"web-app/security-constraint/web-resource-collection/url-pattern",

                              "addPattern", 0);

        digester.addCallMethod(prefix +"web-app/security-constraint/web-resource-collection/web-resource-name",

                              "setName", 0);

 

        digester.addCallMethod(prefix +"web-app/security-role/role-name",

                               "addSecurityRole", 0);

 

        digester.addRule(prefix +"web-app/servlet",

                         newWrapperCreateRule(digester));

        digester.addSetNext(prefix +"web-app/servlet",

                           "addChild",

                            "org.apache.catalina.Container");

 

        digester.addCallMethod(prefix +"web-app/servlet/init-param",

                              "addInitParameter", 2);

        digester.addCallParam(prefix +"web-app/servlet/init-param/param-name",

                              0);

        digester.addCallParam(prefix +"web-app/servlet/init-param/param-value",

                              1);

 

        digester.addCallMethod(prefix +"web-app/servlet/jsp-file",

                               "setJspFile",0);

        digester.addCallMethod(prefix +"web-app/servlet/load-on-startup",

                              "setLoadOnStartupString", 0);

        digester.addCallMethod(prefix +"web-app/servlet/run-as/role-name",

                               "setRunAs",0);

 

        digester.addCallMethod(prefix +"web-app/servlet/security-role-ref",

                              "addSecurityReference", 2);

        digester.addCallParam(prefix +"web-app/servlet/security-role-ref/role-link", 1);

        digester.addCallParam(prefix +"web-app/servlet/security-role-ref/role-name", 0);

 

        digester.addCallMethod(prefix +"web-app/servlet/servlet-class",

                             "setServletClass", 0);

        digester.addCallMethod(prefix +"web-app/servlet/servlet-name",

                             "setName", 0);

 

        digester.addCallMethod(prefix +"web-app/servlet-mapping",

                              "addServletMapping", 2);

        digester.addCallParam(prefix +"web-app/servlet-mapping/servlet-name", 1);

        digester.addCallParam(prefix +"web-app/servlet-mapping/url-pattern", 0);

 

        digester.addCallMethod(prefix +"web-app/session-config/session-timeout",

                              "setSessionTimeout", 1,

                               new Class[] {Integer.TYPE });

        digester.addCallParam(prefix +"web-app/session-config/session-timeout", 0);

 

        digester.addCallMethod(prefix +"web-app/taglib",

                              "addTaglib", 2);

        digester.addCallParam(prefix +"web-app/taglib/taglib-location", 1);

        digester.addCallParam(prefix +"web-app/taglib/taglib-uri", 0);

 

        digester.addCallMethod(prefix +"web-app/welcome-file-list/welcome-file",

                               "addWelcomeFile",0);

 

    }

 

 

}

 

这个时候,我们就可以知道,原来对web.xml的解析就在这里实现的啦!

 

但是这个时候,我们还要特别注意下,

digester.addRule(prefix+ "web-app/servlet",

                         newWrapperCreateRule(digester));

 

在查看下WrapperCreateRule类中的begin方法

public voidbegin(Attributes attributes) throws Exception {

        Context context =

            (Context)digester.peek(digester.getCount() - 1);

        Wrapper wrapper =context.createWrapper();

        digester.push(wrapper);

        if (digester.getDebug() > 0)

            digester.log("new " +wrapper.getClass().getName());

    }

 

我们可以知道,Wrapperwrapper = context.createWrapper();调用了context的createWrapper方法,而这个context的实现类就是我们的standardContext,我们可以返回到

standardContext中查看createWrapper

public Wrapper createWrapper() {

 

       Wrapper wrapper = new StandardWrapper();

 

       synchronized (instanceListeners) {

           for (int i = 0; i < instanceListeners.length; i++) {

                try {

                    Class clazz =Class.forName(instanceListeners[i]);

                    InstanceListener listener =

                      (InstanceListener)clazz.newInstance();

                   wrapper.addInstanceListener(listener);

                } catch (Throwable t) {

                   log("createWrapper", t);

                    return (null);

                }

           }

       }

 

       synchronized (wrapperLifecycles) {

           for (int i = 0; i < wrapperLifecycles.length; i++) {

                try {

                    Class clazz =Class.forName(wrapperLifecycles[i]);

                    LifecycleListener listener=

                      (LifecycleListener)clazz.newInstance();

                    if (wrapper instanceofLifecycle)

                        ((Lifecycle)wrapper).addLifecycleListener(listener);

                } catch (Throwable t) {

                   log("createWrapper", t);

                    return (null);

                }

           }

       }

 

       synchronized (wrapperListeners) {

           for (int i = 0; i < wrapperListeners.length; i++) {

                try {

                    Class clazz =Class.forName(wrapperListeners[i]);

                    ContainerListener listener=

                      (ContainerListener)clazz.newInstance();

                    wrapper.addContainerListener(listener);

                } catch (Throwable t) {

                   log("createWrapper", t);

                    return (null);

                }

           }

       }

 

       return (wrapper);

 

}

明白这里返回了wrapper的实现类StandardWrapper的对象

从上述的分析可以知道,在standardContext启动的时候,通过监听者模式,将项目部署文件web.xml文件进行解析,并利用包装类standardWrapper将web.xml文件中的servlet进行包装起来,一个servlet对应一个standardWrapper

 

第二点,addDefaultMapper使用了StandardContextMapper

 

第三点,执行了children里边的start方法,children里边的元素怎么设置进去的呢?

我们查看下WebRuleSet类中的:

digester.addRule(prefix +"web-app/servlet",

                         newWrapperCreateRule(digester));

       digester.addSetNext(prefix + "web-app/servlet",

                           "addChild",

                           "org.apache.catalina.Container");

 

就很清楚了,children其实就是包装了servlet的standardWrapper,也就是你说standardContext的启动,移交给了starndardWrapper启动

 

第四点,其他操作我们目前暂时略过

我们standardContext的启动流程图:



standardContext启动的关系类图:



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值