<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    隨筆-295  評論-26  文章-1  trackbacks-0
    2007-07-18 Spring的事務通知???

    Spring2.0 可擴展XML配置初探

    關鍵字: Spring ? ????

    Spring 2.0版本支持擴展XML配置,著實興奮了一下,在我看來,Spring作為目前最流行的框架,不能擴展用戶自定義的配置,實在是Spring的一個很不爽的地方,<bean />的方式用起來比較通用,起碼到目前為止符合大部分人的使用習慣,并且能完成Spring所有的配置操作,但是對于第三方的提供商或則會經常擴展Spring功能的開發者來說,使用<bean />這樣的配置方式或許不是他們最想要的,他們需要使組件的配置更加直觀、易閱讀、易擴展……試想使用下面的配置方式

    代碼
    1. <mytag:datasource?id= "datasource" ? ??
    2. ???????databaseType= "oracle" ? ??
    3. ???????ip= "192.168.1.110" ? ??
    4. ???????port= "1521" ? ??
    5. ???????databaseName= "myDB" ??
    6. ???????userName= "admin" ??
    7. ???????password= "password" ??
    8. ???????/> ??
    9. ??
    10. <mytag:ehCache?id= "ehcache" ? ??
    11. ???????cache= "true" ? ??
    12. ???????maxElements= "100000" ? ??
    13. ???????timeToIdleSeconds= "120" ? ??
    14. ???????timeToLiveSeconds= "120" ??
    15. ???????overflowToDisk= "true" ??
    16. ???????/> ??

    上面的代碼中配置了兩個組件,datasource和cache組件,相比普通的bean&propertiy方式,很顯然,這種配置方式更直觀,更易讀,更重要的是,如果作為組件發布,使用者也可以很方便快捷的開始使用,而不需要關心組件的任何實現細節。

    擴展XML配置大致需要一下幾個步驟
    1、創建一個需要擴展的組件
    2、定義一個xsd文件描述組件內容
    3、創建一個文件,實現BeanDefinitionParser接口,用來解析xsd文件中的定義和組件定義
    4、創建一個Handler文件,擴展自NamespaceHandlerSupport,目的是將組件注冊到Spring容器
    5、編寫spring.handlers和spring.schemas文件

    提供一個簡單的例子,來說明如何去擴展一個Spring配置,需求如下:使用自定義標簽定義一個簡單的bean,這個bean有一個或多個屬性,標簽定義完成后,可以在其他項目中用自定義標簽來定義該bean。

    首先,創建一個需要擴展的組件,在這里只是一個簡單的bean,而且這個bean只有一個屬性age.
    One.java

    代碼
    1. package?com.mysite.tag; ??
    2. ??
    3. public?class?One?{ ??
    4. ????private?String?age; ??
    5. ???? ??
    6. ????public?One(){ ??
    7. ???????? ??
    8. ????} ??
    9. ??
    10. ????public?String?getAge()?{ ??
    11. ????????return?age; ??
    12. ????} ??
    13. ??
    14. ????public?void?setAge(String?age)?{ ??
    15. ????????this.age?=?age; ??
    16. ????} ??
    17. } ??

    然后,建立一個xsd文件,來描述這個bean
    mytag.xsd

    代碼
    1. <?xml?version="1.0"?encoding="UTF-8"?>??
    2. <xsd:schema?xmlns="http://www.mysite.org/schema/mytag"??
    3. ????????xmlns:xsd="http://www.w3.org/2001/XMLSchema"??
    4. ????????xmlns:beans="http://www.springframework.org/schema/beans"??
    5. ????????targetNamespace="http://www.mysite.org/schema/mytag"??
    6. ????????elementFormDefault="qualified"??
    7. ????????attributeFormDefault="unqualified">??
    8. ???? ??
    9. ????<xsd:import?namespace="http://www.springframework.org/schema/beans"/>??
    10. ???? ??
    11. ????<xsd:element?name="one">??
    12. ????????<xsd:complexType>??
    13. ????????????<xsd:complexContent>??
    14. ????????????????<xsd:extension?base="beans:identifiedType">??
    15. ????????????????????<xsd:attribute?name="age"?type="xsd:string"?default="99999"/>??
    16. ????????????????</xsd:extension>??
    17. ????????????</xsd:complexContent>??
    18. ????????</xsd:complexType>??
    19. ????</xsd:element>??
    20. </xsd:schema>??

    在上面的xsd文件描述了一個新的targetNamespace,并在這個空間中定義了一個name為one的element,one有一個age屬性,類型為string,默認值為99999.xsd文件是xml DTD的替代者,使用XML Schema語言進行編寫,這里對xsd schema不做太多解釋,有興趣可以參考相關的資料。

    創建一個Java文件,該文件實現了BeanDefinitionParser接口,用來解析xsd文件中的定義并注冊到組件中。
    MyBeanDefinitionParser.java

    代碼
    1. package?com.mysite.tag; ??
    2. ??
    3. import?org.springframework.beans.factory.config.BeanDefinition; ??
    4. import?org.springframework.beans.factory.config.BeanDefinitionHolder; ??
    5. import?org.springframework.beans.factory.support.BeanDefinitionReaderUtils; ??
    6. import?org.springframework.beans.factory.support.RootBeanDefinition; ??
    7. import?org.springframework.beans.factory.xml.BeanDefinitionParser; ??
    8. import?org.springframework.beans.factory.xml.ParserContext; ??
    9. import?org.w3c.dom.Element; ??
    10. ??
    11. public?class?MyBeanDefinitionParser?implements?BeanDefinitionParser{ ??
    12. ????public?BeanDefinition?parse(Element?arg0,?ParserContext?arg1)?{ ??
    13. ????????RootBeanDefinition?def?=?new?RootBeanDefinition(); ??
    14. ????????????????//設置Bean?Class ??
    15. ????????def.setBeanClass(One.class); ??
    16. ???????? ??
    17. ????????????????//注冊ID屬性 ??
    18. ????????String?id?=?arg0.getAttribute("id"); ??
    19. ????????BeanDefinitionHolder?idHolder=?new?BeanDefinitionHolder(def,id); ??
    20. ????????BeanDefinitionReaderUtils.registerBeanDefinition(idHolder,?arg1.getRegistry()); ??
    21. ???????? ??
    22. ????????????????//注冊age屬性 ??
    23. ????????String?age?=?arg0.getAttribute("age"); ??
    24. ????????BeanDefinitionHolder?ageHolder=?new?BeanDefinitionHolder(def,age); ??
    25. ????????BeanDefinitionReaderUtils.registerBeanDefinition(ageHolder,?arg1.getRegistry()); ??
    26. ????????def.getPropertyValues().addPropertyValue("age",?age); ??
    27. ???????? ??
    28. ????????return?def; ??
    29. ????} ??
    30. } ??
    31. ??

    上面的代碼僅僅實現了一個方法public BeanDefinition parse(Element arg0, ParserContext arg1),設置相關的Bean Class,解析了對應的xsd文件,并將解析的內容注冊到上下文中,同時返回一個BeanDefinition對象(BeanDefinition是Spring的bean定義,提供了bean部分的操作方法,如isSingleton()、isLazyInit()等)。

    注意,id屬性是一個默認的屬性,可以不在xsd文件中描述,但是需要注冊它,否則將無法通過getBean方法獲取標簽定義的bean,也無法被其他bean引用。
    另外,下面代碼是給bean的屬性賦值,這個是不可缺少的,否則在使用標簽定義時將無法獲取bean屬性的值。

    代碼
    1. def.getPropertyValues().addPropertyValue("age",?age); ??

    然后為組件編寫一個Handler文件,擴展自NamespaceHandlerSupport,它的作用是將組件注冊到Spring容器
    MyNameSpaceHandler.java

    代碼
    1. package?com.mysite.tag; ??
    2. ??
    3. import?org.springframework.beans.factory.xml.NamespaceHandlerSupport; ??
    4. ??
    5. public?class?MyNameSpaceHandler?extends?NamespaceHandlerSupport?{ ??
    6. ??
    7. ????public?void?init()?{ ??
    8. ?????????registerBeanDefinitionParser("one",new?MyBeanDefinitionParser()); ??
    9. ????} ??
    10. } ??

    實際執行的過程只有一句代碼,注冊了一個名字為one的擴展配置,包含了MyBeanDefinitionParser所parser相關xsd的內容。

    到了這里,一個Spring擴展標簽已經完成,但是我們目前還沒辦法使用它,Spring沒那么聰明,它無法知道我們在什么地方定義了哪些擴展標簽,這些標簽將被誰解析,這個過程要我們通過一些文件來告知Spring知道,它們就是spring.handlers和spring.schemas,它們放在META-INF目錄中,Spring.jar的META-INF目錄中也有同名的文件,它們的文件內容基本上是相似的,而Spring在執行過程中,如果發現其他jar文件的META-INF文件夾中包含有這兩個文件,Spring將會合并它們。
    spring.schemas

    代碼
    1. http\://www.mysite.org/schema/mytag.xsd=com/mysite/tag/mytag.xsd ??

    spring.handlers

    代碼
    1. http\://www.mysite.org/schema/mytag=com.mysite.tag.MyNameSpaceHandler ??

    spring.schemas將告訴Spring配置文件知道,如果在配置中引用http://www.mysite.org/schema/mytag.xsd,它應該去什么地方找相應的xsd文件。
    而spring.handlers文件將告訴Spring,應該使用哪個Handler注冊擴展標簽。

    現在為止,一個完整的xml擴展標簽全部完成,做一個小應用測試一下。
    將整個項目打包成jar文件(別忘記META-INF內的兩個文件),然后新建一個項目,引用剛才打包的jar文件,并引用Spring相關文件。
    需要注意,自定義xml擴展配置只有xsd方式的引用才可以使用.
    application.xml

    代碼
    1. <?xml?version="1.0"?encoding="UTF-8"?>??
    2. <beans?xmlns="http://www.springframework.org/schema/beans"??
    3. ????xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"??
    4. ????xmlns:tag="http://www.mysite.org/schema/mytag"??
    5. ????xsi:schemaLocation="http://www.springframework.org/schema/beans ??
    6. ????http://www.springframework.org/schema/beans/spring-beans-2.0.xsd ??
    7. ????http://www.mysite.org/schema/mytag ??
    8. ????http://www.mysite.org/schema/mytag.xsd">??
    9. ??
    10. ????<tag:one?id="oneBean"?age="99"/>??
    11. </beans>??

    在xml文件引用上可以看到,配置了一個名字為tag的名稱空間,目標為http://www.mysite.org/schema/mytag命名空間,這個目標名稱空間必須是存在于項目的引用中的(mytag.xsd中所定義的).
    代碼
    1. <tag:one?id="oneBean"?age="99"/> ??

    上面定義了一個id為oneBean的組件,使用了“one”擴展標簽,也就是我們在handler中所注冊的,組件age屬性的值為99。

    Main.java

    代碼
    1. package?com.test; ??
    2. ??
    3. import?org.springframework.context.ApplicationContext; ??
    4. import?org.springframework.context.support.ClassPathXmlApplicationContext; ??
    5. ??
    6. import?com.mysite.tag.One; ??
    7. ??
    8. public?class?Main?{ ??
    9. ??
    10. ????public?static?void?main(String[]?args)?{ ??
    11. ????????ApplicationContext?ctx?=?new?ClassPathXmlApplicationContext("application.xml"); ??
    12. ????????One?tag?=?(One)?ctx.getBean("oneBean"); ??
    13. ????????System.out.println("oneBean?age?is?"+tag.getAge()); ??
    14. ????} ??
    15. } ??

    運行測試程序,結果如下
    代碼
    1. oneBean?age?is?99??

    Spring的xml擴展是一個非常有用的特性,在Spring2.0的版本中也提供了一些新的標簽使用,如<aop>,<tx>等,但就目前來講受大家關注程度并不高,我想大部分使用Spring的開發人員都在使用Spring開發企業應用,而Spring所提供的<bean />定義的方式對于開發人員來說已經能夠滿足需要,但是如果看的更遠一些,在Spring以后的發展過程中,xml擴展應該會成為spring的核心特性之一,或許到時大家會習慣這樣的方式來編寫Spring配置文件吧

    代碼
    1. <XXCompany:XXXModule?id=""> ??
    2. ... ??
    3. ... ??

    最后更新:2007-07-18 16:03
    15:42??|?? 永久鏈接??|?? 瀏覽?(481)??|?? 評論?(2)??| ?? 收藏??|?? 進入論壇??|??
    評論 ???共 2 條 發表評論
    baallee ??? 2007-07-18 15:53

    代碼
    1. <? xml ? version = "1.0" ? encoding = "UTF-8" ?> ? ??
    2. < beans ? xmlns = "http://www.springframework.org/schema/beans" ???? ??
    3. xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" ???? ??
    4. xmlns:p = "http://www.springframework.org/schema/p" ???? ??
    5. xsi:schemaLocation ="http://www.springframework.org/schema/beans???????? ??
    6. http://www.springframework.org/schema/beans/spring-beans.xsd" > ?? ??
    7. < bean ? class = "com.interface21.spring2.ioc.Person" ????? ??
    8. p:name = "Tony" ???? ??
    9. p:age = "53" ????? ??
    10. p:house-ref = "number10" ? /> ??? ??
    11. < bean ? class = "com.interface21.spring2.ioc.House" ????? ??
    12. id = "number10" ???? ??
    13. p:name = "10?Downing?Street" /> ?? ??
    14. </ beans > ??

    對于簡單的應用可以用p標簽就好了。
    自定意擴展應該用在更多的高級應用上



    大盤預測 國富論
    posted on 2007-08-29 15:08 華夢行 閱讀(264) 評論(0)  編輯  收藏 所屬分類: Spring
    主站蜘蛛池模板: 亚洲色自偷自拍另类小说| 亚洲AV无码不卡在线播放| 特黄特色的大片观看免费视频| 亚洲精品人成网在线播放影院| 大陆一级毛片免费视频观看| 精品特级一级毛片免费观看| 亚洲中文字幕无码爆乳av中文| 99热在线观看免费| 亚洲精品无码久久久久牙蜜区| 国产亚洲精品不卡在线| 精品免费人成视频app| 美女的胸又黄又www网站免费| 亚洲AV无一区二区三区久久| 成人无遮挡裸免费视频在线观看| 一级一看免费完整版毛片| 亚洲欧洲日产韩国在线| 免费A级毛片无码久久版| 亚欧日韩毛片在线看免费网站| 亚洲成aⅴ人片久青草影院按摩| 国产v亚洲v天堂无码网站| 四虎免费大片aⅴ入口| 丝袜足液精子免费视频| 中文文字幕文字幕亚洲色| 综合亚洲伊人午夜网 | 国产免费MV大全视频网站| 亚洲欧洲日韩综合| 浮力影院亚洲国产第一页| 中文字幕人成无码免费视频| 国产免费一区二区三区免费视频| 亚洲国产精品日韩在线| 国产亚洲精aa成人网站| 四虎免费在线观看| 久久笫一福利免费导航| 日本免费人成网ww555在线| 国产精品亚洲片在线花蝴蝶| 亚洲经典在线中文字幕| 亚洲人成色7777在线观看| 最新69国产成人精品免费视频动漫| 三年片在线观看免费观看大全动漫| 免费一级毛suv好看的国产网站 | 国产午夜亚洲精品不卡电影|