如何实现Activiti的流程定义的设置
程序员文章站
2022-06-03 16:38:08
...
Activiti提供的流程定义是基于XML的,一旦发布完成后,若想对流程定义实现更改,只有一种办法,就是重新发布新的版本,但有时,我们需要的是不让他发行新版本,只是希望修改其原来的Xml,如我们对分支节点进行条件设置。
<sequenceFlow id="flow1" name="input==1" sourceRef="exclusivegateway1" targetRef="usertask1"> <conditionExpression xsi:type="tFormalExpression"><![CDATA[input==1]]></conditionExpression> </sequenceFlow> <sequenceFlow id="flow2" name="input==2" sourceRef="exclusivegateway1" targetRef="usertask2"> <conditionExpression xsi:type="tFormalExpression"><![CDATA[input==2]]></conditionExpression> </sequenceFlow>
在这里,我们提出了一种新的做法,就是绕开Activiti的API,直接实现实现对流程定义的XML实现读写,读写比较简单,只需要拿到流程定义的deployId或definitionId,通过对其act_ge_bytearray表实现更改,其定义内容存放于bytes_字段中。
我们提供了对定义Xml文件的更改方法:
public class ActGeByteArrayDao { @Resource JdbcTemplate jdbcTemplate; /** * 取得流程定义的XML * * @param deployId * @return */ public String getDefXmlByDeployId(String deployId){ String sql = "select a.* from ACT_GE_BYTEARRAY a where NAME_ LIKE '%bpmn20.xml' and DEPLOYMENT_ID_= ? "; final LobHandler lobHandler = new DefaultLobHandler(); // reusable final ByteArrayOutputStream contentOs = new ByteArrayOutputStream(); String defXml = null; try{ jdbcTemplate.query(sql, new Object[]{deployId },new AbstractLobStreamingResultSetExtractor<Object>(){ public void streamData(ResultSet rs) throws SQLException, IOException{ FileCopyUtils.copy(lobHandler.getBlobAsBinaryStream(rs, "BYTES_"), contentOs); } } ); defXml = new String(contentOs.toByteArray(), "UTF-8"); } catch (Exception ex){ ex.printStackTrace(); } return defXml; } /** * 把修改过的xml更新至回流程定义中 * * @param deployId * @param defXml */ public void writeDefXml(final String deployId, String defXml) { try { LobHandler lobHandler = new DefaultLobHandler(); final byte[] btyesXml = defXml.getBytes("UTF-8"); String sql = "update ACT_GE_BYTEARRAY set BYTES_=? where NAME_ LIKE '%bpmn20.xml' and DEPLOYMENT_ID_= ? "; jdbcTemplate.execute(sql, new AbstractLobCreatingPreparedStatementCallback(lobHandler) { @Override protected void setValues(PreparedStatement ps, LobCreator lobCreator) throws SQLException, DataAccessException { lobCreator.setBlobAsBytes(ps, 1, btyesXml); ps.setString(2, deployId); } }); } catch (Exception ex) { ex.printStackTrace(); } } }
但要注意,流程定义发布后,若你使用了该流程,其就会在缓存中缓存了流程定义的解析后的对象,供整个引擎使用,这时你更改了流程定义的XML后,那份缓存并没有实现了更改,因此,需要告诉引擎,让他清空缓存中的该流程定义即可。如何清空流程定义的缓存,请参考以下代码:
((ProcessEngineConfigurationImpl)processEngineConfiguration).getProcessDefinitionCache().remove(actDefId);
通过以上方式,可以灵活实现对流程定义的节点及属性的随意更改,而不会限制于Activiti的API.
后续我会提供更加灵活活的流程属性扩展,如流程定义的节点属性,人员配置,事件回调,脚本执行的配置。除了通过更新流程定义的XML配置外,还可以通过流程定义本身提供的一些功能,如监听器,事件来调用这些配置,从而实现执行。
以下为参考的实现模式:
实现的效果如下所示:
http://www.redxun.cn:8020/saweb/login.jsp
推荐阅读
-
在React中使用Native如何实现自定义下拉刷新上拉加载的列表
-
PHP class 类内部调用类外部定义的变量如何实现
-
Intellij IDEA如何自定义注释模板的实现方法
-
草图大师Sketchup如何设置单位?草图大师设置单位的具体操作流程
-
Winform中自定义添加ZedGraph右键实现设置所有Y轴刻度的上下限
-
网站设计中如何详细的自定义404错误页面的制作和设置
-
iOS开发中跳到系统设置里的各种设置界面如何实现
-
vue 使用element-ui中的Notification自定义按钮并实现关闭功能以及如何处理多个通知
-
vue 使用element-ui中的Notification自定义按钮并实现关闭功能及如何处理多个通知
-
如何实现只授予用户查看存储过程定义的权限