熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> Java開源技術 >> 正文

設計心得——用 XDoclet 減少代碼膨脹

2022-06-13   來源: Java開源技術 

  開放源代碼的 XDoclet 代碼生成引擎是許多領先的 Java 框架不可缺少的組成部分常常被用作面向屬性的編程和持續集成的引擎但是 XDoclet 還有一些不太惹人注目的地方對初級開發人員來說它太難掌握太難精通在這篇文章中流行作者 Sing Li 以 XDoclet 為對象揭示了其內部簡單卻優雅的設計使您能夠理解這項技術並將它應用在實踐當中
  
  XDoclet 能夠很容易成為您的 Java 編程工具箱中的一個更加通用的跨技術代碼生成工具不幸的是開發人員經常忽視 XDoclet 的一般用途只有將它捆綁在大型開發框架或者 IDE 中作為其中的一個隱藏元素時才會用到它人們常常認為很難將 XDoclet 應用在定制解決方案上這篇文章的目的就是要消除這個迷惑把 XDoclet 從常見的復雜陷阱中解脫出來並向您展示了如何能夠利用這個代碼生成引擎
  
  我會用一個實際的例子演示 XDoclet 的用途該例子將接收一個 POJO(plain old Java object)並用 XDoclet 生成完整 Web 應用程序的全部文件這些文件是把數據輸入關系數據庫所必需的該示例使用了 XDoclet 的 自定義模板代碼生成功能以及它對 Hibernate 對象關系映射工具Struct Web 應用程序框架和應用程序服務器的內部支持(請參閱 參考資料)
  
  智能代碼生成器
  
  XDoclet 的核心功能是根據以下組合來生成代碼的(或者生成其他配置/數據文件)
  
  進行特殊標記的 Java 源文件
  
  預先定義的模板
  
  與其他基於模板的代碼生成技術(例如 Velocity請參閱 參考資料)相比XDoclet 具有以下獨特優勢
  
  XDoclet 與 Apache Ant(請參閱 參考資料)緊密集成從而提供了高度自動化的操作
  
  把控制代碼生成和模板處理的 XDoclet 標簽作為內聯注釋嵌入到 Java 源代碼文件中這消除了同步多個相關文件和控制文件的需要
  
  XDoclet 的內置 Java 解析器使用它對 Java 代碼結構的深入理解為輸入的 Java 代碼建立內部 結構模型該結構模型又經常被叫作 元數據(metadata)因為它包含與關聯代碼有關的數據
  
  XDoclet 的模板生成邏輯擁有對輸入 Java 代碼的內部結構模型的完全訪問權
  
  接下來我將進一步研究 XDoclet 是如何工作的以幫助您理解這些特性
  
  XDoclet 操作
  
  圖 顯示了 XDoclet 要求的輸入和生成的輸出
  
  
XDoclet 黑盒子

  
 

  您可以看到包含嵌入式 XDoclet 標簽的 Java 源代碼是系統的輸入在 Apache Ant 的驅動下XDoclet 處理輸入的代碼生成的輸出文本文件可以是 Java 源代碼HTML 頁面XML 文件等為了處理輸入XDoclet 需要使用模板(保存在 xdt 文件中)和標簽處理器(用 Java 編碼)XDoclet 把模板和標簽處理器打包成模塊不同的模塊處理不同的問題域
  
  XDoclet 生成的結構模型
  
  XDoclet 對包含嵌入式 XDoclet 標簽的輸入 Java 源代碼進行解析並為代碼建立非常詳細的結構模型結構模型中的每個元素都代表源代碼中的一個 Java 結構 顯示的結構模型揭示了 XDoclet 跟蹤的代碼構造和關系
  
  
XDoclet 的解析的 Java 源代碼的內部結構模型

  
 

  圖 中的結構模型跟蹤類接口方法之類的代碼構造(模型元素)該模型還跟蹤元素之間的關系例如繼承和接口實現以內聯注釋的形式嵌入在源代碼中的 XDoclet 標簽被解析為模型元素的屬性並被跟蹤
  
  通用的 Javadoc 引擎
  
  能夠理解 Java 代碼結構模型的智能代碼生成引擎不是什麼新概念實際上它是 JDK 自帶的 Javadoc 工具的運作方式通過解析帶有特殊 Javadoc 標簽的 Java 源文件Javadoc 工具可以為所有 Java 程序的內置結構元素(包括類接口字段和方法)生成 HTML 文檔Javadoc 還具有特殊 Java 語言概念方面的知識例如繼承抽象類存儲類和修飾符
  
  XDoclet 的誕生來自這樣一個觀察適用於任意代碼生成的 Javadoc 的通用版本在許多編程場合下會極為有用但是實際的 Javadoc 源代碼不是為通用的代碼生成設計的而只是為了生成 HTML 文檔由於無法重用現有代碼XDoclet 開發小組從頭開始重寫了引擎並顯著優化了它的性能
  
  深入 XDoclet
  
  圖 顯示了 XDoclet 的內部結構揭示了使其運行的功能塊
  
  
XDoclet 內部的功能塊

  
 

  如圖 所示Apache Ant 在運行的時候控制著 XDoclet 的配置和操作XDoclet 解析輸入的 Java 源代碼並在內存中生成結構模型模板引擎通過處理一組模板和標簽處理器生成輸出文件模板和標簽處理器可以是內置的也可以是定制的在代碼生成期間模板和標簽處理器擁有對結構模型的完全訪問
  
  XDoclet 虛假的復雜性
  
  XDoclet 實質上就是一個通用的 Javadoc 引擎(請參閱側欄 通用的 Javadoc 引擎)那麼是什麼讓它看起來這麼復雜呢?答案在於XDoclet 幾乎從未被單獨討論過而總是藏在其他許多復雜的技術中 顯示了了圍繞在 XDoclet 周圍的復雜性迷霧(請參閱側欄 為什麼 XDoclet 看起來比實際的要復雜得多)
  
  為什麼 XDoclet 看起來比實際的要復雜得多
  
  Apache Ant 自動進行 Java 軟件的生成過程構建管理過程通常是生產項目中更復雜過程中的一部分構建管理的術語和概念被集成到 Apache Ant 中而且是理解其操作的先決條件成熟的 Ant 腳本可能會非常復雜Ant 的每個新版本都會引入一些新的特性集從而進一步增加了復雜性這形成了 XDoclet 表面的復雜性因為 XDoclet 需要 Ant 才能執行
  
  XDoclet 處理的問題領域是復雜性的另一個來源在發布 XDoclet 的時候XDoclet 已經可以為 EJB 組件集成JEE Web 容器集成Hibernate 持久性層Struts 框架Java 管理擴展(JMX)等生成代碼這些問題領域中的每一個領域都有一大套該領域專用的行話和概念從這些復雜的問題領域出來的問題經常主導著 XDoclet 的討論這也提高了 XDoclet 表面的復雜性可能是只見森林不見樹木
  
  
XDoclet 的復雜耦合

  

  在圖 您可以看到 XDoclet 與以下內容是緊密相關的
  
  Apache Ant它控制著 XDoclet 的操作XDoclet 是作為一組 Ant 任務存在的沒有 Ant 則不能執行
  
  與生成文件關聯的具體問題領域的一些細節
  
  XDoclet 本身卻是驚人地簡單正如下面示例中的工作代碼所示的那樣
  
  使用 XDoclet
  
  現在您可以通過研究我向您提供的數據入口應用程序示例來觀察 XDoclet 的實際工作(要下載這個示例中使用的 Java 代碼XDoclet 模板和 Ant 腳本請單擊本文頂部或底部的 Code圖標或者請參閱 下載部分)我們將從檢查清單 所示的 Java 代碼開始這部分代碼表示了一個客戶的地址該地址被編碼成 JavaBean 組件其中的 XDoclet 標簽是以黑體字形式顯示的
  
  清單 用 XDoclet 標簽標記的 AddressBeanjava 源文件
  
  package comibmdwbeans; import javaioSerializable; /**     * @dwgenStrutsAction action=/addAddressdo * @hibernateclass table=ADDRESS*/ public class AddressBean implements Serializable { private String streetNumber = ; private String street = ; private String city = ; private String country = ; private String postalCode = ; private long id = ;  public AddressBean() { } /**     * @dwgenStruts formlabel=Street Number * @hibernateproperty length=*/ public String getStreetNumber() {  return streetNumber; } public void setStreetNumber(String inpStreetNumber) {  streetNumber = inpStreetNumber; } /**     * @dwgenStruts formlabel=Street * @hibernateproperty length=*/ public String getStreet() {   return street; } public void setStreet(String inpStreet) {  street = inpStreet; }      more Address bean properties /**     * @hibernateid generatorclass=native*/ public long getId( ) {     return id; } public void setId(long inId) {  id = inId; } }
  
  在清單 需要注意的是要把 XDoclet 標簽嵌入到注釋中緊放在相關代碼元素(例如字段方法接口或類)的前面在解析源代碼時XDoclet 會為每個標簽建立一個屬性並將該屬性附加到結構模型的代碼元素上現在請注意 ;@dwgenStruts 標簽因為這是在本例中將用到的第一個模板
  
  生成另外一個 Java 類
  
  對於本例您需要生成新的 Java 類的代碼 —— 一個 Struts 表單 beanStruts 會用這個 bean 保存並傳輸用戶輸入bean 必須以 bean 屬性的形式包含所有數據字段而且它必須是 orgapachestrutsactionActionForm 的子類
  
  為了生
From:http://tw.wingwit.com/Article/program/Java/ky/201311/28109.html
    Copyright © 2005-2022 電腦知識網 Computer Knowledge   All rights reserved.