十年網(wǎng)站開發(fā)經(jīng)驗 + 多家企業(yè)客戶 + 靠譜的建站團隊
量身定制 + 運營維護+專業(yè)推廣+無憂售后,網(wǎng)站問題一站解決
這篇文章主要為大家展示了“Tomcat配置文件的示例分析”,內(nèi)容簡而易懂,條理清晰,希望能夠幫助大家解決疑惑,下面讓小編帶領(lǐng)大家一起研究并學習一下“Tomcat配置文件的示例分析”這篇文章吧。
網(wǎng)站的建設(shè)創(chuàng)新互聯(lián)建站專注網(wǎng)站定制,經(jīng)驗豐富,不做模板,主營網(wǎng)站定制開發(fā).小程序定制開發(fā),H5頁面制作!給你煥然一新的設(shè)計體驗!已為成都混凝土攪拌機等企業(yè)提供專業(yè)服務(wù)。
Tomcat用戶一定都知道其包含一個名為server.xml的配置文件。畢竟都在這里改過端口或者以目錄形式部署過應(yīng)用。
那這個配置文件里的配置信息又是如何對應(yīng)到Tomcat中的具體對象的。開發(fā)的朋友馬上會在大腦里浮現(xiàn)出Dom4j、Jdom、JAXB、SAX...一系列的XML解析工具。
不過,這里Tomcat用的并不是上面提到的這幾位,而是Apache社區(qū)自己的XML解析工具Digester.
在Digester的Wiki里,這樣介紹自己:
Many projects read XML configuration files to provide initialization of various Java objects within the system. There are several ways of doing this, and the Digester component was designed to provide a common implementation that can be used in many different projects.
我們來看Tomcat內(nèi)部對于Digester是如何使用的。
在Catalina類內(nèi),我們會發(fā)現(xiàn)許多類似這樣的代碼:
digester.addObjectCreate("Server/Service",
"org.apache.catalina.core.StandardService",
"className");
digester.addSetProperties("Server/Service");
digester.addSetNext("Server/Service",
"addService",
"org.apache.catalina.Service");digester.addRuleSet(new NamingRuleSet("Server/GlobalNamingResources/"));
digester.addRuleSet(new EngineRuleSet("Server/Service/"));
digester.addRule("Server/Service/Connector",
new ConnectorCreateRule());
以上這些是配置,最終的解析是通過parse這樣一個方法
inputSource.setByteStream(inputStream);
digester.push(this);
digester.parse(inputSource);
那是不是整個parse就是解析配置文件是否非法呢? Of course Not.
對應(yīng)上面標紅的addObjectCreate, addSetProperties,這些操作的背后,其實是添加了一系列的Rule。
這是個抽象類,對于上面添加的不同的Rule,有不同的實現(xiàn)。
其中,create對應(yīng)的實現(xiàn)是ObjectCreateRule
public void addObjectCreate(String pattern, String className,
String attributeName) {
addRule(pattern,
new ObjectCreateRule(className, attributeName));
}
setProperties對應(yīng)的是SetPropertiesRule。
public void addSetProperties(String pattern) {
addRule(pattern,
new SetPropertiesRule());
}
setNext對應(yīng)的Rule是SetNextRule
在解析過程中,SetNextRule實質(zhì)上,是會通過反射,調(diào)用對應(yīng)方法。下圖是在執(zhí)行Catalina的一個setServer的Rule
對應(yīng)setProperties的執(zhí)行,也是通過反射,設(shè)置對應(yīng)屬性的值。例如,下圖是在設(shè)置Server的port屬性值。
這時,你可能會問,那這些對象設(shè)置屬性,創(chuàng)建新對象等,他們之間又是如何關(guān)聯(lián)起來的呢?
看這里,在Digester內(nèi)部維護了一個stack結(jié)構(gòu),從下到上,越向上的層級越高。如下圖,從Catalina,向上到Server,再到Service
進行Set的時候,會從頂向下,兩個相鄰的,即為父子關(guān)系,從而進行parent的child設(shè)置。
public void end(String namespace, String name) throws Exception {
// Identify the objects to be used
Object child = digester.peek(0);
Object parent = digester.peek(1);
// Call the specified method
IntrospectionUtils.callMethod1(parent, methodName,
child, paramType, digester.getClassLoader());
}
而對應(yīng)的屬性設(shè)置的時候,則是從stack里取最上面的一個,反射進行屬性設(shè)置。
整個stack的最底層,則是Catalina,在獲取配置文件輸入流之后進行的push操作
public void push(Object object) {
if (stack.size() == 0) {
root = object;
}
stack.push(object);
}
Digester整體的設(shè)計思路,在XML元素開始,創(chuàng)建Object的rule執(zhí)行時,把新創(chuàng)建的對象push到stack中。對象會保留在stack中,直到XML元素的結(jié)尾出現(xiàn)。
Rule的解析過程主要涉及到上面Rule類的幾個方法
begin 元素開始時會執(zhí)行
body 嵌套的元素匹配時執(zhí)行
end 元素結(jié)束執(zhí)行
finish 整個parse結(jié)束時調(diào)用
在parse結(jié)束之后,整個xml內(nèi)容對應(yīng)的Java對象已經(jīng)創(chuàng)建成功,開動吧!
在Tomcat內(nèi)部,Digester用在解析server.xml配置文件,MBean的描述文件,TLD文件校驗等等。
具體用法也比較簡單,new 一個Digester對象,然后設(shè)置具體的對象Rule,類似于各類的match規(guī)則,之后parse即可。
比如下面這個xml文件
解析的Digester代碼只有這些
Digester digester = new Digester();
digester.setValidating( false );
digester.addObjectCreate( "foo", "mypackage.Foo" );
digester.addSetProperties( "foo" );
digester.addObjectCreate( "foo/bar", "mypackage.Bar" );
digester.addSetProperties( "foo/bar" );
digester.addSetNext( "foo/bar", "addBar", "mypackage.Bar" );
InputStream is = digester.getClass().getClassLoader().getResourceAsStream("mytest.xml");
Foo foo = digester.parse(is);
當然,具體XML文件需要對應(yīng)的Java類還是需要的。
以上是“Tomcat配置文件的示例分析”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對大家有所幫助,如果還想學習更多知識,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道!