Chapter 4. 设置 Seam 组件

翻译 2007年10月09日 08:42:00

seam中,对基于XML的设置予以简化,其作用是非常巨大的。然而,有很多原因,使我们应当用XML来设置seam组件:从java代码中分离出特定的部署信息,建立复用框架,设置seam的内建功能,等等。对于设置组件,Seam提供两种基本的途径:通过设置属性文件或web.xml里的属性,以及通过设置components.xml文件。

 

4.1.通过属性设定来设置组件

提供Seam组件时可以带有属性配置,它们是由servlet context参数,或者classpath根部的seam.properties文件提供的。可配置的seam组件必须为可配置的属性建立JavaBeans类型的setter方法。如果一个名称为com.jboss.myapp.settings seam组件有一个名称为setLocale()setter方法,我们就可以在seam.properties文件中提供一个名称为com.jboss.myapp.settings.locale的属性,seam在实例化这个组件时,将据此设置locale属性的值。

 

设置seam本身时也使用了这种机制,例如,为设置会话时间,我们在web.xmlseam.propertiesorg.jboss.seam.core.manager.conversationTimeout提供了一个值。(seam

中有一个名为org.jboss.seam.core.managerseam组件,它有一个名为setConversationTimeout()setter方法)

 

4.2.通过components.xml配置组件

 

components.xml文件比属性设定更强大一些。它可以让你:

设置已经自动安装的组件包括内建的组件,和用@Name标注了的和seam的部署扫描器安装的应用程序组件。

把没有用@Name标注的类安装为seam组件--这对某些特定的底层组件非常有用,这种底层组件可以用不同的名称安装多次(例如Seam-managed persistence contexts)。

安装确实有@Name标注,但是由于有@Install标注(表明这个组件不应该安装)默认没被安装的组件。

覆盖组件的生命期。

 

一个components.xml文件可能出现在以下位置:

• War文件的WEB-INF目录。

• Jar文件的META-INF目录。

包含具有@Name标注的类的jar文件的任何目录。

 

For example, the following components.xml file installs jBPM:

一般说来,当部署扫描器发现一个含有@Name标注的类,这个类在seam.properties META-INF/components.xml文件中作了登记,部署扫描器将安装这个类(除非这个组件@Instal标注,表明它默认不应安装)。components.xml文件允许我们处理需要覆盖标注的特殊情况。

 

例如,以下components.xml文件安装jBPM

 

<components xmlns="http://jboss.com/products/seam/components" 

            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

            xmlns:bpm="http://jboss.com/products/seam/bpm">

    <bpm:jbpm/>

</components>

 

下面例子将做同样的事:

 

<components>

    <component class="org.jboss.seam.bpm.Jbpm"/>

</components>

 

下面例子安装并设置两种不同的Seam-managed persistence contexts

 

<components xmlns="http://jboss.com/products/seam/components" 

            xmlns:persistence="http://jboss.com/products/seam/persistence"

 

    <persistence:managed-persistence-context name="customerDatabase"

                       persistence-unit-jndi-name="java:/customerEntityManagerFactory"/>

        

    <persistence:managed-persistence-context name="accountingDatabase"

                       persistence-unit-jndi-name="java:/accountingEntityManagerFactory"/>            

 

</components>

 

与以下例子作用相同:

 

<components>

    <component name="customerDatabase" 

              class="org.jboss.seam.persistence.ManagedPersistenceContext">

        <property name="persistenceUnitJndiName">java:/customerEntityManagerFactory</property>

    </component>

    

    <component name="accountingDatabase"

              class="org.jboss.seam.persistence.ManagedPersistenceContext">

        <property name="persistenceUnitJndiName">java:/accountingEntityManagerFactory</property>

    </component>

</components>

 

这个例子建立了一个session会话期的Seam-managed persistence context(实践中不推荐这么做):

 

<components xmlns="http://jboss.com/products/seam/components" 

            xmlns:persistence="http://jboss.com/products/seam/persistence"

 

  <persistence:managed-persistence-context name="productDatabase" 

                                          scope="session"

                     persistence-unit-jndi-name="java:/productEntityManagerFactory"/>        

 

</components>

<components>

            

    <component name="productDatabase"

              scope="session"

              class="org.jboss.seam.persistence.ManagedPersistenceContext">

        <property name="persistenceUnitJndiName">java:/productEntityManagerFactory</property>

    </component>

 

</components>

 

对基层对象,比如persistence contexts通常可以用auto-create 选项。使用persistence contexts的一个好处是,当你使用@In标注时,不必显式声明create=true

<components xmlns="http://jboss.com/products/seam/components" 

            xmlns:persistence="http://jboss.com/products/seam/persistence"

 

  <persistence:managed-persistence-context name="productDatabase" 

                                    auto-create="true"

                     persistence-unit-jndi-name="java:/productEntityManagerFactory"/>        

 

</components>

<components>

            

    <component name="productDatabase"

        auto-create="true"

              class="org.jboss.seam.persistence.ManagedPersistenceContext">

        <property name="persistenceUnitJndiName">java:/productEntityManagerFactory</property>

    </component>

 

</components>

 

 

<factory>声明用于指定一个值或方法表达式,以便在第一次被引用时初始化context变量的值。

 

<components>

 

    <factory name="contact" method="#{contactManager.loadContact}" scope="CONVERSATION"/>

 

</components>

 

可以为seam组件建立一个“别名”(第二个名字):

<components>

 

    <factory name="user" value="#{actor}" scope="STATELESS"/>

 

</components>

 

甚至可以为常用的表达式建立一个别名:

<components>

 

    <factory name="contact" value="#{contactManager.contact}" scope="STATELESS"/>

 

</components>

 

带有<factory> auto-create="true"参数的<factory>声明尤其常见:

<components>

 

    <factory name="session" value="#{entityManager.delegate}" scope="STATELESS" auto-create="true"/>

 

</components>

 

有时我们想在部署和测试时以最小的改变复用components.xmlseam允许你在components.xml文件中使用通配符@wildcard@,它可以被你的Ant build script(部署时)或被一个类路径下(部署时)名为compon-ents.properties文件替换。在seam例子中你会见到这种方式。

 

4.3. 细粒度配置文件

 

如果你需要用XML配置大量的组件,那么把components.xml中的信息分离开来是很有必要的。例如,可以把com.helloworld.Hello类的设置信息放到名为com/helloworld/Hello.component.xml的文件中。(你可能熟悉这种模式,因为这与Hibernate中的相同 该文件的根元素可以是<components> <component>

 

第一种方式你可以定义多个组件:

<components>

    <component class="com.helloworld.Hello" name="hello">

        <property name="name">#{user.name}</property>

    </component>

    <factory name="message" value="#{hello.message}"/>

</components>

第二种方式仅能定义或设置一个组件,但更简单:

<component name="hello">

<property name="name">#{user.name}</property>

</component>

 

第二种方式中,类名称由组件定义文件来暗示。

你也可以把com.helloworld 包中的所有类设置放到 com/helloworld/components.xml 中。


 

4.4. 可以设置的属性类型

如你所愿,可以设置的属性类型有string primitive primitive wrapper

 

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

<core:manager conversation-timeout="60000"/>

<component name="org.jboss.seam.core.manager">

    <property name="conversationTimeout">60000</property>

</component>

也支持Arrays, sets lists of strings primitives

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

<core:jbpm>

    <core:process-definitions>

        <value>order.jpdl.xml</value>

        <value>return.jpdl.xml</value>

        <value>inventory.jpdl.xml</value>

    </core:process-definitions>

</core:jbpm>

<component name="org.jboss.seam.bpm.jbpm">

    <property name="processDefinitions">

        <value>order.jpdl.xml</value>

        <value>return.jpdl.xml</value>

        <value>inventory.jpdl.xml</value>

    </property>

</component>

支持Even maps with String-valued keys string primitive 值:

<component name="issueEditor">

    <property name="issueStatuses">

        <key>open</key> <value>open issue</value>

        <key>resolved</key> <value>issue resolved by developer</value>

        <key>closed</key> <value>resolution accepted by user</value>

    </property>

</component>

最后,你可以用一个值绑定表达式将多个组件打包。注意,这与用@In 注入有很大不同,因为这发生在组件实例化之时,而非被调用之时。因此,这与传统的IoC容器,像JSF Spring提供的依赖注入环境(dependency injection facilities)更相似。

<drools:managed-working-memory name="policyPricingWorkingMemory" rule-base="#{policyPricingRules}"/>

<component name="policyPricingWorkingMemory"

          class="org.jboss.seam.drools.ManagedWorkingMemory">

    <property name="ruleBase">#{policyPricingRules}</property>

</component>

4.5. 使用XML 命名空间

在所有例子中,声明组件时有两种竞争的方式:用或者不用XML命名空间。下面的例子显示了一种典型的不用命名空间的components.xml

<?xml version="1.0" encoding="UTF-8"?>

<components xmlns="http://jboss.com/products/seam/components"

            xsi:schemaLocation="http://jboss.com/products/seam/components http://jboss.com/products/seam/components-2.0.xsd">

 

    <component class="org.jboss.seam.core.init">

        <property name="debug">true</property>

        <property name="jndiPattern">@jndiPattern@</property>

    </component>

    

</components>

这有点冗长。更糟的是,组件和属性在开发时是不可用的。

命名空间版像这样:

<?xml version="1.0" encoding="UTF-8"?>

<components xmlns="http://jboss.com/products/seam/components"

            xmlns:core="http://jboss.com/products/seam/core"

            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

            xsi:schemaLocation=

                "http://jboss.com/products/seam/core http://jboss.com/products/seam/core-2.0.xsd 

                 http://jboss.com/products/seam/components http://jboss.com/products/seam/components-2.0.xsd">

 

    <core:init debug="true" jndi-pattern="@jndiPattern@"/>

 

</components>

虽然对schema的声明较长,不过真正的XML内容较短且易懂。Schemas提供了关于每个组件和属性的详细信息,允许XML编辑器提供自动完成(intelligent autocomplete)功能。命名空间元素的使用使生成与维护正确的components.xml文件变得非常容易。

现在,对内建seam组件来说,这种机制已经非常完善,但是,用户组件如何呢?有两个选项。第一,seam支持两种模型的混合,允许对用户组件使用普通的<component>声明,同时对内建seam组件使用命名空间声明。更妙的是,seam允许对你自己的组件快速声明命名空间。

@Namespace标注过的任何Java package皆可以关联一个XML命名空间。(包目录中package-info.java文件可以声明Package-level annotations)这里是取自seampay演示的例子:

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

package org.jboss.seam.example.seampay;

 

import org.jboss.seam.annotations.Namespace;

这就是需要你在components.xml做的全部工作!现在我们可以这样写:

<components xmlns="http://jboss.com/products/seam/components"

            xmlns:pay="http://jboss.com/products/seam/examples/seampay"

            ... >

 

    <pay:payment-home new-instance="#{newPayment}"

                      created-message="Created a new payment to #{newPayment.payee}" />

 

    <pay:payment name="newPayment"

                 payee="Somebody"

                 account="#{selectedAccount}"

                 payment-date="#{currentDatetime}"

                 created-date="#{currentDatetime}" />

     ...

</components>

或者这样写:

<components xmlns="http://jboss.com/products/seam/components"

            xmlns:pay="http://jboss.com/products/seam/examples/seampay"

            ... >

 

    <pay:payment-home>

        <pay:new-instance>"#{newPayment}"</pay:new-instance>

        <pay:created-message>Created a new payment to #{newPayment.payee}</pay:created-message>

    </pay:payment-home>

    

    <pay:payment name="newPayment">

        <pay:payee>Somebody"</pay:payee>

        <pay:account>#{selectedAccount}</pay:account>

        <pay:payment-date>#{currentDatetime}</pay:payment-date>

        <pay:created-date>#{currentDatetime}</pay:created-date>

     </pay:payment>

     ...

</components>

这些例子演示了一个命名空间元素的两种使用模式。第一个声明中,<pay:payment-home>引用了paymentHome组件:

package org.jboss.seam.example.seampay;

...

@Name("paymentHome")

public class PaymentController

    extends EntityHome<Payment>

{

    ... 

}

元素名称是连字符型的组件名称。元素属性是连字符型的属性名称。

第二个声明中,<pay:payment>元素指的是org.jboss.seam.example.seampay包中的Payment类。在本例中,Payment是一个声明为seam组件的entity

package org.jboss.seam.example.seampay;

...

@Entity

public class Payment

    implements Serializable

{

    ...

}

如果我们想为用户定义的组件实现校验及自动完成功能,则需要一个schemaSeam还没有为一系列组件自动生成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

 

深入浅出JBoss Seam

本文节选了Michael Yuan和Thomas Heute所著的即将出版JBoss Seam: Power and Flexibility Beyond Java EE 5.0第一章和第二章,内容...
  • Huakelilinjie
  • Huakelilinjie
  • 2016年03月21日 10:11
  • 1283

开源Java EE框架 JBoss Seam 详细介绍

摘要:JBoss Seam是“Java EE 5.0的一个轻量级的框架”。这是什么意思?难道Java EE(Enterprise Edition) 5.0本身不是一套“框架吗”?为什么在官方规范之外,...
  • m_hahahaha1994
  • m_hahahaha1994
  • 2016年06月25日 08:24
  • 4178

图像接缝裁剪(seam carving)算法实现-SIGGRAPH 2007

seam carving是SIGGRAPH 2007数字图形学年会上,以色列两位教授提出的算法,用于实现“内容保留”的图像伸缩。 出自论文《Seam Carving for Content-Aware...
  • czl389
  • czl389
  • 2016年12月19日 19:21
  • 1427

jboss seam Qury组件实践:日期搜索及理解

一直没有实际动手做过seam中搜索相关的东西,最近实现了项目中根据时间搜索的一个功能,期间遇到了问题和疑惑以下做点记录,时间紧,简单记录。 ------------------------------...
  • u012514606
  • u012514606
  • 2014年11月25日 17:21
  • 555

rich:dataTable+a4j:commandLink,ajax删除行(seam)

  • wushuang5566110
  • wushuang5566110
  • 2012年02月14日 23:54
  • 2089

Jboss Seam3 Weld Jpa在J2SE中使用之三[LOG4J日志]

本不打算写这篇,LOG4J大家都会配置,不会的去面壁1小时。 写这张主要是因为导入hibernate3.jar后,发现hibernate3日全部是乱的。LOG4J无法启动,看了源码才知道,新版改用了s...
  • FENGUFO
  • FENGUFO
  • 2011年06月05日 09:24
  • 1847

seam+jsf+richfaces+ajax4jsf 电子书

  • 2009年11月17日 10:33
  • 5.59MB
  • 下载

chapter 6.1: driver 需要的组件

任何driver必须包含如下:     1.driver载入时的entry point     2.driver object     3.一至多个device     4.其他用来管理dev...
  • cyx1231st
  • cyx1231st
  • 2013年03月05日 20:32
  • 368

中文版 Adobe After Effects CS4 新增功能教程 Chapter.2.rar

  • 2013年05月02日 15:32
  • 35.07MB
  • 下载

The C++ Programming Language, 4th Edition: Chapter 2 C++ Basics

  • 2013年05月07日 12:04
  • 1.59MB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Chapter 4. 设置 Seam 组件
举报原因:
原因补充:

(最多只允许输入30个字)