IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    SpringMVC+hibernate整合JBPM4.4

    summer发表于 2016-07-05 08:57:12
    love 0

    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,它是变的



沪ICP备19023445号-2号
友情链接