知识库--StandardContext(57)

来源:互联网 发布:长谷川逸子 知乎 编辑:程序博客网 时间:2024/06/11 13:21

StandardContext (tomcat 4 and 5)历史

A context represents a web application and contains one or more wrappers, each of which represents a servlet definition. However, a context requires other components as well, notably a loader and a manager. Here explains the org.apache.catalina.core.StandardContext class, which represents Catalina’s standard implementation of the Context interface.

First have a look at the StandardContext object instantiation and configuration. We then discuss the related classes StandardContextMapper(in Tomcat 4) and ContextConfig. Next, we look at the sequence of method invocation for each incoming HTTP request. Then, we revisit the StandardContext class by discussing its important properties. Finally, the last section discusses the backgroundProcess method in Tomcat 5.

StandardContext Configuration

After a StandardContext instance is constructed, its start method must be called to make the instance available to service incoming HTTP requests. For one reason or another, a StandardContext object might fail to start. If this happens, the available property of the StandardContext object will be set to false. The available property of course indicates the availability of the StandardContext.

For the start method to succeed, the StandardContext object must be configured properly. In a Tomcat deployment, the configuration of StandardContext does a number of things. It prepares the StandardContext so that the context can read and parse the default web.xml file, which is located in the %CATALINA_HOME%/conf directory and applies to all applications deployed. It also makes sure that the StandardContext instance can process application-level web.xml files. In addition, the configuration installs an authenticator valve and a certificate valve.//认证 证书

One of the properties in the StandardContext class is the configured property, which is a boolean that indicates whether or not a StandardContext instance is configured properly. StandardContext uses an event listener as its configurator. When the start method on a StandardContext instance is called, one of the things it does is fire a lifecycle event. This event invokes the listener that in turn will configure the StandardContext instance. If configuration is successful, the listener will set the configured property to true. Otherwise, the StandardContext instance will refuse to start and thus will be unavailable to service HTTP requests.

//ContextConfig 对于 StandardContext至关重要

Constructor

public StandardContext(){    super();    pipeline.setBasic(new StandardContextValve());    namingResources.setContainer(this);}

The most important thing to note in the constructor is that the StandardContext’s pipeline is given a basic valve of type org.apache.catalina.core.StandardContextValve. This valve will handle every HTTP request that comes through the connector.

The start method initializes the StandardContext instance and gives the lifecycle listener a chance to configure the StandardContext instance. The listener will set the configured property *to true upon a successful configuration, At the end, the start method sets the available property to either true or false. A value of true means the StandardContext instance has been configured properly and all related child containers and components have been started successfully and therefore the StandardContext instance is ready to service incoming HTTP requests*. A value of false indicates otherwise.

The StandardContext class employs a boolean called configured that is initially set to false. If the lifecyle listener is successful in performing its tasks of configuring a StandardContext instance, it will set the StandardContext’s configured property to true. Towards the end of the start method, the StandardContext checks the value of the configured variable. If it is true, the StandardContext has started successfully. Otherwise, the stop method is called to stop all the components that have been started by the start method.

——————————-start method—————————–

    public synchronized void start() throws LifecycleException{        if(started)            throw new LifecycleException (sm.getString("containerBase.alreadyStarted", logName()));        //Notify our interested LifecycleListeners        lifecycle.fireLifecycleEvent(BEFORE_START_EVENT,null);        setAvailable(false);        setConfigured(false);        boolean ok = true;        //add missing components as necessary        if(getResources() == null){//(1)required by loader            try{                if((docBase!=null)&&(docBase.endsWith(".war"))){                    setResources(new WARDirContext());                }else{                    setResources(new FileDirContext());                }            }catch (IllegalArgumentException e) { log("Error initializing resources: " + e.getMessage());             ok = false;             }        }        if(ok &&(resources instanceof ProxyDirContext)){            DirContext dirContext = resources.getDirContext();            if(dirContext != null && dirContext instanceof   BaseDirContext){                dirContext.setDocBase(getBasePath());                dirContext.allocate();              }        }        if(getLoader()==null){//(2)required by Manager            if(getPrivileged()){                setLoader(new WebappLoader(this.getClass().getClassLoader()));            }else{                setLoader(new WebappLoader(getParentClassLoader()));            }        }        if(getManager() == null){//(3)After prerequisites 先决条件            setManeger(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.setName(getNamingContextName());                addLifecycleListener(namingContextListener);            }        }        //Binding thread        ClassLoader oldCCL = bindThread();        if(ok){            try{                addDefaultMapper(this.mapperClass);                started = true;                //Start our subordinate components, if any                if(loader!=null && (loader instanceof Lifecyle))                    ((Lifecyle)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 < mapppers.length;i++){                    if(mappers[i] instanceof Lifecyle)                        ((Lifecycle) mapper[i]).start();                }                //Start our child containers, if any                Container children[] = findChildren();                for (int i = 0; i < children.length; i++) {                     if (children[i] instanceof Lifecycle)                         ((Lifecycle) children[i]).start();                 }                // Start the Valves in our pipeline                if(pipeline instanceof Lifecycle)                    pipeline.start();                //Notify our interested LifecycleListeners                lifecycle.fireLifecycleEvent(START_EVENT,null);                if((manager != null) && (manager instanceof Lifecycle)){                    manager.start();                }            }finally{                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){            postWelcomeFiles();        }        //configure and call application event listeners and filters         if(ok)            if(!listenerStart())                ok = false;        if(ok)            if(!filterStart()))                ok = false;        //load anf initialize all "load on startup" servlets        if(ok)            loadOnStartup(findChildren());        //unbinding  thread        unbindThread(oldCCL);        //set available status depending upon startup success        if(ok)            setAvailable(true);        else{            try{                stop();            }catch(Throwable t){            }            setAvailable(false);        }        //Notify our interested LifecycleListeners        lifecyle.fireLifecycleEvent(AFTER_START_EVENT,null);    }

————————-invoke method————————–
The StandardContext’s invoke method is called by the associated connector or , if the StandardContext is a child container of a host,by the host’s invoke method. First checks if reloading of the application is taking place, and, if so, waits until the application reloading has finished. It then calls the invoke method of its parent class, ContainerBase.

    public void invoke(Request request,Response response)throws IOException,ServletException{        //wait if we are reloading        while(getPaused){            try{                Thread.sleep(1000);            }catch(InterruptedException e);        }        //normal request processing        if(swallowOutput){             try{                 SystemLogHandler.startCapture();                 auper.invoke(request,response);             }finally{                 String log = SystemLogHandler.stopCapture();                 if(log != null && log.length()>0){                     log(log);//吞掉                 }             }        }else{            super.invoke(request,response);        }    }

In Tomcat 5+, the StandardContext class does not provide an implementation of the invoke method, therefore the ContainerBase class’s invoke method is executed. The checking of application reloading has been moved to the invoke method of the StandardContextValve class.

0 0
原创粉丝点击