最近整合了一个jbpm3.2 与ssh框架的Demo,期间遇到了不少问题 ,有的问题比较难搞,但是经过我的努力,还是运行起来了,工作流基本上可以完成流转,不过也存在一些问题,这里我综合起来说一下!当然 有的人说jbpm3已经落伍了,但是我个人不纠结于版本,只要能做出东西来就好。这是我搭建框架所需要的jar包:
其他不说 我说一下jbpm的identity包,我之前用官网的identity包的时候 总会报错field String什么的,是说调动hibernate里面什么东西的时候的一个错误,原因是网上也说了,他调用了hibernate过期的方法或者字段,所以才会报错,后面网上找了很多资料,解决方案都是把这个包里面的类反编译然后修改 然后再打jar包,我一看心凉了,这么麻烦,还好后面有个好心的哥们儿上传了一个修改后的,减轻了我的工作量!这里我也贴出来修改后的jbpm-identity.jar下载地址:点击打开链接
整合主要就是把jbpm的jbpmConfigrantion交由Spring来管理,配置为:
在aplicationcontext.xml中:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:jaxws="http://cxf.apache.org/jaxws" xmlns:jaxrs="http://cxf.apache.org/jaxrs"
xmlns:task="http://www.springframework.org/schema/task"
default-autowire="byName"
xsi:schemaLocation="
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd"
default-lazy-init="false">
<context:component-scan base-package="com">
</context:component-scan>
<context:property-placeholder location="classpath:jdbc.properties"/>
<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>
<!-- 集成jbpm3.2 -->
<bean id="jbpmConfiguration" class="org.springmodules.workflow.jbpm31.LocalJbpmConfigurationFactoryBean">
<property name="sessionFactory" ref="sessionFactory" />
<property name="configuration" value="classpath:jbpm.cfg.xml"></property>
</bean>
<bean id="jbpmTemplate" class="org.springmodules.workflow.jbpm31.JbpmTemplate">
<property name="jbpmConfiguration" ref="jbpmConfiguration"></property>
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="hibernateProperties">
<props>
<prop key="hibernate.proxool.pool_alias">proxooldatascr</prop>
<prop key="hibernate.connection.provider_class">org.hibernate.connection.ProxoolConnectionProvider</prop>
<prop key="hibernate.dialect">org.hibernate.dialect.Oracle9iDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.generate_statistics">true</prop>
<prop key="hibernate.query.factory_class">org.hibernate.hql.classic.ClassicQueryTranslatorFactory</prop>
<prop key="hibernate.format_sql">true</prop>
<prop key="current_session_context_class">thread</prop>
<prop key="hibernate.jdbc.batch_size">30</prop>
<prop key="hibernate.cache.use_second_level_cache">true</prop>
<prop key="hibernate.cache.provider_class">net.sf.ehcache.hibernate.EhCacheProvider</prop>
<prop key="hibernate.cache.use_query_cache">true</prop>
<prop key="generate_statistics">true</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop> <!-- hbm2ddl.auto在这里会不识别,所以这里要加上hibernate前缀 -->
</props>
</property>
<property name="packagesToScan">
<list><value>com.qyt.jbpm.model</value></list>
</property>
<property name="mappingResources">
<list>
<value>org/jbpm/graph/action/Script.hbm.xml</value>
<value>org/jbpm/identity/User.hbm.xml</value>
<value>org/jbpm/identity/Group.hbm.xml</value>
<value>org/jbpm/identity/Membership.hbm.xml</value>
<value>org/jbpm/db/hibernate.queries.hbm.xml</value>
<value>org/jbpm/graph/action/MailAction.hbm.xml</value>
<value>org/jbpm/graph/def/ProcessDefinition.hbm.xml</value>
<value>org/jbpm/graph/def/Node.hbm.xml</value>
<value>org/jbpm/graph/def/Transition.hbm.xml</value>
<value>org/jbpm/graph/def/Event.hbm.xml</value>
<value>org/jbpm/graph/def/Action.hbm.xml</value>
<value>org/jbpm/graph/def/SuperState.hbm.xml</value>
<value>org/jbpm/graph/def/ExceptionHandler.hbm.xml</value>
<value>org/jbpm/instantiation/Delegation.hbm.xml</value>
<value>org/jbpm/graph/node/StartState.hbm.xml</value>
<value>org/jbpm/graph/node/EndState.hbm.xml</value>
<value>org/jbpm/graph/node/ProcessState.hbm.xml</value>
<value>org/jbpm/graph/node/Decision.hbm.xml</value>
<value>org/jbpm/graph/node/Fork.hbm.xml</value>
<value>org/jbpm/graph/node/Join.hbm.xml</value>
<value>org/jbpm/graph/node/MailNode.hbm.xml</value>
<value>org/jbpm/graph/node/State.hbm.xml</value>
<value>org/jbpm/graph/node/TaskNode.hbm.xml</value>
<value>org/jbpm/context/def/ContextDefinition.hbm.xml</value>
<value>org/jbpm/context/def/VariableAccess.hbm.xml</value>
<value>org/jbpm/taskmgmt/def/TaskMgmtDefinition.hbm.xml</value>
<value>org/jbpm/taskmgmt/def/Swimlane.hbm.xml</value>
<value>org/jbpm/taskmgmt/def/Task.hbm.xml</value>
<value>org/jbpm/taskmgmt/def/TaskController.hbm.xml</value>
<value>org/jbpm/module/def/ModuleDefinition.hbm.xml</value>
<value>org/jbpm/bytes/ByteArray.hbm.xml</value>
<value>org/jbpm/file/def/FileDefinition.hbm.xml</value>
<value>org/jbpm/scheduler/def/CreateTimerAction.hbm.xml</value>
<value>org/jbpm/scheduler/def/CancelTimerAction.hbm.xml</value>
<value>org/jbpm/graph/exe/Comment.hbm.xml</value>
<value>org/jbpm/graph/exe/ProcessInstance.hbm.xml</value>
<value>org/jbpm/graph/exe/Token.hbm.xml</value>
<value>org/jbpm/graph/exe/RuntimeAction.hbm.xml</value>
<value>org/jbpm/module/exe/ModuleInstance.hbm.xml</value>
<value>org/jbpm/context/exe/ContextInstance.hbm.xml</value>
<value>org/jbpm/context/exe/TokenVariableMap.hbm.xml</value>
<value>org/jbpm/context/exe/VariableInstance.hbm.xml</value>
<value>org/jbpm/context/exe/variableinstance/ByteArrayInstance.hbm.xml</value>
<value>org/jbpm/context/exe/variableinstance/DateInstance.hbm.xml</value>
<value>org/jbpm/context/exe/variableinstance/DoubleInstance.hbm.xml</value>
<value>org/jbpm/context/exe/variableinstance/HibernateLongInstance.hbm.xml</value>
<value>org/jbpm/context/exe/variableinstance/HibernateStringInstance.hbm.xml</value>
<value>org/jbpm/context/exe/variableinstance/LongInstance.hbm.xml</value>
<value>org/jbpm/context/exe/variableinstance/NullInstance.hbm.xml</value>
<value>org/jbpm/context/exe/variableinstance/StringInstance.hbm.xml</value>
<value>org/jbpm/job/Job.hbm.xml</value>
<value>org/jbpm/job/Timer.hbm.xml</value>
<value>org/jbpm/job/ExecuteNodeJob.hbm.xml</value>
<value>org/jbpm/job/ExecuteActionJob.hbm.xml</value>
<value>org/jbpm/taskmgmt/exe/TaskMgmtInstance.hbm.xml</value>
<value>org/jbpm/taskmgmt/exe/TaskInstance.hbm.xml</value>
<value>org/jbpm/taskmgmt/exe/PooledActor.hbm.xml</value>
<value>org/jbpm/taskmgmt/exe/SwimlaneInstance.hbm.xml</value>
<value>org/jbpm/logging/log/ProcessLog.hbm.xml</value>
<value>org/jbpm/logging/log/MessageLog.hbm.xml</value>
<value>org/jbpm/logging/log/CompositeLog.hbm.xml</value>
<value>org/jbpm/graph/log/ActionLog.hbm.xml</value>
<value>org/jbpm/graph/log/NodeLog.hbm.xml</value>
<value>org/jbpm/graph/log/ProcessInstanceCreateLog.hbm.xml</value>
<value>org/jbpm/graph/log/ProcessInstanceEndLog.hbm.xml</value>
<value>org/jbpm/graph/log/ProcessStateLog.hbm.xml</value>
<value>org/jbpm/graph/log/SignalLog.hbm.xml</value>
<value>org/jbpm/graph/log/TokenCreateLog.hbm.xml</value>
<value>org/jbpm/graph/log/TokenEndLog.hbm.xml</value>
<value>org/jbpm/graph/log/TransitionLog.hbm.xml</value>
<value>org/jbpm/context/log/VariableLog.hbm.xml</value>
<value>org/jbpm/context/log/VariableCreateLog.hbm.xml</value>
<value>org/jbpm/context/log/VariableDeleteLog.hbm.xml</value>
<value>org/jbpm/context/log/VariableUpdateLog.hbm.xml</value>
<value>org/jbpm/context/log/variableinstance/ByteArrayUpdateLog.hbm.xml</value>
<value>org/jbpm/context/log/variableinstance/DateUpdateLog.hbm.xml</value>
<value>org/jbpm/context/log/variableinstance/DoubleUpdateLog.hbm.xml</value>
<value>org/jbpm/context/log/variableinstance/HibernateLongUpdateLog.hbm.xml</value>
<value>org/jbpm/context/log/variableinstance/HibernateStringUpdateLog.hbm.xml</value>
<value>org/jbpm/context/log/variableinstance/LongUpdateLog.hbm.xml</value>
<value>org/jbpm/context/log/variableinstance/StringUpdateLog.hbm.xml</value>
<value>org/jbpm/taskmgmt/log/TaskLog.hbm.xml</value>
<value>org/jbpm/taskmgmt/log/TaskCreateLog.hbm.xml</value>
<value>org/jbpm/taskmgmt/log/TaskAssignLog.hbm.xml</value>
<value>org/jbpm/taskmgmt/log/TaskEndLog.hbm.xml</value>
<value>org/jbpm/taskmgmt/log/SwimlaneLog.hbm.xml</value>
<value>org/jbpm/taskmgmt/log/SwimlaneCreateLog.hbm.xml</value>
<value>org/jbpm/taskmgmt/log/SwimlaneAssignLog.hbm.xml</value>
</list>
</property>
</bean>
<bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
<bean id="txManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<tx:advice id="txAdvice" transaction-manager="txManager">
<tx:attributes>
<tx:method name="insert*" propagation="REQUIRED" rollback-for="Exception" />
<tx:method name="update*" propagation="REQUIRED" rollback-for="Exception" />
<tx:method name="delete*" propagation="REQUIRED" rollback-for="Exception" />
<tx:method name="save*" propagation="REQUIRED" rollback-for="Exception" />
<tx:method name="deploy*" propagation="REQUIRED" rollback-for="Exception" />
<tx:method name="create*" propagation="REQUIRED" rollback-for="Exception" />
<tx:method name="sub*" propagation="REQUIRED" rollback-for="Exception" />
<tx:method name="*" read-only="true" />
</tx:attributes>
</tx:advice>
<aop:aspectj-autoproxy />
<aop:config proxy-target-class="true">
<aop:advisor id="serviceManagerTx" advice-ref="txAdvice"
pointcut="execution(* com..*Service*.*(..)) " />
<aop:advisor id="daoManagerTx" advice-ref="txAdvice"
pointcut="execution(* com..*Dao*.*(..)) " />
<aop:advisor id="jobManagerTx" advice-ref="txAdvice"
pointcut="execution(* com..*Fac*.*(..)) " />
</aop:config>
<!--
<aop:config>
<aop:pointcut id="servicespointcut"
expression="execution(* com.qyt.jbpm.*service*.*(..))" />
<aop:advisor advice-ref="txAdvice" pointcut-ref="servicespointcut" />
</aop:config>
</beans>
配置之后 ,那么在用到jbpm的时候就只需要将jbpmConfigration注入进入就可以,然后使用jbpmcontext去操作session等等,注意context这时候是不需要手动关闭的(比如说我们没有交由spring管理的时候,我们进行一个流程定义部署context.deployProcessdefinition("xxxx.xml");我们是需要context.close()的, 不然数据库里面是没有数据的,它的作用就是进行事务提交,然后关闭context) )
三层架构中 我们去交由spring管理进行项目集成的时候,我们最好是把jbpm相关的东西单独用一个接口,这里所说的就是门面模式Face,将jbpm的东西与项目分离,降低程序事件的耦合度 。
矿建搭建好了,其他东西自然就遵循平时开发的模式就可以了,把我们的业务与jbpm结合起来。
开发中我遇到一个严重的问题,但是也没解决掉,就用另一种方法代替了,当我开启公文流转后,从开始节点成功流转到下一个actorID后,数据库里面也有对应的TaskInstance了 ,可是我用当前actorId去查它的任务列表时 会报错,这个错误我在网上查了很久也没人解决掉:错误是:
couldn't get task instances list for actor ‘actorId’ 然后下面会报 true 啥的 ,我看了源码,里面
context.getTaskMgmtSession().findTaskInstances(actorId) 这个方法里面实现是命名查询 那个queryName方法那里出错,可是看了源码又找不出错误来,我甚是不解,
后面没办法了,我就直接吧hibernate.cfg.xml引入过来,在查询用户任务列表Task的时候我就自己用jbpm本身的去查询,(虽然不是好办法,但是也比无解决方法的情况下等待死亡好) 当然我是在没解决整合后这个问题的情况下这么做的!如果谁知道 解决方法也可以告诉我……
另外一些基本方法
/**
* 部署流程定义
*/
public String deployProcessDefinition() {
ProcessDefinition processDefinition=ProcessDefinition.parseXmlResource("LeavingProcessDefinition/processdefinition.xml");
this.getJbpmContext().deployProcessDefinition(processDefinition);
return processDefinition.getName();
}
/**
* 创建流程实例 ,将公文对象与流程实例绑定
*/
public long createProcessInstance(Document document,int documentId){
ProcessDefinition processDefinition=getJbpmContext().getGraphSession().findLatestProcessDefinition("test01");
ProcessInstance processInstance=new ProcessInstance(processDefinition);//根据流程定义加载流程实例
this.getJbpmContext().save(processInstance);
document.setProcessInstanceId(processInstance.getId());
processInstance.getContextInstance().setVariable("documentId", documentId);
return processInstance.getId();
}
/**
* 开始节点进行提交 可以直接用signal 如果是任务节点 就要用到end()方法
*/
public void subDocument(long processInstansId) {
ProcessInstance processInstance=this.getJbpmContext().getProcessInstance(processInstansId);
processInstance.signal();//开始节点的话就直接提交
}
/**
* 显示当前公文流转到哪个节点了
*/
public String currentNode(long processInstanceId) {
ProcessInstance processInstance=this.getJbpmContext().getProcessInstance(processInstanceId);
return processInstance.getRootToken().getNode().getName();
}
/**
* 查询当前登录用户(张三或者李四)的审批任务
*
*/
public List<Document> getCurrentMyTask(String actorName) {
JbpmContext context=JbpmConfiguration.getInstance().createJbpmContext();
List<Document> myTaskDocumentList=null;
List<Document> taskList=null;
try{ taskList= context.getTaskMgmtSession().findTaskInstances(actorName);
for (Iterator iterator = taskList.iterator(); iterator.hasNext();) {
myTaskDocumentList=new ArrayList<Document>();
TaskInstance ti = (TaskInstance) iterator.next();
int documentId=(Integer)ti.getProcessInstance().getContextInstance().getVariable("documentId");
Document doc=(Document)this.getJbpmContext().getSession().load(Document.class, documentId);
myTaskDocumentList.add(doc);
}
}catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
return myTaskDocumentList;
}
等等一些方法 这些处理方法 我上面讲了 就要卸载专门处理jbpm的接口里面 不要与我们的业务写在一起。。
好了 就写这么多…………