How tomcat works読書ノート15 Digesterライブラリ下


このセクションではContextConfigというクラスについてお話しします.
このクラスは昔から使われていましたが(以前はSimpleContextConfigと呼ばれていましたが)、前にやったことは簡単でしたね.contextのconfigured変数をtrueにします.ここでは、完全版のContextConfigが何をしているかを見てみましょう.
tomcatの実装ではStandContextクラスの実際のListenerはorgである.apache.catalina.startup.ContextConfigの例.
ContextConfigはベリファイアバルブのロードを完了し、StandContextのパイプバルブに許可バルブを入れます.しかし、最も重要なのは、前節のDigesterライブラリを適用して、2つのxmlファイルを解析することです.一つはtomcat全体のプロファイル、webです.xml、confディレクトリの下にあります.もう1つは、WEB-INFディレクトリの下にある単一のwebアプリケーションのxmlファイルです.
ここで私は主にシステムをあるwebアプリケーションの下のwebに基づいてどのようにするかについて話します.xmlで指定したように、StandWrapperが自動的に作成されます.
    LifecycleListener listener = new ContextConfig();
    ((Lifecycle) context).addLifecycleListener(listener);
まずStandContextにContextConfigというリスナーを注入しなければなりません.
StandContextの起動と停止では、次のイベントがトリガーされます.
START_ENENT
STOP_ENENT
ContextConfig.java
 public void lifecycleEvent(LifecycleEvent event) {
        ...
        // Process the event that has occurred
        if (event.getType().equals(Lifecycle.START_EVENT))
            start();
        else if (event.getType().equals(Lifecycle.STOP_EVENT))
            stop();
    }
ContextConfigのstartメソッドを見てみましょう.
 private synchronized void start() {
    ...
        // Process the default and application web.xml files
        defaultConfig();          //  conf/xml.xml
        applicationConfig();      //  WEB-INF/web.xml
    ...
}
tomcat全体のxmlにかかわらず、単一のプロジェクトを見ます.
 private void applicationConfig() {

       ...
        // Process the application web.xml file
        synchronized (webDigester) {
        //public static final String ApplicationWebXml = "/WEB-INF/web.xml";
                URL url =servletContext.getResource(Constants.ApplicationWebXml);

                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);//        context 
                webDigester.parse(is);  //    
            }
    ...
    }
現在の問題は、webDigesterはどうやって来たのかということです.
ContextConfigには次のクラス変数があります.
private static Digester webDigester = createWebDigester();
我々はcreateWebDigesterを見てみましょう
    private static Digester createWebDigester() {
        ...
        Digester webDigester = new Digester();
    ...
        webDigester.addRuleSet(new WebRuleSet());  //addRuleSet            
        return (webDigester);
    }
今WebRuleSet類を見に行きますが、主にどの方法を見たか覚えていますか.
WebRuleSet.java
 public void addRuleInstances(Digester digester) {
    ....
         digester.addRule(prefix + "web-app/servlet",new WrapperCreateRule(digester));
    ...
    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);

    //setServletClass            ?         
}

final class WrapperCreateRule extends Rule {

    public void begin(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());
    }
}

皆さんは流れを見ましたか?
まずルールを追加します
digester.addRule(prefix + "web-app/servlet",new WrapperCreateRule(digester));
Web-app/servletに遭遇するとbeginメソッドが呼び出され、wrapperが生成されます.
Web-app/servlet/servlet-nameがこれに遭遇した後、wrapperを呼び出す方法はokです.