配置Seam元件

梧桐雨—168發表於2008-04-19

Seam所崇尚的哲學是XML配置最小化。不過,基於不同的原因,我們有時候還是要利用XML來配置Seam元件。這些原因包括: 將Java程式碼與特定於部署的資訊分離;要建立可重用的框架;配置Seam的內建功能等等。 Seam提供了兩種基本的配置元件方法:通過在properties檔案或者 web.xml 中設定屬性來配置, 或者通過 components.xml 進行配置。

4.1. 通過屬性設定來配置元件

Seam元件的配置屬性可以通過兩種方式得到:通過servlet context引數,或者通過位於classpath下的 seam.properties 屬性檔案進行。

可配置的Seam元件必須為可配置的屬性暴露JavaBean風格的屬性setter方法。例如,一個名為 com.jboss.myapp.settings 的Seam元件擁有一個名為 setLocale() 的setter方法,我們就可以在 seam.properties 檔案中提供一個名為 com.jboss.myapp.settings.locale 的屬性,或者作為一個servlet context引數, 這樣,一旦該元件被例項化,Seam將自動為這個名為 locale 的屬性注入相應的值。

Seam本身的配置也採用了相同的機制。例如,要設定對話超時,我們可以在 web.xml 或者 seam.properties 中為 org.jboss.seam.core.manager.conversationTimeout 提供一個值。 (在Seam內建的元件 org.jboss.seam.core.manager 中,已經包含了一個名為 setConversationTimeout() 的setter方法。)

4.2. 通過 components.xml 來配置元件

components.xml 檔案的功能要比屬性設定的更強大一些。它讓你:

  • 配置那些已經被自動安裝的元件—包括內建元件以及那些帶有 @Name 註解, 且被Seam的部署掃描器識別到的那些應用元件。

  • 將那些沒有 @Name 註解的類安裝成為Seam元件— 這一點對於那些需要以不同的名字進行多次安裝的結構元件特別有用(例如,Seam管理的持久化上下文)。

  • 安裝那些 具有 @Name 註解,但是預設情況下未被安裝的Seam元件。 因為 @Install 註解表明該元件不應當被安裝。

  • 覆蓋元件的範圍。

components.xml 檔案可以出現在下面三個不同地方中的任何一處:

  • war 包的 WEB-INF 目錄下。

  • jar 包的 META-INF 目錄下。

  • 包含帶有 @Name 註解類的 jar 包下的任何目錄。

通常情況下,當Seam部署掃描器在包含 seam.properties 檔案或者 META-INF/components.xml 檔案的資料夾中識別到一個包含 @Name 註解的類時, Seam將安裝載該元件。(除非這個元件具有一個 @Install 註解,表示它不應該被預設安裝。) components.xml 檔案讓我們去處理那些需要覆蓋註解的特殊情況。

例如,下面的 components.xml 檔案安裝了jBPM:


    

這個例子實現了相同的功能:


    

這個例子安裝並配置了Seam管理的兩個不同的持久化上下文:



    

這個例子也一樣:


    
        java:/customerEntityManagerFactory
    

    
        java:/accountingEntityManagerFactory
    

這個例子建立了一個Seam管理的session範圍持久化上下文(這在實際專案中並不推薦使用)





    
        java:/productEntityManagerFactory
    

通常會給像持久化上下文這樣的基礎結構物件使用 auto-create 選項, 它能在你使用 @In 註解時,不必顯式地指定 create=true





    
        java:/productEntityManagerFactory
    

宣告讓你指定一個值或者方法來繫結一個表示式,當它第一次被引用時,將被執行用來初始化一個context變數的值。



    

你也可以為Seam元件建立一個別名(第二個名字),就像這樣:



    

你甚至可以給常用的表示式定義別名:



    

auto-create="true" 用在 宣告中尤其常見。



    

我們在部署或者測試期間,有時候想要通過略微的改動,來重用同一個 components.xml檔案。 Seam允許你在 components.xml 檔案中使用 @wildcard@ 形式的萬用字元, 這些萬用字元可以在部署的時候被Ant構建指令碼替換,也可以在開發時通過在classpath中提供一個名為 components.properties 的檔案進行替換。 你會在Seam的示例程式中找到這個用法。

4.3. 細粒度的配置檔案

如果你有大量的元件需要在XML中進行配置,那麼就很有必要將 components.xml 檔案中的內容分散到多個檔案中去。 Seam允許你把類(例如名為 com.helloworld.Hello )的配置放到一個資源中(名為 com/helloworld/Hello.component.xml)。 (你對這種模式可能很熟悉,因為它與我們在Hibernate中使用的相同)。 檔案的根元素應該是 或者

第一個選項允許你在一個檔案中定義多個元件:


    
        #{user.name}
    
    

第二個選項只允許你定義或者配置單個元件,不過麻煩會少一點:


    #{user.name}

在第二個選項中,類名與元件定義所在的檔案是一致的。

你還可以選擇將所有類的配置都放在 com/helloworld/components.xmlcom.helloworld 包中。

4.4. 可配置的屬性型別

String的屬性、基本型別以及基本型別的包裝型別可以像我們期望的那樣進行配置:

org.jboss.seam.core.manager.conversationTimeout 60000

    60000

也支援由String或者基本型別構成的陣列、Set和List:

org.jboss.seam.bpm.jbpm.processDefinitions order.jpdl.xml, return.jpdl.xml, inventory.jpdl.xml

    
        order.jpdl.xml
        return.jpdl.xml
        inventory.jpdl.xml
    

    
        order.jpdl.xml
        return.jpdl.xml
        inventory.jpdl.xml
    

甚至也支援那些包含String值為鍵、String或者基本型別值的Map:


    
        open open issue
        resolved issue resolved by developer
        closed resolution accepted by user
    

最後,你可以利用值繫結表示式來將所有的元件裝配起來。 注意這與使用 @In 註解進行注入非常不同,因為它是在元件初始化而不是被呼叫時起作用的。 因而它與傳統的IoC容器例如JSF或者Spring所提供的依賴注入功能非常非常類似。


    #{policyPricingRules}

4.5. 使用XML名稱空間

縱觀整個示例,有兩種完全不同的宣告元件的方式:使用或者不使用XML名稱空間。 下面的示例展示了一個典型的 components.xml 檔案,它沒有使用名稱空間,而是使用Seam Components DTD:




    
        true
        @jndiPattern@
    

正如你所見,這樣的配置有點繁瑣。更糟的是,這些元件和屬性的名稱在開發時是無法被校驗的。

使用名稱空間的配置看起來像這樣:




    

雖然Schema的宣告很繁瑣,不過實際的XML內容是清晰而簡單易懂的。 Schema提供了關於每個可用元件和屬性的詳細資訊,這使得XML編輯器可以發揮其自動完成的功效。 所以,使用名稱空間的元素使生成和維護正確的 components.xml 檔案都變得更加簡單。

現在,這種方式對於Seam內建的元件工作得很好,但是對於使用者自定義的元件又如何呢? 這裡有兩種選擇:第一種,Seam支援兩種模型的混合使用,允許使用普通的 宣告來配置使用者自定義的元件,同時也使用名稱空間來配置內建元件。 不過更好的方法是,Seam允許你快速地為你自己的元件宣告名稱空間。

任何Java包都可以通過用 @Namespace 註解該包,而與XML名稱空間而關聯起來。 (包級別的註解是在一個名為 package-info.java 的檔案中宣告的,該檔案處於包的同級目錄下)。 下面是一個來自seampay演示的例子:

@Namespace(value="http://jboss.com/products/seam/examples/seampay")
package org.jboss.seam.example.seampay;

import org.jboss.seam.annotations.Namespace;

這樣,你就可以在 components.xml 中使用名稱空間的方式了!現在,你可以這麼寫:



    

    
     ...

或者:



    
        "#{newPayment}"
        Created a new payment to #{newPayment.payee}
    

    
        Somebody"
        #{selectedAccount}
        #{currentDatetime}
        #{currentDatetime}
     
     ...

這些示例展示了名稱空間元素的兩種使用模式。 在第一個宣告中, 指向 paymentHome 元件。

package org.jboss.seam.example.seampay;
...
@Name("paymentHome")
public class PaymentController
    extends EntityHome
{
    ...
}

元素的名稱是連字元號(-)形式的元件名稱。元素的屬性是連字元號(-)形式的屬性名稱。

在第二個宣告中, 元素指向 org.jboss.seam.example.seampay 包中的 Payment 類。 在這個例子中,Payment 是一個被定義成Seam元件的實體。

package org.jboss.seam.example.seampay;
...
@Entity
public class Payment
    implements Serializable
{
    ...
}

如果我們需要使用者自定義元件的驗證和自動完成功能,我們就需要一個Schema。 目前Seam還無法提供為一組元件自動生成Schema的機制,所以你必需手工生成。標準Seam包的Schema定義可以當作示範。

以下是Seam所使用的名稱空間:

  • components — http://jboss.com/products/seam/components

  • core — http://jboss.com/products/seam/core

  • drools — http://jboss.com/products/seam/drools

  • framework — http://jboss.com/products/seam/framework

  • jms — http://jboss.com/products/seam/jms

  • remoting — http://jboss.com/products/seam/remoting

  • theme — http://jboss.com/products/seam/theme

  • security — http://jboss.com/products/seam/security

  • mail — http://jboss.com/products/seam/mail

  • web — http://jboss.com/products/seam/web

  • pdf — http://jboss.com/products/seam/pdf

  • spring — http://jboss.com/products/seam/spring

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/13270562/viewspace-244092/,如需轉載,請註明出處,否則將追究法律責任。

相關文章