SpringMVC需要的的jar包
Jbpm所需jar包
Jbpm默认的hibernate版本是hibernate3,若是更高版本的就会有缺少包的问题
一般我们都先配置好springMVC和hibernate后直接引入jbpm的核心包 即可,若需要jbpm的其他依赖包时,再引入即可。
接下来我们配置配置文件
引入 两个文件,(引入根目录)
Jbpm.cfg.xml文件配置:
<?xml version="1.0" encoding="UTF-8"?>
<jbpm-configuration>
<import resource="jbpm.default.cfg.xml" />
<!-- <import resource="jbpm.tx.hibernate.cfg.xml" /> -->
<import resource="jbpm.jpdl.cfg.xml" />
<import resource="jbpm.bpmn.cfg.xml" />
<import resource="jbpm.identity.cfg.xml" />
<import resource="jbpm.businesscalendar.cfg.xml" />
<import resource="jbpm.console.cfg.xml" />
<!-- <import resource="jbpm.jobexecutor.cfg.xml" /> -->
<!-- 导入spring配置文件 -->
<import resource="jbpm.tx.spring.cfg.xml" />
</jbpm-configuration>
Jbpm.hibernate.cfg.xml文件配置:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- jBMP4.4下使用MySQL必须把方言设置为 org.hibernate.dialect.MySQL5InnoDBDialect-->
<!-- <property name="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</property> <property name="hibernate.connection.driver_class">org.gjt.mm.mysql.Driver</property> <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/gzitcast1008jbpm</property> <property name="hibernate.connection.username">root</property> <property name="hibernate.connection.password">admin</property> <property name="hibernate.format_sql">false</property> <property name="hibernate.show_sql">false</property> <property name="hibernate.hbm2ddl.auto">update</property> <mapping resource="jbpm.repository.hbm.xml" /> <mapping resource="jbpm.execution.hbm.xml" /> <mapping resource="jbpm.history.hbm.xml" /> <mapping resource="jbpm.task.hbm.xml" /> <mapping resource="jbpm.identity.hbm.xml" /> -->
</session-factory>
</hibernate-configuration>
Persistance-mysql.properties文件配置:
# \u6570\u636e\u6e90\u7684\u9009\u62e9(\u53ef\u9009:jdbcDataSource/c3p0DataSource)
dataSource_reference=jdbcDataSource
# \u9879\u76ee\u540d\u79f0(\u4f8b\u5982:student5,\u6ce8\u610f\u5927\u5c0f\u5199)
project_name=jbpmDemo
# JDBC\u6570\u636e\u6e90\u914d\u7f6e(jdbcDataSource)
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://127.0.0.1:3308/jbpm_demo?createDatabaseIfNotExist=true&characterEncoding=UTF8&useUnicode=true
jdbc.user=root
jdbc.pass=mysql
# hibernate4\u57fa\u672c\u914d\u7f6e
hibernate.format_sql=true
hibernate.show_sql=true
hibernate.hbm2ddl.auto=update
#hibernate.use_outer_join=true
hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect
hibernate.jdbc.fetch_size=100
hibernate.jdbc.batch_size=30
hibernate.jdbc.use_scrollable_resultset=true
# Hibernate4 \u7f13\u5b58\u914d\u7f6e
#\u9ad8\u901f\u7f13\u5b58\u63d0\u4f9b\u7a0b\u5e8f,\u7531\u4e8espring\u4e5f\u4f7f\u7528\u4e86Ehcache,\u4fdd\u8bc1\u53cc\u65b9\u90fd\u4f7f\u7528\u540c\u4e00\u4e2a\u7f13\u5b58\u7ba1\u7406\u5668(\u9ed8\u8ba4\u4e3a:org.hibernate.cache.ehcache.EhCacheRegionFactory)
hibernate.cache.region.factory_class=org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory
hibernate.cache.use_second_level_cache=true
hibernate.cache.use_query_cache=true
hibernate.cache.use_structured_entries=true
hibernate.Connection.useUnicode=true
hibernate.connection.characterEncoding=UTF8
spring-hibernate.xml文件配置
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.1.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.1.xsd">
<!-- 加载资源文件,其中包含变量信息,必须在Spring配置文件的最前面加载,即第一个加载(项目必备) -->
<context:property-placeholder location="classpath:/database/persistence-mysql.properties" />
<!-- JDBC数据源配置(与c3p0数据源选择其一)(项目开发阶段必备) -->
<bean id="jdbcDataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${jdbc.driverClassName}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.user}" />
<property name="password" value="${jdbc.pass}" />
</bean>
<!-- c3p0数据源配置(与JDBC数据源选择其一)(项目正式上线后必备) -->
<bean id="c3p0DataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<!-- <property name="user" value="${c3p0.user}" /> <property name="password" value="${c3p0.password}" /> -->
<property name="driverClass" value="${c3p0.driverClass}" />
<property name="jdbcUrl" value="${c3p0.jdbcUrl}" />
<property name="initialPoolSize" value="${c3p0.initPoolSize}" />
<property name="minPoolSize" value="${c3p0.minPoolSize}" />
<property name="maxPoolSize" value="${c3p0.maxPoolSize}" />
<property name="properties" ref="loginEncrypted" />
</bean>
<!-- c3p0数据源数据库用户名与密码加密 -->
<bean id="loginEncrypted" class="name.yrz.utils.DatasourcePropertiesFactory" factory-method="getProperties">
<constructor-arg type="java.lang.String">
<value>${c3p0_username_encrypted}</value>
</constructor-arg>
<constructor-arg type="java.lang.String">
<value>${c3p0_password_encrypted}</value>
</constructor-arg>
<!-- 生产环境模式,才特殊处理加密密码 -->
<constructor-arg type="java.lang.String">
<value>${c3p0.production}</value>
</constructor-arg>
</bean>
<!-- 配置SessionFactory(项目必备) -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<!-- 配置SessionFactory使用的数据源 -->
<property name="dataSource" ref="${dataSource_reference}" />
<!-- 以下packagesToScan和mappingLocations建议二选其一,注解形式用前者,配置文件形式用后者 -->
<!-- <property name="packagesToScan"> <list>可以加多个包 <value>com.yashi.${project_name}</value> </list> </property> -->
<property name="mappingLocations" value="classpath:com/yashi/${project_name}/**/*.hbm.xml" />
<property name="mappingResources">
<list>
<value>jbpm.repository.hbm.xml</value>
<value>jbpm.execution.hbm.xml</value>
<value>jbpm.history.hbm.xml</value>
<value>jbpm.task.hbm.xml</value>
<value>jbpm.identity.hbm.xml</value>
</list>
</property>
<!-- 配置Hibernate的一些属性 -->
<property name="hibernateProperties">
<props>
<!-- Hibernate基本配置 -->
<prop key="hibernate.format_sql">${hibernate.format_sql}</prop>
<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
<prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop>
<!-- 其他配置 -->
<!-- <prop key="hibernate.use_outer_join">${hibernate.use_outer_join}</prop> -->
<!-- 数据库方言 -->
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<!-- 每次从数据库中取出并放到JDBC的Statement中的记录条数,100为宜,貌似不支持MySQL -->
<prop key="hibernate.jdbc.fetch_size">${hibernate.jdbc.fetch_size}</prop>
<!-- 批量插入,删除和更新时每次操作的记录数,30为宜,貌似不支持MySQL -->
<prop key="hibernate.jdbc.batch_size">${hibernate.jdbc.batch_size}</prop>
<!-- 是否允许Hibernate用JDBC的可滚动的结果集,貌似不支持MySQL -->
<prop key="hibernate.jdbc.use_scrollable_resultset">${hibernate.jdbc.use_scrollable_resultset}</prop>
<!-- 编码 -->
<prop key="hibernate.Connection.useUnicode">${hibernate.Connection.useUnicode}</prop>
<prop key="hibernate.connection.characterEncoding">${hibernate.connection.characterEncoding}</prop>
</props>
</property>
</bean>
<!-- Spring(注意不是SpringMVC)也使用ehcache,所以也需要在spring配置文件中添加ehcache的配置 ,cacheManager,指定ehcache.xml的位置 -->
<bean id="cacheManagerEhcache" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
<property name="configLocation">
<value>classpath:name/yrz/config/ehcache.xml</value>
</property>
<!-- 由于hibernate也使用了Ehcache,保证双方都使用同一个缓存管理器 -->
<property name="shared" value="true"/>
</bean>
<!-- 配置Hibernate事务管理器(项目必备) -->
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<!-- 配置事务异常封装 -->
<bean id="persistenceExceptionTranslationPostProcessor" class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />
<!-- 基于注释的事务(与下面的声明式容器事务管理二选其一即可),当注释中发现@Transactional注解时,使用id为"transactionManager"的事务管理器(项目必备) -->
<!-- 如果没有设置transaction-manager的值,则spring以缺省默认的事务管理器来处理事务,默认事务管理器为第一个加载的事务管理器 -->
<!-- <tx:annotation-driven transaction-manager="transactionManager" /> -->
<!-- 声明式容器事务管理(与上面的基于注释的事务二选其一即可) ,transaction-manager指定事务管理器为transactionManager -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<!-- REQUIRED:指定当前方法必需在事务环境中运行,如果当前有事务环境就加入当前正在执行的事务环境, 如果当前没有事务,就新建一个事务.这是默认值 -->
<!-- 读操作(疑问:这里有必要加read-only="true"吗?) -->
<tx:method name="export*" propagation="REQUIRED" read-only="true" />
<tx:method name="find*" propagation="REQUIRED" read-only="true" />
<tx:method name="get*" propagation="REQUIRED" read-only="true" />
<tx:method name="list*" propagation="REQUIRED" read-only="true" />
<tx:method name="load*" propagation="REQUIRED" read-only="true" />
<tx:method name="read*" propagation="REQUIRED" read-only="true" />
<!-- 写操作 -->
<tx:method name="add*" propagation="REQUIRED" />
<tx:method name="change*" propagation="REQUIRED" />
<tx:method name="create*" propagation="REQUIRED" />
<tx:method name="del*" propagation="REQUIRED" />
<tx:method name="edit*" propagation="REQUIRED" />
<tx:method name="import*" propagation="REQUIRED" />
<tx:method name="insert*" propagation="REQUIRED" />
<tx:method name="merge*" propagation="REQUIRED" />
<tx:method name="new*" propagation="REQUIRED" />
<tx:method name="persist*" propagation="REQUIRED" />
<tx:method name="remove*" propagation="REQUIRED" />
<tx:method name="save*" propagation="REQUIRED" />
<tx:method name="set*" propagation="REQUIRED" />
<tx:method name="update*" propagation="REQUIRED" />
<!-- 指定当前方法以非事务方式执行操作,如果当前存在事务,就把当前事务挂起,等我以非事务的状态运行完,再继续原来的事务. 查询定义即可. read-only="true"表示只读 -->
<tx:method name="*" propagation="NOT_SUPPORTED" read-only="true" />
</tx:attributes>
</tx:advice>
<!-- 整合jbpm -->
<bean id="springHelper" class="org.jbpm.pvm.internal.processengine.SpringHelper">
<!-- <property name="jbpmCfg" value="jbpm.cfg.xml"></property> -->
</bean>
<!-- 调用上面的springHelper Bean的createProcessEngine方法来创建流程引擎 -->
<bean name="processEngine" factory-bean="springHelper" factory-method="createProcessEngine"></bean>
<!-- 配置repositoryService -->
<bean name="repositoryService" factory-bean="processEngine" factory-method="getRepositoryService"></bean>
<!-- 配置ExecutionService -->
<bean name="executionService" factory-bean="processEngine" factory-method="getExecutionService"></bean>
<!-- 配置TaskService -->
<bean name="taskService" factory-bean="processEngine" factory-method="getTaskService"></bean>
<bean name="historyService" factory-bean="processEngine" factory-method="getHistoryService"></bean>
<bean name="identityService" factory-bean="processEngine" factory-method="getIdentityService" ></bean>
<!-- 配置Spring(注意不是SpringMVC)的事务切面 -->
<aop:config expose-proxy="true">
<!-- 只对业务逻辑层实施事务 -->
<aop:pointcut id="txPointcut" expression="execution(* com.yashi.*.service..*.*(..))" />
<!-- Advisor定义,切入点和通知分别为txPointcut、txAdvice -->
<aop:advisor pointcut-ref="txPointcut" advice-ref="txAdvice" />
</aop:config>
</beans>
配置文件配置好后,启动项目后,会因为包的冲突,缺包的问题而报错,这时候缺什么包就引进来即可。
SpringMVC+jbpm的简单示例:报销流程
1. 设计流程定义图
<?xml version="1.0" encoding="UTF-8"?>
<process key="baoxiao" name="baoxiao" xmlns="http://jbpm.org/4.4/jpdl">
<start g="65,211,48,48" name="start1">
<transition g="-79,-22" name="to exclusive1" to="exclusive1"/>
</start>
<decision expr="#{baoxiao.money>5000?'to 老板审批':'to 经理审批'}" g="188,213,48,48" name="exclusive1">
<transition g="-69,-22" name="to 老板审批" to="老板审批"/>
<transition g="-69,-22" name="to 经理审批" to="经理审批"/>
</decision>
<task assignee="#{boss}" g="310,151,92,52" name="老板审批">
<transition g="-69,-22" name="通过" to="财务支出"/>
<transition g="-50,-22" name="否决" to="否决"/>
</task>
<task assignee="#{manager}" g="295,301,92,52" name="经理审批">
<transition g="-69,-22" name="通过" to="财务支出"/>
<transition g="-50,-22" name="否决" to="否决"/>
<transition name="请示老板" to="老板审批" g="-69,-22"/>
</task>
<task candidate-groups="finance" g="507,159,92,52" name="财务支出">
<transition g="-50,-22" name="转账" to="通过"/>
</task>
<end g="706,145,48,48" name="通过"/>
<end g="694,311,48,48" name="否决"/>
</process>
根据流程定义图,使用task节点的两种任务分配方式:1.任务分配者assignee,2. 任务候选人candidate-groups
部署流程定义:
账号登录后进入主页,流程定义部署成功后,要创建流程实例,以及填写报销单
这时流程自动流转到decision节点,并根据此条件expr=”#{baoxiao.money>5000?’to 老板审批’:’to 经理审批’}”
流转到下一个节点,经理审批。
代码:
经理登录后,会看到指派给自己的任务,而操作的内容是当前节点的所有输出箭头名称
代码:
点击通过,完成任务,流转到财务支出节点
代码:
在部署流程定义时,我们已经创建了finance用户组,并为其创建了用户cai10,cai20,cai30,财务人员登录后,会看到自己的可见的任务,但不能处理任务,只有接受此任务,才能真正成为自己的个人任务,其他组员也就不会看到这个任务
代码:
接受任务后,在待办事宜中出现这条任务,此时这个任务专属于接受任务的用户
代码:
财务人员转账后,整个报销流程结束。
而报销人要看自己的报销单此时的状态,(处理到哪里)
代码:
注意
一个流程实例的id只要流程没结束,它的id始终都不变
每个任务都有一个新的id,它是变的