jBPM jPDL 用户开发手册 - 第9章

9章Java EE 应用服务器工具

本章将描述jBPM提供的工具,它对Java EE基础架构起到一个杠杆的作用。

9.1. EJB

CommandServiceBean是一个无状态的会话bean,它在独立的jBPM上下文里通过调用它的execute方法执行jBPM命令。下表中总结了可定制的环境入口和资源。
名称
类型
描述
JbpmCfgResource
环境入口
用来读jBPM配置的类路径资源。可选,缺省是jbpm.cfg.xml。
ejb/LocalTimerEntityBean
EJB 引用
连接到实现任务服务的本地实体bean。当包含定时器时是流程需要。
jdbc/JbpmDataSource
资源管理器引用
给jBPM持久化服务提供JDBC连接的数据源的逻辑名。必须同hibernate配置文件中的hibernate.connection.datasource属性相匹配。
jms/JbpmConnectionFactory
资源管理器引用
给jBPM消息服务提供JMS连接的工厂的逻辑名称。包含同步连续的流程需要。
jms/JobQueue
消息目的引用
jBPM消息服务发送工作消息到这里引用的队列。为了确保这个和job监听器bean收到消息是同一个队列,message-destination-link指出一个通用的逻辑目标, JobQueue。

表 9-1 Command service bean环境

CommandListenerBean是一个在JbpmCommandQueue上用来监听命令消息消息驱动bean。这个bean为CommandServiceBean代理命令执行。
消息体必须是一个实现了org.jbpm.Command 接口的Java对象。消息属性,如果有的话,将被忽略。如果消息不匹配预期的格式,它被转进DeadLetterQueue中。不再进一步地处理那个消息。如果缺少目标引用的话,消息被拒绝。
这样收到的消息指定了一个replyTo目标,命令执行的结果就是打包消息对象并发送到那里。命令连接工厂环境引用显示JMS连接所支持的资源管理器。

相反,JobListenerBean是一个在JbpmJobQueue上用来监听工作消息的消息驱动bean来支持异步连续(asynchronous continuations)。

消息必须有一个叫jobId的长整数类型属性引用一个数据库中的待决的工作。对于消息体,如果有的话,可以忽略。
这个bean扩展CommandListenerBean并且可定制来继承它的环境入口和资源引用。
名称
类型
描述
ejb/LocalCommandServiceBean
EJB引用
链接到在独立的jBPM上下文上执行命令的本地会话baen。
jms/JbpmConnectionFactory
资源管理器引用
给产生结果消息的JMS连接提供本地工厂的逻辑命名。命令消息需要显示一个回复目标。

jms/DeadLetterQueue ce

消息目标引用
不包含命令的消息被送到这里引用的队列。可选的,如果没有的话,这消息将被驳回,可能导致容器再投递消息。

表 9-2 Command/Job监听器bean环境

TimerEntityBean同EJB定时器服务共同作用来调度jBPM定时器。在定时到期后,定时器的执行才真正地被委托给命令服务bean。

为了读取定时器的数据定时器的实体bean需要访问jBPM数据源。EJB部署符没有提供一种方式去定义如何让一个实体bean映射到一个数据库。这个留给了容器的提供器(provider)。在JBoss AS中,jbosscmp-jdbc.xml描述符定义数据源JNDI名和关系映射数据(它们中的表和列名)。注意JBoss XMP描述符使用一个全书JNDI名(java:JbpmDS),这和资源管理器引用形成对照(java:comp/env/jdbc/JbpmDataSource)。

jBPM较早版本使用一个叫TimerServiceBean的无状态会话bean同EJB定时器服务交互。这session方案不得不被放弃了因为在cancelation方法中有一个不可避免的瓶颈问题。因为会话bean没有身份,定时器服务被迫去迭代所有的定时器来查找出已经退出的。这个bean仍然是围绕着向后的兼容性。它像TimerEntityBean一样工作在相同的环境下,以至于更容易迁移。
名称
类型
描述
ejb/LocalCommandServiceBean
EJB引用

链接到独立的jBPM上下文中执行定时器的本地{@linkplain CommandServiceBean会话bean}。

表 9-2 Command/Job监听器bean环境

9.2. jBPM企业配置

jbpm.cfg.xml包含下列的配置项:
<jbpm-context>

  <service name="persistence"

           factory="org.jbpm.persistence.jta.JtaDbPersistenceServiceFactory" />

  <service name="message"

           factory="org.jbpm.msg.jms.JmsMessageServiceFactoryImpl" />

  <service name="scheduler"

           factory="org.jbpm.scheduler.ejbtimer.EntitySchedulerServiceFactory" />

</jbpm-context>
JtaDbPersistenceServiceFactor允许jBPM加入JTA事务。如果一个现有的事务正在进行的话,JTA持久化事务将保持它,否则它开始一个新的事务。jBPM企业bean配置为给窗口分派一个事务管理。然而,如果你在没有活动的事务的环境中创建一个JbpmContext的话(也就是说,在一个web应用中),一个事务将自动开始。JTA持久化服务工厂有个下面描述的配置域。

·           isCurrentSessionEnabled:如果是true,jBPM将使用同进行的JTA事务关联的“当前”Hibernate会话。这是缺省设置。参考Hibernate手册,2.5 Contextual sessions节描述了这个行为。你可以利用session机制的上下文关系来使用被jBPM在应用的其他部分通过调用SessionFactory.getCurrentSession()取得的同一个session。另一方面,你可以让jBPM支持你自己的hibernate session。这样做的话,设置isCurrentSessionEnabledfalse并通过JbpmContext.setSession(session)方法注入session。这也要确保jBPM同你应用的其他部分使用相同的Hibernate session。注意,Hibernate session可能通过持久化上下文注入到无状态的会话bean中。

·           isTransactionEnabled:这个域值为true意味着jBPM将通过Hibernate的事务APIHibernate手册的11.2数据库事务分界部分显示了这些API)用JbpmConfiguration.createJbpmContext()来创建事务,使用JbpmContext.close()来提交事务并关闭Hibernate会话。当jBPMpear来部署时这绝对不是一个期望的行为,因此isTransactionEnabled缺省情况下设置为false

JmsMessageServiceFactoryImpl对可靠的通信基础结构有一个杠杆作用通过暴露的JMS接口传递异步连续消息到JobListenerBeanJMS消息服务工厂暴露下列的配置域。
  • connectionFactoryJndiName: 在JNDI初始上下文中的JMS连接工厂的名字。对于Java缺省是:comp/env/jms/JbpmConnectionFactory
  • destinationJndiName: 工作消息将被传送那里JMS目标的名字。必须同JobListenerBean 接收消息的目标相匹配。对于java缺省是:comp/env/jms/JobQueue
  • isCommitEnabled: 告诉jBPM是否应该使用JbpmContext.close()提交JMS会话。消息被JMS消息服务产生,那就意味着(消息)在当前的事务提交前将从不会被接收。因此通过服务创建的JMS会话总是被处理。当在用的连接工厂是XA时缺省的值false是合适的,同样的JMS会话产生的消息将通过被全部的JTA事务控制。这个域应该被设置为true如果JMS连接工厂不是XA的话,因此jBPM将明确地提交这个JMS会话的本地事务。
EntitySchedulerServiceFactory构建在事务告知服务上,为EJB容器提供的定时事件调度企业流程定时器。EJB调度服务工厂有下面描述的可配置域。
  • timerEntityHomeJndiName: TimerEntityBean 在JNDI初始上下文中的本地home接口的名称。对于java缺省是:comp/env/ejb/LocalTimerEntityBean.

9.3. Hibernate企业配置

hibernate.cfg.xml包含下列被修改后去支持其他数据库或应用服务器的配置项目:

<!-- sql dialect -->

<property name="hibernate.dialect">org.hibernate.dialect.HSQLDialect</property>

 

<property name="hibernate.cache.provider_class">

  org.hibernate.cache.HashtableCacheProvider

</property>
 

<!-- DataSource properties (begin) -->

<property name="hibernate.connection.datasource">java:comp/env/jdbc/JbpmDataSource</property>

<!-- DataSource properties (end) -->

 

<!-- JTA transaction properties (begin) -->

<property name="hibernate.transaction.factory_class">

  org.hibernate.transaction.JTATransactionFactory

</property>

<property name="hibernate.transaction.manager_lookup_class">

  org.hibernate.transaction.JBossTransactionManagerLookup

</property>

<!-- JTA transaction properties (end) -->

 

<!-- CMT transaction properties (begin) ===

<property name="hibernate.transaction.factory_class">

  org.hibernate.transaction.CMTTransactionFactory

</property>

<property name="hibernate.transaction.manager_lookup_class">

  org.hibernate.transaction.JBossTransactionManagerLookup

</property>

==== CMT transaction properties (end) -->

你可以符合你的数据库管理系统的一个方言来替换hibernate.dialect。hibernate参考手册在3.4.1 SQL方言部分列举了可用的数据库方言。

HashtableCacheProvider能够使用其他支持的缓存提供器实替换。对于支持的缓存提供器列表可以查阅hibernate手册19.2 二级缓存部分。

JbossTransactionManagerLookup可以被一个策略替换适合的不同于JBoss的应用服务器。查看3.8.1 事务策略配置部分找到符合每个应用服务器的lookup类。

注意用于hibernate.connection.datasourceJNDI名称, 实际上,是一个资源管理器引用,可移植多应用服务器。也就是说引用意味着一个真正的数据源在部署时绑定到目标服务器上。在包含的jboss.xml描述符中,引用绑定到java:JbpmDS上。
默认包中,jBPM被配置使用JTATransactionFactory。如果一个现有的事务是正在进行中的话,JTATransaction工厂使用它,否则它创建一个新的事务。jBPM企业Bean被配置委派事务管理到容器上。然而,如果你使用的jBPM API在没有的事务活动事务的上下文中的话(也就是说,在一个web应用中),一个事务被将自动开始。
如果你自己的EJB容器管理事务并且你想限制非计划的事务创建的话,你可以切换到 CMTTransactionFactory。使用空上设置,hibernate将总是查找一个现有的事务并且如果什么也没有找到的话就汇报问题。

9.4. 客户端组件

客户组件依赖jBPM API编写,希望对企业服务确保他们的部署描述符在适当的位置有个合适的环境引用起到杠杆作用。
下面的描述符可以被看作典型的客户端会话Bean。
<session>
 

  <ejb-name>MyClientBean</ejb-name>

  <home>org.example.RemoteClientHome</home>

  <remote>org.example.RemoteClient</remote>

  <local-home>org.example.LocalClientHome</local-home>

  <local>org.example.LocalClient</local>

  <ejb-class>org.example.ClientBean</ejb-class>

  <session-type>Stateless</session-type>

  <transaction-type>Container</transaction-type>

 

  <ejb-local-ref>

    <ejb-ref-name>ejb/LocalTimerEntityBean</ejb-ref-name>

    <ejb-ref-type>Entity</ejb-ref-type>

    <local-home>org.jbpm.ejb.LocalTimerEntityHome</local-home>

    <local>org.jbpm.ejb.LocalTimerEntity</local>

  </ejb-local-ref>

 

  <resource-ref>

    <res-ref-name>jdbc/JbpmDataSource</res-ref-name>

    <res-type>javax.sql.DataSource</res-type>

    <res-auth>Container</res-auth>

  </resource-ref>

 

  <resource-ref>

    <res-ref-name>jms/JbpmConnectionFactory</res-ref-name>

    <res-type>javax.jms.ConnnectionFactory</res-type>

    <res-auth>Container</res-auth>

  </resource-ref>

 

  <message-destination-ref>

    <message-destination-ref-name>jms/JobQueue</message-destination-ref-name>

    <message-destination-type>javax.jms.Queue</message-destination-type>

    <message-destination-usage>Produces</message-destination-usage>

  </message-destination-ref>

 
</session>

被提供的目标服务器是JBoss,上面的环境引用可以像后面的那样被绑定资源在目标操作环境上。注意JNDI名称必须同jBPM Bean使用的值相匹配。

<session>
 

  <ejb-name>MyClientBean</ejb-name>

  <jndi-name>ejb/MyClientBean</jndi-name>

  <local-jndi-name>java:ejb/MyClientBean</local-jndi-name>

 

  <ejb-local-ref>

    <ejb-ref-name>ejb/LocalTimerEntityBean</ejb-ref-name>

    <local-jndi-name>java:ejb/TimerEntityBean</local-jndi-name>

  </ejb-local-ref>

 

  <resource-ref>

    <res-ref-name>jdbc/JbpmDataSource</res-ref-name>

    <jndi-name>java:JbpmDS</jndi-name>

  </resource-ref>

 

  <resource-ref>

    <res-ref-name>jms/JbpmConnectionFactory</res-ref-name>

    <jndi-name>java:JmsXA</jndi-name>

  </resource-ref>

 

  <message-destination-ref>

    <message-destination-ref-name>jms/JobQueue</message-destination-ref-name>

    <jndi-name>queue/JbpmJobQueue</jndi-name>

  </message-destination-ref>

 
</session>
假使客户端组件是一个web应用,与企业Bean形成对照,部署描述符看起来像这样:
<web-app>
 

  <servlet>

    <servlet-name>MyClientServlet</servlet-name>

    <servlet-class>org.example.ClientServlet</servlet-class>

  </servlet>

 

  <servlet-mapping>

    <servlet-name>MyClientServlet</servlet-name>

    <url-pattern>/client/servlet</url-pattern>

  </servlet-mapping>

 

  <ejb-local-ref>

    <ejb-ref-name>ejb/LocalTimerEntityBean</ejb-ref-name>

    <ejb-ref-type>Entity</ejb-ref-type>

    <local-home>org.jbpm.ejb.LocalTimerEntityHome</local-home>

    <local>org.jbpm.ejb.LocalTimerEntity</local>

    <ejb-link>TimerEntityBean</ejb-link>

  </ejb-local-ref>

 

  <resource-ref>

    <res-ref-name>jdbc/JbpmDataSource</res-ref-name>

    <res-type>javax.sql.DataSource</res-type>

    <res-auth>Container</res-auth>

  </resource-ref>

 

  <resource-ref>

    <res-ref-name>jms/JbpmConnectionFactory</res-ref-name>

    <res-type>javax.jms.ConnectionFactory</res-type>

    <res-auth>Container</res-auth>

  </resource-ref>

 

  <message-destination-ref>

    <message-destination-ref-name>jms/JobQueue</message-destination-ref-name>

    <message-destination-type>javax.jms.Queue</message-destination-type>

    <message-destination-usage>Produces</message-destination-usage>

    <message-destination-link>JobQueue</message-destination-link>

  </message-destination-ref>

 
</web-app>
如果目标应用服务器是JBoss的话,上面的环境引用能够像下面一样在目标操作的环境中绑定到资源上。
<jboss-web>
 

  <ejb-local-ref>

    <ejb-ref-name>ejb/LocalTimerEntityBean</ejb-ref-name>

    <local-jndi-name>java:ejb/TimerEntityBean</local-jndi-name>

  </ejb-local-ref>

 

  <resource-ref>

    <res-ref-name>jdbc/JbpmDataSource</res-ref-name>

    <jndi-name>java:JbpmDS</jndi-name>

  </resource-ref>

 

  <resource-ref>

    <res-ref-name>jms/JbpmConnectionFactory</res-ref-name>

    <jndi-name>java:JmsXA</jndi-name>

  </resource-ref>

 

  <message-destination-ref>

    <message-destination-ref-name>jms/JobQueue</message-destination-ref-name>

    <jndi-name>queue/JbpmJobQueue</jndi-name>

  </message-destination-ref>

 
</jboss-web>

 

 

昨天去医大看牙医了,要不昨天就能翻译完成的,可是没有...... :< ,还得今天起个大早

but all has got it! :~;

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值