由于各种原因,我们需要在项目中引入 jBPM4 工作流框架,遇到了不少问题,今记录如下O(∩_∩)O

1 引入步骤

1.1 加入依赖包

  1. 非 Maven 项目,在 lib 包中加入 jbpm.jar。
  2. Maven 项目,加入以下配置:
<dependency><groupId>org.jbpm</groupId><artifactId>jbpm</artifactId><version>${jbpm.version}</version>
</dependency>

如果私服上没有,可以自行作为第三方库上传到私服后,再配置 pom.xml。

1.2 集成到 Spring

<!-- jbpm 集成进 Spring -->
<bean id="springHelper" class="org.jbpm.pvm.internal.processengine.SpringHelper"lazy-init="default" autowire="default"><property name="jbpmCfg"><value>jbpm.cfg.xml</value></property>
</bean><!-- 工作流引擎-->
<bean id="processEngine" factory-bean="springHelper"factory-method="createProcessEngine"/>

名为 springHelper 的 Bean 中可以配置一个 jbpmCfg 参数,用于自定义 jbpm 配置文件。该文件名为 jbpm.cfg.xml,默认放置在 classpath 路径下。

1.3 配置 Hibernate

因为 jBPM4 使用的是 Hibernate 进行持久化操作,所以我们必须在此配置 jBPM4 持久化映射文件:

<bean id="sessionFactory"class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"><property name="dataSource" ref="dataSource" /><property name="hibernateProperties"><props><prop key="hibernate.dialect">${hibernate.dialect}</prop><prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop><prop key="hibernate.show_sql">${hibernate.show_sql}</prop><prop key="hibernate.format_sql">${hibernate.format_sql}</prop><prop key="hibernate.temp.use_jdbc_metadata_defaults">${hibernate.temp.use_jdbc_metadata_defaults}</prop></props></property>...<!-- 持久化 jBPM4 实体类--><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>
</bean>

一般来说,通过以上步骤就可以通过注入,获取到 jBPM4 的 processEngine 引擎啦O(∩_∩)O哈哈~

1.4 执行脚本

在下载的 jbpm-4.4 包中,打开 install\jdbc\ 文件夹,依据实际的数据库类型,选择相应的脚本,初始化 jBPM 库表:

2 兼容 Hibernate4+

jBPM4 默认适配 Hibernate3,所以如果框架使用的是高版本的 Hibernate,那么就必须修改 jBPM4 的源代码做适配。

下面以 Hibernate4 为例,我们需要修改 jBPM4 这 SpringProcessEngine 与 HibernateSessionDescriptor 两个类。

修改后的 jBPM4 源代码如下:

1、SpringProcessEngine.java

public class SpringProcessEngine extends ProcessEngineImpl {private static final Log log = Log.getLog(SpringProcessEngine.class.getName());private static final long serialVersionUID = 1L;private ApplicationContext applicationContext;public static ProcessEngine create(ConfigurationImpl configuration) {SpringProcessEngine springProcessEngine = null;ApplicationContext applicationContext = null;if (configuration.isInstantiatedFromSpring()) {applicationContext = (ApplicationContext) configuration.getApplicationContext();springProcessEngine = new SpringProcessEngine();springProcessEngine.applicationContext = applicationContext;springProcessEngine.initializeProcessEngine(configuration);LocalSessionFactoryBean localSessionFactoryBean = springProcessEngine.get(LocalSessionFactoryBean.class);Configuration hibernateConfiguration = localSessionFactoryBean.getConfiguration();springProcessEngine.processEngineWireContext.getWireDefinition().addDescriptor(new ProvidedObjectDescriptor(hibernateConfiguration, true));springProcessEngine.checkDb(configuration);} else {String springCfg = (String) configuration.getProcessEngineWireContext().get("spring.cfg");if (springCfg==null) {springCfg = "applicationContext.xml";}applicationContext = new ClassPathXmlApplicationContext(springCfg);springProcessEngine = (SpringProcessEngine) applicationContext.getBean("jbpmProcessEngine");}return springProcessEngine;}public EnvironmentImpl openEnvironment() {PvmEnvironment environment = new PvmEnvironment(this);if (log.isTraceEnabled())log.trace("opening jbpm-spring" + environment);environment.setContext(new SpringContext(applicationContext));installAuthenticatedUserId(environment);installProcessEngineContext(environment);installTransactionContext(environment);return environment;}@SuppressWarnings("unchecked")@Overridepublic <T> T get(Class<T> type) {T candidateComponent = super.get(type);if (candidateComponent != null) {return candidateComponent;}String[] names = applicationContext.getBeanNamesForType(type);if (names.length >= 1) {if (names.length > 1 && log.isWarnEnabled()) {log.warn("Multiple beans for type " + type + " found. Returning the first result.");}return (T) applicationContext.getBean(names[0]);}return null;}@Overridepublic Object get(String key) {if (applicationContext.containsBean(key)) {return applicationContext.getBean(key);}return super.get(key);}
}

2、HibernateSessionDescriptor.java

public class HibernateSessionDescriptor extends AbstractDescriptor {private static final long serialVersionUID = 1L;private static final Log log = Log.getLog(HibernateSessionDescriptor.class.getName());protected String factoryName;protected boolean useCurrent = false;protected boolean tx = true;protected boolean close = true;protected String standardTransactionName;protected String connectionName;public Object construct(WireContext wireContext) {EnvironmentImpl environment = EnvironmentImpl.getCurrent();if (environment == null) {throw new WireException("no environment");}// get the hibernate-session-factorySessionFactory sessionFactory = null;if (factoryName != null) {sessionFactory = (SessionFactory) wireContext.get(factoryName);} else {sessionFactory = environment.get(SessionFactory.class);}if (sessionFactory == null) {throw new WireException("couldn't find hibernate-session-factory " + (factoryName != null ? "'" + factoryName + "'" : "by type ") + "to open a hibernate-session");}// open the hibernate-sessionSession session = null;if (useCurrent) {if (log.isTraceEnabled()) log.trace("getting current hibernate session");session = sessionFactory.getCurrentSession();} else if (connectionName != null) {Connection connection = (Connection) wireContext.get(connectionName);if (log.isTraceEnabled())log.trace("creating hibernate session with connection " + connection);session = (Session)sessionFactory.openStatelessSession(connection);} else {if (log.isTraceEnabled()) log.trace("creating hibernate session");session = sessionFactory.openSession();}StandardTransaction standardTransaction = environment.get(StandardTransaction.class);if (standardTransaction != null) {HibernateSessionResource hibernateSessionResource = new HibernateSessionResource(session);standardTransaction.enlistResource(hibernateSessionResource);}return session;}public Class<?> getType(WireDefinition wireDefinition) {return SessionImpl.class;}public void setFactoryName(String factoryName) {this.factoryName = factoryName;}public void setTx(boolean tx) {this.tx = tx;}public void setStandardTransactionName(String standardTransactionName) {this.standardTransactionName = standardTransactionName;}public void setConnectionName(String connectionName) {this.connectionName = connectionName;}public void setUseCurrent(boolean useCurrent) {this.useCurrent = useCurrent;}public void setClose(boolean close) {this.close = close;}
}

3 兼容 Activiti5+

你没有看错,有的项目就是这么奇葩,已经有 Activiti5 咯,还需要集成进 jBPM4……

这两套框架都是同一个架构师 Tom Baeyens 负责的,可谓是一脉相承,所以一些基本 Bean 的命名都是相同的,比如流程引擎 Bean 都叫做 processEngine。因此如果直接按照上述配置,就会出现 Spring Bean 命名冲突的问题。

1、重命名 jBPM 工作流引擎 Bean

<!-- 工作流引擎-->
<bean id="jbpmProcessEngine" factory-bean="jbpmSpringHelper"factory-method="createProcessEngine"/>

2、在 注入时使用该名称(比如这里取名为 jbpmProcessEngine)

4 非 Spring 环境

是的,有的项目非常老,连 Spring 框架都没有用,纳尼……

可以写一个工具类,把流程引擎对象作为常量返回:

public class WorkflowUtils {//工作流引擎private static ProcessEngine PROCESS_ENGINE;//配置文件前缀public static final String SPRING_CONFIG_PREFIX = "classpath:resources/";/*** 获取工作流引擎** @return*/public static ProcessEngine getProcessEngine() {if (PROCESS_ENGINE == null) {ApplicationContext applicationContext = new ClassPathXmlApplicationContext(SPRING_CONFIG_PREFIX + "spring-hibernate.xml",SPRING_CONFIG_PREFIX + "spring-jbpm" +".xml");PROCESS_ENGINE = (ProcessEngine) applicationContext.getBean("jbpmProcessEngine");}return PROCESS_ENGINE;}
}

在此,我们利用 ApplicationContext 加载与 jBPM4 相关的配置文件,然后初始化 ProcessEngine,并设置为常量。这样,以后直接使用这个常量引擎对象就可以啦O(∩_∩)O哈哈~


只要有耐心、细心和恒心,没有我们程序员解决不了的事儿O(∩_∩)O哈哈~

说说如何在项目中引入 jBPM4 工作流框架以及遇到的坑儿相关推荐

  1. vue ajax highcharts,在vue项目中引入highcharts图表的方法(详解)

    npm进行highchars的导入,导入完成后就可以进行highchars的可视化组件开发了 npm install highcharts --save 1.components目录下新建一个char ...

  2. 在C++项目中引入Lua(AlphaGo使用的方案)

    最近大火的AlphaGo,其中的deepmind已经开源,可以到github中下载https://github.com/deepmind/lab·,网上还有一个基于Python开源AlphaGo,那个 ...

  3. 引入 javascript_在您JavaScript项目中引入类型安全性? 再想一想

    引入 javascript by James Wright 詹姆斯·赖特(James Wright) 在您JavaScript项目中引入类型安全性? 再想一想 (Introducing Type Sa ...

  4. 项目中引入阿里巴巴图标——iconfont图标的使用-svg格式

    项目中引入阿里巴巴图标--iconfont图标的使用-svg格式 一.下载图标 1.先进入iconfont.cn页面 iconfont官网:https://www.iconfont.cn/ 2.登陆, ...

  5. 如何在Vue项目中引入ArcGIS JavaScript API​ 创建三维可视化地图(含vue项目创建教程)

    新手上路之在Vue项目中引入ArcGIS API​ 视频教程 B站搜索 X北辰北,感谢up主无私的教学~ B站地址:https://www.bilibili.com/video/BV18E411K7B ...

  6. Webpack项目中引入Bootstrap4.x

    Bootstrap是一个简洁.直观.强悍的前端开发框架,在Web开发中使用频率很高,本文主要记录一下如何在 webpack项目中引入Bootstrap4.x. 由于Bootstrap在各个Vue组件中 ...

  7. VUE 项目中引入外部js文件(CND引入)

    以VUE项目中引入echarts文件为例: 第一步在VUE项目中找到index.html文件 引入 :<script src="https://cdnjs.cloudflare.com ...

  8. 如何在vue项目中引入html页面

    在vue项目中引入html页面的两种方法 第一种:/static/page.html 第二种:通过iframe嵌入 第一种:/static/page.html 在static或public文件夹下,新 ...

  9. Webpack项目中引入IconFont图标

    本篇文章将介绍一下如何在Vue Webpack项目中引入IconFont图标. IconFont官网:https://www.iconfont.cn/ 1.打开IconFont官网并登陆自己的账户. ...

最新文章

  1. 刷手支付已来,亚马逊技术专利曝光,不侵犯隐私、秒速支付
  2. hyperledger-simple-app
  3. php 数据库时间函数大全,PHP时间函数和SQL
  4. linux unix系统区别,Unix和Linux操作系统有什么区别?看这里!
  5. 20-爬虫之scrapy框架CrawlSpider07
  6. 深入理解操作系统内核架构(送书)!
  7. python处理完数据导入数据库_python 将execl测试数据导入数据库操作
  8. 【codevs1867】【Tyvj3508】【BZOJ1041】圆上的整点,数学乱搞
  9. Android 系统(180)---Android.mk入门
  10. 一名董事长给大学生的18条忠告(全)
  11. 如果你感到ETF内卷了,聪明的你要换条路
  12. 如何下载中国卫星地图高清版大图
  13. 美团饿了吗CPS红包,别人领红包下单,你拿推广佣金(附源码)
  14. 【每天学点管理学】目标管理工具——SMART法则
  15. 错误代码:88000, 错误信息:without comment privilege hint: [7oJ0533w689] rid: 630432cd-15944cf6-083e04fc
  16. 零基础-微信小程序入门教程
  17. 同建金融IT新生态——令克软件富途证券达成战略合作
  18. Android SystemUI相关定制(一)
  19. 前端面试总结(转载请标明)
  20. day55 django 模型层,orm连表操作

热门文章

  1. [Android]混淆Android代码
  2. xUnit.net入门
  3. Java基础(一) 八大基本数据类型
  4. This application is currently offline解决办法
  5. Angular Landing – Material Design Angular App Landing Page
  6. android图片压缩终极解决方案
  7. python给我做500份问卷
  8. 关于百度站长工具中站点属性LOGO提交申请详解说明
  9. 吴恩达 深度学习系列--卷积神经网络(Convolutional Neural Networks)-03(目标检测)
  10. CentOS下安装XAMPP详细教程