您好,登錄后才能下訂單哦!
這篇文章主要為大家展示了“Tomcat配置文件的示例分析”,內容簡而易懂,條理清晰,希望能夠幫助大家解決疑惑,下面讓小編帶領大家一起研究并學習一下“Tomcat配置文件的示例分析”這篇文章吧。
Tomcat用戶一定都知道其包含一個名為server.xml的配置文件。畢竟都在這里改過端口或者以目錄形式部署過應用。
那這個配置文件里的配置信息又是如何對應到Tomcat中的具體對象的。開發的朋友馬上會在大腦里浮現出Dom4j、Jdom、JAXB、SAX...一系列的XML解析工具。
不過,這里Tomcat用的并不是上面提到的這幾位,而是Apache社區自己的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內部對于Digester是如何使用的。
在Catalina類內,我們會發現許多類似這樣的代碼:
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.
對應上面標紅的addObjectCreate, addSetProperties,這些操作的背后,其實是添加了一系列的Rule。
這是個抽象類,對于上面添加的不同的Rule,有不同的實現。
其中,create對應的實現是ObjectCreateRule
public void addObjectCreate(String pattern, String className,
String attributeName) {
addRule(pattern,
new ObjectCreateRule(className, attributeName));
}
setProperties對應的是SetPropertiesRule。
public void addSetProperties(String pattern) {
addRule(pattern,
new SetPropertiesRule());
}
setNext對應的Rule是SetNextRule
在解析過程中,SetNextRule實質上,是會通過反射,調用對應方法。下圖是在執行Catalina的一個setServer的Rule
對應setProperties的執行,也是通過反射,設置對應屬性的值。例如,下圖是在設置Server的port屬性值。
這時,你可能會問,那這些對象設置屬性,創建新對象等,他們之間又是如何關聯起來的呢?
看這里,在Digester內部維護了一個stack結構,從下到上,越向上的層級越高。如下圖,從Catalina,向上到Server,再到Service
進行Set的時候,會從頂向下,兩個相鄰的,即為父子關系,從而進行parent的child設置。
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());
}
而對應的屬性設置的時候,則是從stack里取最上面的一個,反射進行屬性設置。
整個stack的最底層,則是Catalina,在獲取配置文件輸入流之后進行的push操作
public void push(Object object) {
if (stack.size() == 0) {
root = object;
}
stack.push(object);
}
Digester整體的設計思路,在XML元素開始,創建Object的rule執行時,把新創建的對象push到stack中。對象會保留在stack中,直到XML元素的結尾出現。
Rule的解析過程主要涉及到上面Rule類的幾個方法
begin 元素開始時會執行
body 嵌套的元素匹配時執行
end 元素結束執行
finish 整個parse結束時調用
在parse結束之后,整個xml內容對應的Java對象已經創建成功,開動吧!
在Tomcat內部,Digester用在解析server.xml配置文件,MBean的描述文件,TLD文件校驗等等。
具體用法也比較簡單,new 一個Digester對象,然后設置具體的對象Rule,類似于各類的match規則,之后parse即可。
比如下面這個xml文件
<?xml version="1.0" encoding="UTF-8"?>
<foo name="The Parent">
<bar id="123" title="The First Child"/>
<bar id="456" title="The Second Child"/>
</foo>
解析的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文件需要對應的Java類還是需要的。
以上是“Tomcat配置文件的示例分析”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業資訊頻道!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。