XDoclet是生成配置文件的強(qiáng)有力的工具,在使用Spring框架時(shí),手動(dòng)編寫(xiě)Spring配置文件極其繁瑣,而且容易遺漏,利用XDoclet即可輕松生成配置文件。
XDoclet支持的Spring方法注入包括:ref,list,name和value。遺憾的是,在某個(gè)項(xiàng)目中,我需要注入一個(gè)包含Bean引用的List:
public void setHandlers(List handlers) {
? ...
}
然后,XDoclet并不支持元素為引用類型的List,倘若使用下列注釋:
/**
?* @spring.property list="articleHandler,imageHandler"
?*/
public void setHandlers(List handlers) {
? ...
}
生成的配置文件如下:
<property name="handlers">
? <list>
??? <value>articleHandler</value>
??? <value>imageHandler</value>
? </list>
</property>
毫無(wú)疑問(wèn),在Spring啟動(dòng)時(shí),一個(gè)ClassCastException將被拋出,因?yàn)闊o(wú)法將String類型轉(zhuǎn)化為我們自定義的Handler引用類型。
幸運(yùn)的是,XDoclet良好的可擴(kuò)展性使我們能夠輕松擴(kuò)展需要的配置,甚至不需要我們利用XDoclet提供的API編寫(xiě)代碼。XDoclet提供一種XML結(jié)構(gòu)的模版語(yǔ)言來(lái)生成配置文件,對(duì)于Spring配置文件,對(duì)應(yīng)的XML配置文件在xdoclet-spring-module-1.2.3.jar/xdoclet/modules/spring/resources/spring_xml.xdt中。
解開(kāi)jar包,修改spring_xml.xdt,增加如下XML片斷(紅色部分):
? <XDtMethod:forAllMethods superclasses="true">
?? <XDtMethod:ifHasMethodTag tagName="spring.property">
??? <property name="<XDtMethod:propertyName/>">
??? <XDtMethod:ifHasMethodTag tagName="spring.property" paramName="value">
????? <value><XDtMethod:methodTagValue tagName="spring.property" paramName="value"/></value>
??? </XDtMethod:ifHasMethodTag>
??? <XDtMethod:ifHasMethodTag tagName="spring.property" paramName="ref">
????? <ref bean="<XDtMethod:methodTagValue tagName="spring.property" paramName="ref"/>"/>
??? </XDtMethod:ifHasMethodTag>
??? <XDtMethod:ifHasMethodTag tagName="spring.property" paramName="list">
????? <list>
????? <XDtMethod:forAllMethodTagTokens tagName="spring.property" paramName="list">
??????? <value><XDtMethod:currentToken/></value>
????? </XDtMethod:forAllMethodTagTokens>
????? </list>
??? </XDtMethod:ifHasMethodTag>
??? <XDtMethod:ifHasMethodTag tagName="spring.property" paramName="list.ref">
????? <list>
??????? <XDtMethod:forAllMethodTagTokens tagName="spring.property" paramName="list.ref">
????????? <ref bean="<XDtMethod:currentToken/>"/>
??????? </XDtMethod:forAllMethodTagTokens>
????? </list>
??? </XDtMethod:ifHasMethodTag>
??? </property>
?? </XDtMethod:ifHasMethodTag>
? </XDtMethod:forAllMethods>
注意紅色部分的代碼,我們仿照l(shuí)ist,增加一個(gè)list.ref來(lái)實(shí)現(xiàn)引用類型的List。
現(xiàn)在,修改注釋如下:
/**
?* @spring.property list.ref="articleHandler,imageHandler"
?*/
public void setHandlers(List handlers) {
? ...
}
備份好原有的xdoclet-spring-module-1.2.3.jar,然后將修改后的目錄打包:
jar cvf xdoclet-spring-module-1.2.3.jar .
替換原來(lái)的xdoclet-spring-module-1.2.3.jar,運(yùn)行XDoclet,順利生成預(yù)期配置:
<property name="handlers">
? <list>
??? <ref bean="articleHandler"/>
??? <ref bean="imageHandler"/>
? </list>
</property>
類似的,我們還可以增加X(jué)Doclet對(duì)Map注入的支持。