频道栏目
首页 > 程序开发 > 综合编程 > 组件/库 > 正文
知识库--Digester + ContextConfig(73)
2017-01-09 10:05:05      个评论    来源:qfzhangwei的专栏  
收藏   我要投稿

Digester + ContextConfig

Unlike other types of containes, a StandardContext must have a listener. This listener configures the StandardContext instance and upon successfully doing so sets the StandardContext’s configured vaiable to true.

In previous, we use the SimpleContextConfig class as the StandardContext’s listener. This class was a very simple one whose sole purpose is to set the configured variable so that the start method of StandardContext can continue.

In a real Tomcat deployment, the standard listener for StandardContext is an instance of org.apache.catalina.startup.ContextConfig class. Unlike our humble SimpleContextConfig class, ContextConfig does a lot of useful stuff that the StandardContext instance cannot live without it. A ContextConfig instance associated with a StandardContext installs an authenticator(验证器) valve in the StandardContext’s pipeline. It also adds a certificate(证书 ) valve (of type org.apache.catalina.valves.CertificateValve) to the pipeline.

More importantly, however, the ContextConfig instance also reads and parses the default web.xml file and the** application web.xml** file and convert the XML elements to Java objects. The default web.xml file is located in the conf directory of CATALINE_HOME. It defines and maps default servlets, maps file extensions with MIME types, defines the default session timeout, and list welcome files.

The application web.xml file is the application configuration file, located in the WEB-INF directory of an application. Both files are not required. ContextConfig will continue even if none of these files is found.

The** ContextConfig creates a StandardWrapper instance for each servlet element**. Therefore, as you can see in the application accompanying, configuration is made easy. You are no longer required to instantiate a wrapper anymore.

Therefore, somewhere in your bootstrap class, you must instantiate the ContextConfig class and add it to the StandardContext by calling the addLifecycleListener method of the org.apache.catalina.Lifecycle interface.

LifecycleListener listener = new ContextConfig();
((LifeCycle)context).addLifecycleListener(listener);

//启动时触事件
The StandardContext fires the following events when it is started:

BEFORE_START_EVENT
START_EVENT
AFTER_START_EVENT

When stopped, the StandardContext fires the following events:

BEFORE_STOP_EVENT
STOP_EVENT
AFTER_STOP_EVENT

The ContextConfig class responds to two events: START_EVENT and STOP_EVENT . The lifecycleEvent method is invoked every time the StandardContext triggers an event.

//the lifecycleEvent method of ContextConfig
public void lifecycleEvent(LifecycleEvent event){
    try{
        context = (Context)event.getLifecycle();
        if(context instanceof StandardContext){
            int conextDebug = context.getDebug();
            if(contextDebug > this.debug)
                this.debug = contextDebug;
        }
    }catch(ClassCastException e){
        log(...);
        return;
    }
    //process the event that has occured
    if(event.getType().equals(Lifecycle.START_EVENT)){
        start();//很重要!!
    }else if(event.getType().equals(Lifecycle.STOP_EVENT)){
        stop();
    }
}

Notice that somewhere in its body the start method calls the defaultConfig and applicationConfig methods .

The start method of ContextConfig

private synchronized void start(){
        if(debug > 0){
            log(...);
        }
        //reset the configured boolean
        context.setConfigured(false);
        //a flag that indeicates whether the process is still going smoothly
        ok = true;
        // Set properties based on DefaultContext
        Container container = context.getParent();
        if(!context.getOverride()){
            if(container instanceof Host){
                ((Host)container).importDefaultContext(context);
            }
            if(container instanceof Engine){
                ((Engine)container).importDefaultContext(context);
            }
        }
        //Process the default and application web.xml files
        defaultConfig();
        applicationConfig();//web.xml
        if(ok)
            validateSecurityRoles();
        //Dump the contents of this pipeline if requested
        if ((debug >= 1) && (context instanceof ContainerBase)) { 
        log("Pipline Configuration:"); 
        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 no problems were encountered
        if(ok)
            context.setConfigured(true);
        else{
            log(...);
            context.setConfigured(false);
        }
}

tips 1 The defaultConfig Method

The defaultConfig method reads and parses the default web.xml file in the %CATALINA_HOME%/conf directory.

private void defaultConfig(){
    //Open the default web.xml file, if it exists
    File file = new File(Constants.DefaultWebXml);
    if(!file.isAbsolute())
        file = new File(System.getProperty("catalina.base"),Constants.DefaultWebXml);
    FileInputStream stream = null;
    try{
        stream = new FileInputStream(file.getCanonicalPath());//权威路径
        stream.close();//为了检测?
        stream = null;
    }catch(FileNotFoundException e){
        log(...);
        return;
    }catch(IOException e){
        log(...);
        return;
    }
    //Process the default web.xml file
    synchronized(webDigester){
        try{
            InputSource is = new InputSource("file://"+file.getAbsolutePath());
            stream = new FileInputStream(file);
            is.setByteStream(stream);//byte 流
            webDigester.setDebug(getDebug());
            if(context instanceof StandardContext)
                ((StandardContext)context).setReplaceWelcomeFiles(true);
            webDigester.clear();
            webDigester.push(conext);//:-O 作为root!!
            webDigester.parse(is);//增加默认配置
        }catch(SAXParseException e){
            log(sm.getString("contextConfig.defaultParse"), e); log(sm.getString("contextConfig.defaultPosition", "" + e.getLineNumber(), "" + e.getColumnNumber())); //精确定位啊!
            ok = false;
        }catch(Exception e){
            log(...);
            ok = false;
        }finally{
            try{
                if(stream != null)
                    stream.close());
            }catch(IOException e){
                log(...);
            }
        }
    }

}

Attention The webDigester object variable references a Digester instance that have been populated with rules for processing a web.xml file.

tips 2 The applicationConfig Method

The applicationConfig method is similar to the defaultConfig method, except that it processes the application deployment descriptor. A deployment descriptor resides in the WEB-INF directory of the application directory.//小心脏

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(...);
            return;
        }
        //process the application web.xml file
        //webDigester 监视器 同步堵塞
        synchronized(webDigester){
            try{
                URL url = servletContext.getResource(Contants.ApplicationWebXml);//获取resource
                InputSource is = new InputSource(url.toExternalForm());
                is.setByteStream(stream);
                webDigester.setDebug(getDebug());
                if(context instanceof StandardContext){
                    ((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); 
        }
    }
 }
} 
//web Digester following…
点击复制链接 与好友分享!回本站首页
上一篇:知识库--Server + Service
下一篇:知识库--Web+Digester(73)
相关文章
图文推荐
点击排行

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训 | 举报中心

版权所有: 红黑联盟--致力于做实用的IT技术学习网站