JBPM3.2与Spring结合时任务调度的实现[收藏]

JBPM3.2Spring结合时任务调度的实现

 

Jbpm3.1.x的时候,如果我们要实现JbpmSpring结合使用需要借助于SpringModulespring-modules-jbpm31.jar来实现。目前Jbpm的最新版本是 3.2.1 ,对于这一版本如果我们要实现其与Spring结合使用,同样我们也可以借助SpringModulespring-modules-jbpm31.jar来实现。

首先我们需要下载spring-modules-0.8工程包文件(下载地址:http://springmodules.dev.java.net),下载后我们只需要工程包里的spring-modules-jbpm31.jar把它放在我们Web应该的WEB-INF/lib目录下,我们知道该包是为Jbpm3.1准备的,但在Jbpm3.2中我们还是可以借助该包实现与Spring结合。

打开WEB应该里的web.xml文件,加上Jbpm3.2任务调试的Servlet,配置信息如下:

         <!-- JbpmJobExecutorServlet -->

         <servlet>

                   <servlet-name>JobExecutorServlet</servlet-name>

                   <servlet-class>

                            org.jbpm.job.executor.JobExecutorServlet

                   </servlet-class>

                   <load-on-startup>3</load-on-startup>

         </servlet>

 

         <servlet-mapping>

                   <servlet-name>JobExecutorServlet</servlet-name>

                   <url-pattern>/jobs</url-pattern>

         </servlet-mapping>

Jbpm3.2中任务调度的配置和Jbpm3.1.x中任务调度配置方法与原理基本相同。在Jbpm3.1.x中任务调度我们可以认为就是一个后台线程在不停的监听着timer(jbpm_timer),如果有需要触发的timer生成了,就按照timer的属性定时或者循环触发它。Jbpm3.1.x中我们是按下面的方法配置任务调度的servlet的:

         <servlet>

                   <servlet-name>SchedulerServlet</servlet-name>

                   <servlet-class>

                            org.jbpm.scheduler.impl.SchedulerServlet

                   </servlet-class>

                   <init-param>

                            <param-name>interval</param-name>

                            <param-value>5000</param-value>

                   </init-param>

                   <init-param>

                            <param-name>historyMaxSize</param-name>

                            <param-value>50</param-value>

                   </init-param>

                   <load-on-startup>1</load-on-startup>

         </servlet>

         <servlet-mapping>

                   <servlet-name>SchedulerServlet</servlet-name>

                   <url-pattern>/jbpmscheduler</url-pattern>

         </servlet-mapping>

 

Jbpm3.2中已经取消了jbpm_timer表,取而代之的是jbpm_job表。也就是说我们可以理解成后台有一个线程在不停的监听着jbpm_job表,如果有需要触发的timer生成了,就按照timer的属性定时或者循环触发它。比较一下两个不同版本的的配置3.1.x里用的是org.jbpm.scheduler.impl.SchedulerServlet,而3.2里用的是org.jbpm.job.executor.JobExecutorServlet这是最明显的不同之处,另外关于扫描表的周期值等相关参数3.1.x是直接设置在servlet里,而3.2里则是配置在jbpm.cfg.xml:

  <bean name="jbpm.job.executor" class="org.jbpm.job.executor.CustomJobExecutor">

    <field name="jbpmConfiguration"><ref bean="jbpmConfiguration" /></field>

    <!--field name="jbpmConfiguration"><ref bean="jbpmConfiguration" /></field-->

    <field name="name"><string value="JbpmJobExector" /></field>

    <field name="nbrOfThreads"><int value="1" /></field>

    <field name="idleInterval"><int value="5000" /></field>

    <field name="maxIdleInterval"><int value="3600000" /></field> <!-- 1 hour -->

    <field name="historyMaxSize"><int value="20" /></field>

    <field name="maxLockTime"><int value="600000" /></field> <!-- 10 minutes -->

    <field name="lockMonitorInterval"><int value="60000" /></field> <!-- 1 minute -->

    <field name="lockBufferTime"><int value="5000" /></field> <!-- 5 seconds -->

  </bean>

 

到这里为止Jbpm的任务的Servlet配置已经完成了,如果直接使用hibernate.cfg.xml来连接数据库的话那我们上面的配置就够了。如果我们使用Spring,那还有一些工作要完成。接下来要看一下怎么去在Spring中配置Jbpm

首先我们要在Spring的配置文件里配置好HibernateSessionFacotry等相关信息:

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

<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"

 "http://www.springframework.org/dtd/spring-beans.dtd">

 

<beans>

         <bean id="propertyConfigurer"         class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">

                   <property name="locations">

                            <list>

                                     <value>WEB-INF/configs/jdbc.properties</value>

                            </list>

                   </property>

         </bean>

        

         <!-- configuration datasource -->

        

<!—配置数据源-->

         <bean id="dataSource"

                   class="org.apache.commons.dbcp.BasicDataSource"

                   destroy-method="close">

                   <property name="driverClassName"

                            value="${jdbc.driverClassName}" />

                   <property name="url" value="${jdbc.url}" />

                   <property name="username" value="${jdbc.username}" />

                   <property name="password" value="${jdbc.password}" />

         </bean>

        

         <!—利用数据源配置HibernateSessionFactory -->

         <bean id="sessionFactory"

                   class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">

                   <property name="dataSource">

                            <ref local="dataSource" />

                   </property>

 

<!—-设置Jbpmcfg.xml文件的映射,这里从jbpm-jpdl.jar里读取cfg.xml文件-->

                   <property name="mappingJarLocations">

                            <list>

                                     <value>WEB-INF/lib/jbpm-jpdl.jar</value>

                            </list>

                   </property>

 

                   <property name="hibernateProperties">

                            <props>

                                     <prop key="hibernate.dialect">

                                               org.hibernate.dialect.MySQL5Dialect

                                     </prop>

                                     <prop key="hibernate.show_sql">false</prop>

                                     <prop key="hibernate.cache.provider_class">org.hibernate.cache.HashtableCacheProvider</prop>

                            </props>

                   </property>

         </bean>

</beans>

接下来我们要把spring-modules-jbpm31.jar中提供的JbpmConfiguration配置进去:

         <!-- jBPM configuration -->

         <bean id="jbpmConfiguration"

         class="org.springmodules.workflow.jbpm31.LocalJbpmConfigurationFactoryBean">

                   <property name="sessionFactory" ref="sessionFactory" />

                   <property name="configuration" value="classpath:jbpm.cfg.xml" />

                   <property name="createSchema" value="false" />

         </bean>

 

         <bean id="jbpmTemplate"

                   class="org.springmodules.workflow.jbpm31.JbpmTemplate">

                   <constructor-arg index="0" ref="jbpmConfiguration" />

         </bean>

这里我们把spring-modules-jbpm31.jar中提供的JbpmTemplate配置进去,这里需要解释一下JbpmTemplate是在Spring中访问Jbpm相关方法的接口对象,利用JbpmTemplate我们可以快速操作Jbpm里提供的方法接口:

public ProcessInstance findProcessInstance(final Long processInstanceId) {

  return (ProcessInstance) jbpmTemplate.execute(new JbpmCallback() {

     public Object doInJbpm(JbpmContext context) {

      // do something

      ...

      return context.getGraphSession().loadProcessInstance(processInstanceId.longValue());

     }

  });

}

接下来我们可以启动工程测试一下,启动过程中我们发现有异常抛出来,告诉我们说找不到hibernate.cfg.xml文件,同时我们也看到该错误是由org.jbpm.job.executor.JobExecutorServlet该类抛出来的,为了修正该错误我们对其修改如下:

package org.jbpm.job.executor;

 

import java.io.IOException;

import java.io.PrintWriter;

import java.util.Collection;

import java.util.Iterator;

 

import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

 

import org.jbpm.JbpmConfiguration;

import org.springframework.web.context.support.WebApplicationContextUtils;

import org.springmodules.workflow.jbpm31.JbpmTemplate;

 

public class JobExecutorServlet extends HttpServlet {

 

         private static final long serialVersionUID = 1L ;

 

         JbpmConfiguration jbpmConfiguration;

//修改了JobExecutorServlet里获取JbpmConfiguration的方式

         public void init() throws ServletException {

                   JbpmTemplate jbpmTemplate = (JbpmTemplate) WebApplicationContextUtils

                                     .getWebApplicationContext(this.getServletContext()).getBean(

                                                        "jbpmTemplate");

                   jbpmConfiguration = jbpmTemplate.getJbpmConfiguration();

                   jbpmConfiguration.startJobExecutor();

         }

 

         protected void doGet(HttpServletRequest request,

                            HttpServletResponse response) throws ServletException, IOException {

                   PrintWriter out = response.getWriter();

                   out.println("<html>");

                   out.println("<body>");

                   out.println("<h2>JBoss jBPM Scheduler Servlet</h2><hr />");

                   Collection threads = jbpmConfiguration.getJobExecutor().getThreads()

                                     .values();

                   Iterator iter = threads.iterator();

                   while (iter.hasNext()) {

                            Thread thread = (Thread) iter.next();

                            out.println("<h4>" + thread.getName() + "</h4>");

                            out.println("<b>isAlive</b>:" + thread.isAlive());

                   }

                   out.println("</body>");

                   out.println("</html>");

         }

}

在红色的代码块里,我们修改了JobExecutorServlet里获取JbpmConfiguration的方式。

再次启动工程,还是有异常发生,主要原因是JobExecutorServlet里获取了JbpmConfiguration对象后调用了startJobExecutor方法:

  public void startJobExecutor() {

    getJobExecutor().start();

  }

 

  public synchronized JobExecutor getJobExecutor() {

    if (jobExecutor==null) {

      try {

        jobExecutor = (JobExecutor) this.objectFactory.createObject("jbpm.job.executor");

      } catch (ClassCastException e) {

        throw new JbpmException("jbpm configuration object under key 'jbpm.job.executor' is not a "+JobExecutor.class.getName(), e);

      }

    }

    return jobExecutor;

  }

深入其代码,我们明白了它报错的原因是JobExecutor是从jbpm.cfg.xml里来的:

<bean name="jbpm.job.executor" class="org.jbpm.job.executor.JobExecutor">

    <field name="jbpmConfiguration"><ref bean="jbpmConfiguration" /></field>

    <field name="name"><string value="JbpmJobExector" /></field>

    <field name="nbrOfThreads"><int value="1" /></field>

    <field name="idleInterval"><int value="5000" /></field>

    <field name="maxIdleInterval"><int value="3600000" /></field> <!-- 1 hour -->

    <field name="historyMaxSize"><int value="20" /></field>

    <field name="maxLockTime"><int value="600000" /></field> <!-- 10 minutes -->

    <field name="lockMonitorInterval"><int value="60000" /></field> <!-- 1 minute -->

    <field name="lockBufferTime"><int value="5000" /></field> <!-- 5 seconds -->

  </bean>

我们看到里面有<field name="jbpmConfiguration"><ref bean="jbpmConfiguration" /></field>因为我们没有采用Hibernate.cfg.xml,所以在JobExecutor得不到jbpmConfiguration对象所致,因此我们需要在调用JobExecutor时对JobExecutor里的jbpmConfiguration进行初始化,这里我们选择对JobExecutor类进行扩展,而不是对其进行修改,扩展的代码类如下:

package org.jbpm.job.executor;

 

import org.jbpm.JbpmConfiguration;

 

public class CustomJobExecutor extends JobExecutor{

         public static JbpmConfiguration jbpmConfig;

         public synchronized void start() {

                   jbpmConfiguration = jbpmConfig;

                   super.start();

         }

         public static void setJbpmConfiguration(JbpmConfiguration config){

                   jbpmConfig=config;

         }

}

同时对JobExecutorServlet做修改,主要目的是在该servlet进行初始化时为CustomJobExecutor类的jbpmConfig进行初始化。代码如下:

 

package org.jbpm.job.executor;

 

import java.io.IOException;

import java.io.PrintWriter;

import java.util.Collection;

import java.util.Iterator;

 

import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

 

import org.jbpm.JbpmConfiguration;

import org.springframework.web.context.support.WebApplicationContextUtils;

import org.springmodules.workflow.jbpm31.JbpmTemplate;

 

public class JobExecutorServlet extends HttpServlet {

 

         private static final long serialVersionUID = 1L ;

 

         JbpmConfiguration jbpmConfiguration;

//修改了JobExecutorServlet里获取JbpmConfiguration的方式

         public void init() throws ServletException {

                   JbpmTemplate jbpmTemplate = (JbpmTemplate) WebApplicationContextUtils

                                     .getWebApplicationContext(this.getServletContext()).getBean(

                                                        "jbpmTemplate");

                   jbpmConfiguration = jbpmTemplate.getJbpmConfiguration();

                   CustomJobExecutor.setJbpmConfiguration(jbpmConfiguration);

                   jbpmConfiguration.startJobExecutor();

         }

 

         protected void doGet(HttpServletRequest request,

                            HttpServletResponse response) throws ServletException, IOException {

                   PrintWriter out = response.getWriter();

                   out.println("<html>");

                   out.println("<body>");

                   out.println("<h2>JBoss jBPM Scheduler Servlet</h2><hr />");

                   Collection threads = jbpmConfiguration.getJobExecutor().getThreads()

                                     .values();

                   Iterator iter = threads.iterator();

                   while (iter.hasNext()) {

                            Thread thread = (Thread) iter.next();

                            out.println("<h4>" + thread.getName() + "</h4>");

                            out.println("<b>isAlive</b>:" + thread.isAlive());

                   }

                   out.println("</body>");

                   out.println("</html>");

         }

}

 

再次启动工程,一切正常,没有异常发生,证明我们的修改工作达到的预期的效果。

 

上海锐道信息技术有限公司

高杰

2007-8-19


 

文档信息

文档中文名称

JBPM3.2Spring结合时任务调度的实现

文档英文名称

Task Dispatch Realization for JBPM v3.2 and Spring Integration

文档内容简介

 

文档分享范围

公开文档

版本信息

日期 作者 版本 变更说明

 

2007 08 19 Jacky.gao@bstek.com v1.01 创建

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值