paulwong

          My Links

          Blog Stats

          常用鏈接

          留言簿(67)

          隨筆分類(1389)

          隨筆檔案(1147)

          文章分類(7)

          文章檔案(10)

          相冊

          收藏夾(2)

          AI

          Develop

          E-BOOK

          Other

          養生

          微服務

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

          60天內閱讀排行

          EJB Descriptor

            比如,我們有一個Bank(銀行)類。Bank有兩個方法,deposit(存錢)和withdraw(取錢)。
            
            類和方法的定義如下:
             網管有家www.bitscn.net
            Code 2.1 Bank.java
            class Bank{
            public float deposit(AccountInfo account, float money){
             // 增加account賬戶的錢數,返回賬戶里當前的錢數
            }
            
            public float withdraw(AccountInfo account, float money){
             // 減少account賬戶的錢數,返回取出的錢數
            }
            };
            
            這兩個方法涉及到用戶的賬戶資金等重要信息,必須要非常小心,所以編寫完上面的商業邏輯之后,項目負責人又提出了新的要求--給Bank類的每個重要方法加上安全認證特性。
            
            于是,我們不得不分別在上面的兩個方法中加入安全認證的代碼。
            
            類和方法的定義如下:(新增加的代碼用不同的背景標出)
            
            Code 2.2 Bank.java
            class Bank{
            public float deposit(AccountInfo account, float money){
             // 驗證account是否為合法用戶
             // 增加account賬戶的錢數,返回賬戶里當前的錢數
            }
            
            public float withdraw(AccountInfo account, float money){
             // 驗證account是否為合法用戶
             // 減少account賬戶的錢數,返回取出的錢數
            }
            }; 
            
            這兩個方法都需要操作數據庫,為了保持數據完整性,項目負責人又提出了新的要求--給Bank類的每個操作數據庫的方法加上事務控制。
            
            于是,我們不得不分別在上面的兩個方法中加入安全認證的代碼。
            
            類和方法的定義如下:(新增加的代碼用不同的背景標出)
            
            Code 2.3 Bank.java
            class Bank{
            public float deposit(AccountInfo account, float money){
             // 驗證account是否為合法用戶
             // Begin Transaction
             // 增加account賬戶的錢數,返回賬戶里當前的錢數
             // End Transaction
            }
            
            public float withdraw(AccountInfo account, float money){
             // 驗證account是否為合法用戶
             // Begin Transaction
             // 減少account賬戶的錢數,返回取出的錢數
             // End Transaction
            }
            };
            
            我們看到,這些與商業邏輯無關的重復代碼遍布在整個程序中。實際的工程項目中涉及到的類和函數,遠遠不止兩個。如何解決這種問題?
            
            我們首先來看看OOP能否解決這個問題。
            
            我們利用Design Pattern的Template Pattern,可以抽出一個框架,改變上面的例子的整個設計結構。


            
            類和方法的定義如下:
            
            Code 2.4 Base.java
            abstract class Base{
            public float importantMethod(AccountInfo account, float money){
             // 驗證account是否為合法用戶
             // Begin Transaction
             
             float result = yourBusiness(account, money)
            
             // End Transaction
             return result;
            }
            
            protected abstract float yourBusiness(AccountInfo account, float money);
            };
            
            Code 2.5 BankDeposit.java
            class BankDeposit extends Base{
            protected float yourBusiness(AccountInfo account, float money){
             // 增加account賬戶的錢數,返回賬戶里當前的錢數
            }
            };
            
            Code 2.6 BankWithdraw.java
            class BankWithdraw extends Base{
            protected float yourBusiness(AccountInfo account, float money){
             // 減少account賬戶的錢數,返回取出的錢數
            }
            };
            
            這里我們用一種很勉強的方法實現了認證和事務代碼的重用。而且,有心的讀者可能會注意到,這種方法的前提是,強制所有的方法都遵守同樣的signature。


            
            如果有一個轉賬方法transfer(AccountInfo giver, AccountInfo receiver, float money),由于transfer方法的signature不同于yourBusiness的signature,這個方法無法使用上面的框架。
            
            這個例子中提到的認證,事務等方面,就是AOP所關心的Aspect。
            
            AOP就是為了解決這種問題而出現的。AOP的目的就是--Separation of Aspects (or Separation of Concerns).
            
            下面的章節,解釋EJB Descriptor,AspectJ,xDoclet等工具如何解決Separation of Aspects的問題。
            
            3.EJB Descriptor
            如果我們使用EJB實現上面的例子,Bank類可以作為一個Stateless Session Bean實現。
            
            在Bank的代碼中只用考慮商業邏輯,不用考慮認證和事務等方面。
            
            認證和事務等方面在EJB Descriptor中定義,由EJB Container提供這些方面的實現。
            
            我們來看一下,如何使用EJB Descriptor描述上面的例子。
            
            EJB Descriptor包括一個ejb-jar.xml文件。ejb-jar.xml文件包含兩大部分,enterprise-beans和assembly-descriptor部分。enterprise-beans部分包含EJB的定義--JNDI Name,EJB Home, Interface, Bean Class Path等;assembly-descriptor部分包括配置信息的定義--安全角色,事務控制等等。 
            
            下面給出上面例子對應的模擬EJB Descriptor。
            
            <ejb-jar>
            <enterprise-beans>
             <session>
               <ejb-name>Bank</ejb-name>
               …
               <ejb-class>example.Bank</ejb-class>
               <session-type>Stateless</session-type>
               <transaction-type>Container</transaction-type>
            <security-role-ref>
            <role-name>bank-account</role-name>
            </security-role-ref>
             </session>
            </enterprise-beans>
            
            <assembly-descriptor>
             <security-role>
              <role-name>bank-account</role-name>
             </security-role>
            
            <method-permission>
            <role-name>employee</role-name>
            <method>
            <ejb-name>Bank</ejb-name>
            <method-name>deposit</method-name>
            </method>
            <method>
            <ejb-name>Bank</ejb-name>
            <method-name>withdraw</method-name>
            </method>
            </method-permission> 
            
            <container-transaction>
            <method>
            <ejb-name>Bank</ejb-name>
            <method-name>deposit</method-name>
            </method>
            <method>
            <ejb-name>Bank</ejb-name>
            <method-name>withdraw</method-name>
            </method>
            
            <trans-attribute>Required</trans-attribute>
            </container-transaction>
            </assembly-descriptor>
            </ejb-jar>


            定義部署描述檔


              此篇文章適合的讀者以及內容

          此篇文章適合的讀者為Enterprise Bean提供者,例如,負責開發伺服器端的軟體 元件者。此篇文章描述Enterprise Bean提供者應該如何為他所寫的元件撰寫所需 的部署描述檔。

          此篇文章包含以下的內容:
          1. 此篇文章適合的讀者以及內容 <#Target>
          2. 原則 <#Princip>
          3. Session Bean描述檔範例 <#Exampl1>
          4. Container-managed Persistence(CMP) Entity Bean描述檔範例 <#Exampl2>
          5. 使用技巧 <#Tips>
          原則
          

          Enterprise bean的程式設計師負責提供所開發的Enterprise Bean所關聯的部署描 述檔。隨著Enterprise JavaBean應用程式開發與部署的生命週期的不同階段(開 發,彙合,部署),部署描述檔必須要被完成。

          
          

          Enterprise Bean提供者跟應用程式集合者的責任是提供XML部署描述檔,並符合 EJB 2.0規格裡所定義的XML部署檔的DTD。(詳見|$JONAS_ROOT/xml/ejb- jar_2_0.dtd|)。

          
          

          在EJB伺服器上部署Enterprise JavaBean時,可能還需要一些沒有定義在標準的 XML部署描述檔裡面的資訊。這些資訊包括如CMP Entity Bean所使用的資料庫的對 應資訊等。在部署階段的時候,這資訊是被指定的,另外在JOnAS特定的XML部署描 述檔裡。JOnAS特定的部署描述檔的XML DTD可以在|$JONAS_ROOT/xml/jonas-ejb- jar_X_Y.dtd|被找到。這個JOnAS特定的XML部署描述檔的名稱必須是用標準的XML 部署描述檔名前再加'jonas-'。

          在XML解析器去解析部署描述檔時,JOnAS對標籤做了特別的解釋。
          

          首先解析器會先試著去取得classpath裡指定的DTD檔案,然後才是透過指定的URL 或路徑去取得。

          
          

          範例:如下的兩個範例,XML解析器取得於JOnAS jar檔案裡的|jonas-ejb- jar_2_4.dtd|DTD檔案:

              <!DOCTYPE jonas-ejb-jar PUBLIC "-//ObjectWeb//DTD JOnAS 2.4//EN"
          "http://www.objectweb.org/jonas/dtds/jonas-ejb-jar_2_4.dtd";>
          <!DOCTYPE jonas-ejb-jar SYSTEM
          "/usr/local/jonas/xml/jonas-ejb-jar_2_4.dtd">
          

          標準的部署描述檔應該包含每個Enterprise Beas結構的資訊如下:
          * Enterprise bean的名稱,
          * Enterprise bean的類別,
          * Enterprise bean的Home介面,
          * Enterprise bean的Remote介面,
          * Enterprise bean的型別,
          * 重新加入Entity bean的指示,
          * Session bean的狀態管理型態,
          * Session bean的Transaction分界型態,
          * Entity bean的Persistence管理,
          * Entity bean的主鍵類別,
          * Container管理的欄位,
          * 環境項目,
          * Bean的EJB參考,
          * 資源管理員連線Factory參考,
          * Transaction的屬性。
          JOnAS特定的部署描述檔包含每個Enterprise Bean的資訊如下:
          * 實作Enterprise Bean中Home介面的Home物件之JNDI名稱,
          * 在Enterprise Beas類別中所參考到的資源管理員連線Factory,其所對應的
          DataSource物件的JNDI名稱,
          * 每個EJB參考的JNDI名稱,
          * JMS管理物件的JNDI名稱,
          * CMP Entity Bean所使用的資源庫的對應資訊。
          Session Bean部署描述檔範例
          <!DOCTYPE ejb-jar PUBLIC "-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0//EN"
          "http://java.sun.com/dtd/ejb-jar_2_0.dtd";>
          <ejb-jar>
          <description>Here is the description of the test's beans</description>
          <enterprise-beans>
          <session>
          <description>... Bean example one ...</description>
          <display-name>Bean example one</display-name>
          <ejb-name>ExampleOne</ejb-name>
          <home>tests.Ex1Home</home>
          <remote>tests.Ex1</remote>
          <ejb-class>tests.Ex1Bean</ejb-class>
          <session-type>Stateful</session-type>
          <transaction-type>Container</transaction-type>
          <env-entry>
          <env-entry-name>name1</env-entry-name>
          <env-entry-type>java.lang.String</env-entry-type>
          <env-entry-value>value1</env-entry-value>
          </env-entry>
          <ejb-ref>
          <ejb-ref-name>ejb/ses1</ejb-ref-name>
          <ejb-ref-type>session</ejb-ref-type>
          <home>tests.SS1Home</home>
          <remote>tests.SS1</remote>
          </ejb-ref>
          <resource-ref>
          <res-ref-name>jdbc/mydb</res-ref-name>
          <res-type>javax.sql.DataSource</res-type>
          <res-auth>Application</res-auth>
          </resource-ref>
          </session>
          </enterprise-beans>
          <assembly-descriptor>
          <container-transaction>
          <method>
          <ejb-name>ExampleOne</ejb-name>
          <method-name>*</method-name>
          </method>
          <trans-attribute>Required</trans-attribute>
          </container-transaction>
          <container-transaction>
          <method>
          <ejb-name>ExampleOne</ejb-name>
          <method-inter>Home</ejb-name>
          <method-name>*</method-name>
          </method>
          <trans-attribute>Supports</trans-attribute>
          </container-transaction>
          <container-transaction>
          <method>
          <ejb-name>ExampleOne</ejb-name>
          <method-name>methodOne</method-name>
          </method>
          <trans-attribute>NotSupported</trans-attribute>
          </container-transaction>
          <container-transaction>
          <method>
          <ejb-name>ExampleOne</ejb-name>
          <method-name>methodTwo</method-name>
          <method-params><method-param>int</method-param></method-params>
          </method>
          <trans-attribute>Mandatory</trans-attribute>
          </container-transaction>
          <container-transaction>
          <method>
          <ejb-name>ExampleOne</ejb-name>
          <method-name>methodTwo</method-name>
          <method-params><method-param>java.lang.String</method-param></method-params>
          </method>
          <trans-attribute>NotSupported</trans-attribute>
          </container-transaction>
          </assembly-descriptor>
          </ejb-jar>
          <!DOCTYPE jonas-ejb-jar PUBLIC "-//ObjectWeb//DTD JOnAS 2.4//EN"
          "http://www.objectweb.org/jonas/dtds/jonas-ejb-jar_2_4.dtd";>
          <jonas-ejb-jar>
          <jonas-session>
          <ejb-name>ExampleOne</ejb-name>
          <jndi-name>ExampleOneHome</jndi-name>
          <jonas-ejb-ref>
          <ejb-ref-name>ejb/ses1</ejb-ref-name>
          <jndi-name>SS1Home_one</jndi-name>
          </jonas-ejb-ref>
          <jonas-resource>
          <res-ref-name>jdbc/mydb</res-ref-name>
          <jndi-name>jdbc_1</jndi-name>
          </jonas-resource>
          </jonas-session>
          </jonas-ejb-jar>
          

              Container-managed Persistence Entity Bean描述檔範例(CMP 1.1)
          <!DOCTYPE ejb-jar PUBLIC "-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0//EN"
          "http://java.sun.com/dtd/ejb-jar_2_0.dtd";>
          <ejb-jar>
          <description>Here is the description of the test's beans</description>
          <enterprise-beans>
          <entity>
          <description>... Bean example one ...</description>
          <display-name>Bean example two</display-name>
          <ejb-name>ExampleTwo</ejb-name>
          <home>tests.Ex2Home</home>
          <remote>tests.Ex2</remote>
          <ejb-class>tests.Ex2Bean</ejb-class>
          <persistence-type>Container</persistence-type>
          <prim-key-class>tests.Ex2PK</prim-key-class>
          <reentrant>False</reentrant>
          <cmp-version>1.x</cmp-version>
          <cmp-field>
          <field-name>field1</field-name>
          </cmp-field>
          <cmp-field>
          <field-name>field2</field-name>
          </cmp-field>
          <cmp-field>
          <field-name>field3</field-name>
          </cmp-field>
          <primkey-field>field3</primkey-field>
          <env-entry>
          <env-entry-name>name1</env-entry-name>
          <env-entry-type>java.lang.String</env-entry-type>
          <env-entry-value>value1</env-entry-value>
          </env-entry>
          </entity>
          </enterprise-beans>
          <assembly-descriptor>
          <container-transaction>
          <method>
          <ejb-name>ExampleTwo</ejb-name>
          <method-name>*</method-name>
          </method>
          <trans-attribute>Supports</trans-attribute>
          </container-transaction>
          </assembly-descriptor>
          </ejb-jar>
          <!DOCTYPE jonas-ejb-jar PUBLIC "-//ObjectWeb//DTD JOnAS 2.4//EN"
          "http://www.objectweb.org/jonas/dtds/jonas-ejb-jar_2_4.dtd";>
          <jonas-ejb-jar>
          <jonas-entity>
          <ejb-name>ExampleTwo</ejb-name>
          <jndi-name>ExampleTwoHome</jndi-name>
          <jdbc-mapping>
          <jndi-name>jdbc_1</jndi-name>
          <jdbc-table-name>YourTable</jdbc-table-name>
          <cmp-field-jdbc-mapping>
          <field-name>field1</field-name>
          <jdbc-field-name>dbf1</jdbc-field-name>
          </cmp-field-jdbc-mapping>
          <cmp-field-jdbc-mapping>
          <field-name>field2</field-name>
          <jdbc-field-name>dbf2</jdbc-field-name>
          </cmp-field-jdbc-mapping>
          <cmp-field-jdbc-mapping>
          <field-name>field3</field-name>
          <jdbc-field-name>dbf3</jdbc-field-name>
          </cmp-field-jdbc-mapping>
          <finder-method-jdbc-mapping>
          <jonas-method>
          <method-name>findByField1</method-name>
          </jonas-method>
          <jdbc-where-clause>where dbf1 = ?</jdbc-where-clause>
          </finder-method-jdbc-mapping>
          </jdbc-mapping>
          </jonas-entity>
          </jonas-ejb-jar>
          

              使用技巧
          有一些字元,如"<"和"&"在XML資料裡嚴格來說是不合法的。
          其他像">"則是合法的,但習慣上最好將這些字元置換成XML的實體對應。
          以下列示出XML裡事先定義好的實體對應:
          &lt;        <    小於
          &gt;        >    大於
          &amp;       &   And符號
          &apos;      '       單引號
          &quot;      "  雙引號
          

          posted on 2008-12-06 16:29 paulwong 閱讀(202) 評論(0)  編輯  收藏 所屬分類: J2EE

          主站蜘蛛池模板: 泸西县| 庆元县| 东台市| 旅游| 伽师县| 札达县| 裕民县| 浠水县| 汕尾市| 湘潭县| 丰顺县| 札达县| 南部县| 临澧县| 红原县| 武穴市| 昌图县| 农安县| 南涧| 上思县| 苏州市| 紫阳县| 资溪县| 图木舒克市| 廊坊市| 武宣县| 扎赉特旗| 阿拉尔市| 怀化市| 门头沟区| 潜江市| 平凉市| 镇赉县| 驻马店市| 鸡东县| 漳浦县| 安仁县| 汉寿县| 西平县| 崇州市| 乐至县|