概述
XmlConfiguration是Jetty中用來實現使用XML文件配置WebAppContext實例的框架,事實上,他可以用來配置任何的Object。類似Digester可以將一個XML配置文件直接實例化成一個類實例,XmlConfiguration可以使用一個XML文件初始化一個Object實例,它支持屬性設置、方法調用、新建新實例等。
XmlConfiguration實現
在XmlConfiguration的實現中,可以使用URL、configuration字符串、InputStream作為構造函數傳入XmlConfiguration中,在XmlConfiguration的構造函數初始化時,它初始化XmlParser實例,使用XmlParser對XML文件進行解析成一個Node樹,并將該樹的根節點賦值給config字段;在初始化config字段的同時初始化processor字段,processor字段是ConfigurationProcessor類型,他用于解析XmlParser解析出的Node樹的處理類,如果根節點的Tag是Configure,則processor使用Jetty中的默認實現:JettyXmlConfiguration類,否則使用ServiceLoader查找到的ConfigurationProcessorFactory實例,并調用其getConfigurationProcessor方法,傳入dtd和tag作為參數,直到找到一個非null的ConfigurationProcessor;在創建出ConfigurationProcessor實例后,首先調用其init方法,在JettyXmlConfiguration類的實現中,init方法只是將傳入的參數保存:Node樹的config實例、以及兩個idMap、propertyMap實例用于傳遞參數,其中idMap用于保存解析過程中所有id屬性對應的實例,也可以用它來傳遞XML文件用于配置的實例以及其他ref引用的實例,而propertyMap用于定義一些XML文件中用到的屬性對應的值。
可以使用帶Object實例的參數或不帶參數兩種方式調用configure方法,帶參數表示將XML中內容配置實例中的屬性,不帶參數則先在內部創建class屬性指定的類實例,然后使用XML的內容配置該新創建的實例的屬性,如果根元素定義了id屬性,則可以設置要配置的實例是idMap中該id值對應的實例。
在configure方法的真正實現中,它遍歷根節點的所有子節點,判斷tag值(在這個過程中對任何有id定義的元素,將該id屬性的值做為key,該元素對應的實例保存在idMap中):
Set => 用于設置name屬性指定的set方法或字段的值,在查找方法中會有各種嘗試:1. 嘗試當前值實例作為參數的set方法;2. 使用Class實例的TYPE字段作為參數類型的set方法;3. 嘗試查找public類型的字段;4. 嘗試所有只有一個參數的對應的set方法;5. 嘗試是否可以將其轉換成Set或數組類型的參數;6. 嘗試裝箱后的參數。
Put => 要使用該方法,配置類型必須繼承自Map接口,使用name屬性作為key,獲取其值實例,調用put方法。
Call => 指定class屬性表示調用其靜態方法;讀取所有的Arg子節點(Arg節點必須緊跟Call節點),并且解析這些Arg的值類型,name屬性指定方法名,在返回后如果其他節點定義,則使用它們配置返回的實例。
Get => 使用name屬性指定的get無參數方法,如果沒有找到get方法,則從name屬性指定的字段中獲取值,如果還有子元素,則對返回的實例進行配置。
New => 創建一個class指定的類實例,可以使用Arg指定構造函數參數。如果有除了Arg以外的節點定義,則使用它們對新創建的實例配置。
Array => 創建數組實例,type指定數組類型,支持以下列舉的所有的值類型,使用Item指定它的元素。
Ref => 為傳入的ref引用實例配置。
Property => 從傳入的propertyMap中獲取值,可以指定default屬性。可以通過定義子元素繼續配置返回的值。
Map => 創建新的Map實例,使用Entry/Item, Item指定key、value的值。
對于所有值類型,可以指定其type屬性,Jetty默認支持的類型有String、java.lang.String、URL、java.net.URL、InetAddress、java.net.InetAddress、boolean、byte、char、double、float、int、long、short、void、java.lang.Boolean.TYPE、java.lang.Byte.TYPE、java.lang.Character.TYPE、java.lang.Double.TYPE、java.lang.Float.TYPE、java.lang.Integer.TYPE、java.lang.Long.TYPE、java.lang.Short.TYPE、java.lang.Void.TPPE、Boolean、Byte、Character、Double、Float、Integer、Long、Short、null、string等。另外值類型還可以使用Call、Get、New、Ref、Array、Map、Property、SystemProperty定義。其中SystemProperty可以定義name和default屬性用于表示prop名和default的值。ref引用必須先定義,因而這里無法處理循環引用的問題。
使用
可以使用XmlConfiguration,給定一個或多個Properties、XML文件參數,在Command Line中直接啟動Jetty服務器。
XmlConfiguration也可以用于EnvConfiguration中,用于進一步配置WebAppContext,可以手動設置jettyEnvXmlUrl屬性,或默認使用WEB-INF/jetty-env.xml文件。
XmlConfiguration還用于JettyWebXmlConfiguration,他默認查找WEB-INF目錄下的jetty8-web.xml、jetty-web.xml、web-jetty.xml作為配置文件對WebAppContext做進一步的配置。
附錄
XmlConfiguration支持的XML文件格式使用configure_6_0.dtd文件定義:
<?xml version="1.0" encoding="ISO-8859-1"?><!--
This is the document type descriptor for the
org.eclipse.XmlConfiguration class. It allows a java object to be
configured by with a sequence of Set, Put and Call elements. These tags are
mapped to methods on the object to be configured as follows:
<Set name="Test">value</Set> == obj.setTest("value");
<Put name="Test">value</Put> == obj.put("Test","value");
<Call name="test"><Arg>value</Arg></Call> == obj.test("value");
Values themselves may be configured objects that are created with the
<New> tag or returned from a <Call> tag.
Values are matched to arguments on a best effort approach, but types
my be specified if a match is not achieved.
--><!ENTITY % CONFIG "Set|Get|Put|Call|New|Ref|Array|Map|Property"><!ENTITY % VALUE "#PCDATA|Get|Call|New|Ref|Array|Map|SystemProperty|Property"><!ENTITY % TYPEATTR "type CDATA #IMPLIED " > <!-- String|Character|Short|Byte|Integer|Long|Boolean|Float|Double|char|short|byte|int|long|boolean|float|double|URL|InetAddress|InetAddrPort| #classname --><!ENTITY % IMPLIEDCLASSATTR "class NMTOKEN #IMPLIED" ><!ENTITY % CLASSATTR "class NMTOKEN #REQUIRED" ><!ENTITY % NAMEATTR "name NMTOKEN #REQUIRED" ><!ENTITY % IMPLIEDNAMEATTR "name NMTOKEN #IMPLIED" ><!ENTITY % DEFAULTATTR "default CDATA #IMPLIED" ><!ENTITY % IDATTR "id NMTOKEN #IMPLIED" ><!ENTITY % REQUIREDIDATTR "id NMTOKEN #REQUIRED" ><!--
Configure Element.
This is the root element that specifies the class of object that
can be configured:
<Configure class="com.acme.MyClass">
</Configure>
--><!ELEMENT Configure (%CONFIG;)* ><!ATTLIST Configure %IMPLIEDCLASSATTR; %IDATTR; ><!--
Set Element.
This element maps to a call to a setter method or field on the current object.
The name and optional type attributes are used to select the setter
method. If the name given is xxx, then a setXxx method is used, or
the xxx field is used of setXxx cannot be found.
A Set element can contain value text and/or the value objects returned
by other elements such as Call, New, SystemProperty, etc.
If no value type is specified, then white
space is trimmed out of the value. If it contains multiple value
elements they are added as strings before being converted to any
specified type.
A Set with a class attribute is treated as a static set method invocation.
--><!ELEMENT Set ( %VALUE; )* ><!ATTLIST Set %NAMEATTR; %TYPEATTR; %IMPLIEDCLASSATTR; ><!--
Get Element.
This element maps to a call to a getter method or field on the current object.
The name attribute is used to select the get method.
If the name given is xxx, then a getXxx method is used, or
the xxx field is used if getXxx cannot be found.
A Get element can contain other elements such as Set, Put, Call, etc.
which act on the object returned by the get call.
A Get with a class attribute is treated as a static get method or field.
--><!ELEMENT Get (%CONFIG;)*><!ATTLIST Get %NAMEATTR; %IMPLIEDCLASSATTR; %IDATTR; ><!--
Put Element.
This element maps to a call to a put method on the current object,
which must implement the Map interface. The name attribute is used
as the put key and the optional type attribute can force the type
of the value.
A Put element can contain value text and/or value elements such as Call,
New, SystemProperty, etc. If no value type is specified, then white
space is trimmed out of the value. If it contains multiple value
elements they are added as strings before being converted to any
specified type.
--><!ELEMENT Put ( %VALUE; )* ><!ATTLIST Put %NAMEATTR; %TYPEATTR; ><!--
Call Element.
This element maps to an arbitrary call to a method on the current object,
The name attribute and Arg elements are used to select the method.
A Call element can contain a sequence of Arg elements followed by
a sequence of other elements such as Set, Put, Call, etc. which act on any object
returned by the original call:
<Call id="o2" name="test">
<Arg>value1</Arg>
<Set name="Test">Value2</Set>
</Call>
This is equivalent to:
Object o2 = o1.test("value1");
o2.setTest("value2");
A Call with a class attribute is treated as a static call.
--><!ELEMENT Call (Arg*,(%CONFIG;)*)><!ATTLIST Call %NAMEATTR; %IMPLIEDCLASSATTR; %IDATTR;><!--
Arg Element.
This element defines a positional argument for the Call element.
The optional type attribute can force the type of the value.
An Arg element can contain value text and/or value elements such as Call,
New, SystemProperty, etc. If no value type is specified, then white
space is trimmed out of the value. If it contains multiple value
elements they are added as strings before being converted to any
specified type.
--><!ELEMENT Arg ( %VALUE; )* ><!ATTLIST Arg %TYPEATTR; %IMPLIEDNAMEATTR; ><!--
New Element.
This element allows the creation of a new object as part of a
value for elements such as Set, Put, Arg, etc. The class attribute determines
the type of the new object and the contained Arg elements
are used to select the constructor for the new object.
A New element can contain a sequence of Arg elements followed by
a sequence of elements such as Set, Put, Call, etc. elements
which act on the new object:
<New id="o" class="com.acme.MyClass">
<Arg>value1</Arg>
<Set name="test">Value2</Set>
</New>
This is equivalent to:
Object o = new com.acme.MyClass("value1");
o.setTest("Value2");
--><!ELEMENT New (Arg*,(%CONFIG;)*)><!ATTLIST New %CLASSATTR; %IDATTR;><!--
Ref Element.
This element allows a previously created object to be referenced by id.
A Ref element can contain a sequence of elements such as Set, Put, Call, etc.
which act on the referenced object:
<Ref id="myobject">
<Set name="Test">Value2</Set>
</New>
--><!ELEMENT Ref ((%CONFIG;)*)><!ATTLIST Ref %REQUIREDIDATTR;><!--
Array Element.
This element allows the creation of a new array as part of a
value of elements such as Set, Put, Arg, etc. The type attribute determines
the type of the new array and the contained Item elements
are used for each element of the array:
<Array type="java.lang.String">
<Item>value0</Item>
<Item><New class="java.lang.String"><Arg>value1</Arg></New></Item>
</Array>
This is equivalent to:
String[] a = new String[] { "value0", new String("value1") };
--><!ELEMENT Array (Item*)><!ATTLIST Array %TYPEATTR; %IDATTR; ><!--
Map Element.
This element allows the creation of a new map as part of a
value of elements such as Set, Put, Arg, etc. The type attribute determines
the type of the new array and the contained Item elements
are used for each element of the array:
<Map>
<Entry>
<Item>keyName</Item>
<Item><New class="java.lang.String"><Arg>value1</Arg></New></Item>
</Entry>
</Map>
This is equivalent to:
Map m = new HashMap();
m.put("keyName", new String("value1"));
--><!ELEMENT Map (Entry*)><!ATTLIST Map %IDATTR; ><!ELEMENT Entry (Item,Item)><!--
Item Element.
This element defines an entry for the Array or Map Entry elements.
The optional type attribute can force the type of the value.
An Item element can contain value text and/or the value object of
elements such as Call, New, SystemProperty, etc. If no value type
is specified, then white space is trimmed out of the value.
If it contains multiple value elements they are added as strings
before being converted to any specified type.
--><!ELEMENT Item ( %VALUE; )* ><!ATTLIST Item %TYPEATTR; %IDATTR; ><!--
System Property Element.
This element allows JVM System properties to be retrieved as
part of the value of elements such as Set, Put, Arg, etc.
The name attribute specifies the property name and the optional
default argument provides a default value.
<SystemProperty name="Test" default="value" />
This is equivalent to:
System.getProperty("Test","value");
--><!ELEMENT SystemProperty EMPTY><!ATTLIST SystemProperty %NAMEATTR; %DEFAULTATTR; %IDATTR;><!--
Property Element.
This element allows arbitrary properties to be retrieved by name.
The name attribute specifies the property name and the optional
default argument provides a default value.
A Property element can contain a sequence of elements such as Set, Put, Call, etc.
which act on the retrieved object:
<Property name="Server">
<Call id="jdbcIdMgr" name="getAttribute">
<Arg>jdbcIdMgr</Arg>
</Call>
</Property>
--><!ELEMENT Property ((%CONFIG;)*)><!ATTLIST Property %NAMEATTR; %DEFAULTATTR; %IDATTR;> 一個簡單的例子(摘自:http://www.tkk7.com/xylz/archive/2012/04/12/372999.html):
<Configure id="Server" class="org.eclipse.jetty.server.Server">
<Set name="ThreadPool">
<New class="org.eclipse.jetty.util.thread.QueuedThreadPool">
<Set name="minThreads">10</Set>
<Set name="maxThreads">200</Set>
<Set name="detailedDump">false</Set>
</New>
</Set>
<Call name="addConnector">
<Arg>
<New class="org.eclipse.jetty.server.nio.SelectChannelConnector">
<Set name="host"><Property name="Inside in Jetty.host" /></Set>
<Set name="port"><Property name="Inside in Jetty.port" default="8080"/></Set>
<Set name="maxIdleTime">300000</Set>
<Set name="Acceptors">2</Set>
<Set name="statsOn">false</Set>
<Set name="confidentialPort">8443</Set>
<Set name="lowResourcesConnections">20000</Set>
<Set name="lowResourcesMaxIdleTime">5000</Set>
</New>
</Arg>
</Call>
<Set name="handler">
<New id="Handlers" class="org.eclipse.jetty.server.handler.HandlerCollection">
<Set name="handlers">
<Array type="org.eclipse.jetty.server.Handler">
<Item>
<New id="Contexts" class="org.eclipse.jetty.server.handler.ContextHandlerCollection"/>
</Item>
<Item>
<New id="DefaultHandler" class="org.eclipse.jetty.server.handler.DefaultHandler"/>
</Item>
</Array>
</Set>
</New>
</Set>
<Set name="stopAtShutdown">true</Set>
<Set name="sendServerVersion">true</Set>
<Set name="sendDateHeader">true</Set>
<Set name="gracefulShutdown">1000</Set>
<Set name="dumpAfterStart">false</Set>
<Set name="dumpBeforeStop">false</Set>
</Configure>
posted on 2014-05-24 22:12
DLevin 閱讀(2915)
評論(0) 編輯 收藏 所屬分類:
Jetty