欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

如何实现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配置外,还可以通过流程定义本身提供的一些功能,如监听器,事件来调用这些配置,从而实现执行。

 

以下为参考的实现模式:


如何实现Activiti的流程定义的设置
            
    
    博客分类: Activiti  
 

 实现的效果如下所示:

http://www.redxun.cn:8020/saweb/login.jsp

 

 

 

  • 如何实现Activiti的流程定义的设置
            
    
    博客分类: Activiti  
  • 大小: 28.7 KB