JFinal集成Activiti流程引擎(不使用Spring)

Java框架

浏览数:114

2020-6-8

大多数项目都集成Spring网上大多数教程也是Activiti集成Spring的方法集成到项目中。

一直也没有找到如何抛离Spring使用Activiti。

一开始以为集成Activit需要大量的工作,实际上非常简单。

只需要把Activiti的Jar包和Mybatis的Jar包导入到项目中。

设置自启动Servlet在web.xml中修改如下

	  <servlet>
	    <servlet-name>initActiviti</servlet-name>
	    <servlet-class>com.pansoft.jbsf.servlet.InitProcessEngine</servlet-class>
	    <load-on-startup>3</load-on-startup>
	  </servlet>
	  <servlet-mapping>
	    <servlet-name>initActiviti</servlet-name>
	    <url-pattern>/initActiviti</url-pattern>
	  </servlet-mapping>

 

 

InitProcessEngine代码如下

package com.****.jbsf.servlet;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;

import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngineConfiguration;
import org.activiti.engine.ProcessEngines;
import org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration;

import com.jf.plugin.activerecord.DbKit;
import com.****.jbsf.plugin.ActivitiPlugin;
import com.****.jbsf.util.activiti.ActivitiTransactionFactory;

public class InitProcessEngine extends HttpServlet {
	private static final long serialVersionUID = 715456159702221404L;

	public void init(ServletConfig config) throws ServletException {
		StandaloneProcessEngineConfiguration conf = (StandaloneProcessEngineConfiguration) ProcessEngineConfiguration.createStandaloneProcessEngineConfiguration();
//		conf.setDatabaseSchema("root");
		conf.setDataSource(DbKit.getDataSource()).setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE).setDbHistoryUsed(true);
		conf.setTransactionFactory(new ActivitiTransactionFactory());
		ActivitiPlugin.processEngine = conf.buildProcessEngine();
//自启动完成

//部署流程定义
		ProcessEngine pe = ProcessEngines.getDefaultProcessEngine();
		pe.getRepositoryService()
		.createDeployment()
		.name("督察催办")
		.addClasspathResource("/com/pansoft/jbsf/oa/bpmn/Urge.bpmn")
		.addClasspathResource("/com/pansoft/jbsf/oa/bpmn/Urge.png")
		.deploy();
	}

}

启动以上代码之后,数据库表将自动建立

DbKit.getDataSource()为项目中获取DataSource对象

其中new ActivitiTransactionFactory()的ActivitiTransactionFactory事务管理代码为

package com.****.jbsf.util.activiti;

import java.sql.Connection;
import java.util.Properties;

import javax.sql.DataSource;

import org.apache.ibatis.session.TransactionIsolationLevel;
import org.apache.ibatis.transaction.Transaction;
import org.apache.ibatis.transaction.TransactionFactory;


public class ActivitiTransactionFactory implements TransactionFactory {

	@Override
	public void setProperties(Properties props) {
	}

	@Override
	public Transaction newTransaction(Connection conn) {
		return new ActivitiTransaction(conn);
	}

	@Override
	public Transaction newTransaction(DataSource ds, TransactionIsolationLevel level, boolean autoCommit) {
		return new ActivitiTransaction(ds, level, autoCommit);
	}
}

其中ActivitiTransaction对象代码为

package com.****.jbsf.util.activiti;

import java.sql.Connection;
import java.sql.SQLException;

import javax.sql.DataSource;

import org.apache.ibatis.session.TransactionIsolationLevel;
import org.apache.ibatis.transaction.Transaction;

import com.jf.plugin.activerecord.DbKit;


public class ActivitiTransaction implements Transaction {

	protected Connection connection;
	protected DataSource dataSource;
	protected TransactionIsolationLevel level;
	protected boolean autoCommmit;

	public ActivitiTransaction(DataSource ds, TransactionIsolationLevel desiredLevel, boolean desiredAutoCommit) {
		dataSource = ds;
		level = desiredLevel;
		autoCommmit = desiredAutoCommit;
	}

	public ActivitiTransaction(Connection connection) {
		this.connection = connection;
	}

	@Override
	public Connection getConnection() throws SQLException {
		if (connection == null) {
			openConnection();
		}
		return connection;
	}

	@Override
	public void commit() throws SQLException {
	}

	@Override
	public void rollback() throws SQLException {
	}

	@Override
	public void close() throws SQLException {
		if(connection!=null){
			DbKit.close(connection);
		}
	}

	protected void openConnection() throws SQLException {
		connection = DbKit.getConnection();
		if (level != null) {
			connection.setTransactionIsolation(level.getLevel());
		}
	}
}

openConnection对象获取系统内获取Conn对象方法.

需要注意的是,Oracle不同用户对应不同数据库表

如果用户不同对应不同的Schema.初始化的时候通过

conf.setDatabaseSchema(“username”);

切换schema.

使用Jfinal的话,可以不实用servlet的方式加载.

将activiti作为一个插件的形式集成进去.

写一个activitiPlugin.总体代码与servlet的相似.

代码比较多,贴出来的代码中还有,”流程转换为模型”和”创建新模型”还有”加载流程定义”的代码.

具体代码如下:

package com.****.jbsf.plugin;

import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;

import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamReader;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.jf.plugin.IPlugin;
import com.jf.plugin.activerecord.DbKit;

import org.activiti.bpmn.converter.BpmnXMLConverter;
import org.activiti.bpmn.model.BpmnModel;
import org.activiti.editor.constants.ModelDataJsonConstants;
import org.activiti.editor.language.json.converter.BpmnJsonConverter;
import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngineConfiguration;
import org.activiti.engine.ProcessEngines;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration;
import org.activiti.engine.repository.Model;
import org.activiti.engine.repository.ProcessDefinition;
import org.apache.commons.lang3.StringUtils;



import com.****.util.activiti.ActivitiTransactionFactory;

public class ActivitiPlugin implements IPlugin{

	private static ProcessEngine processEngine = null;
	private static ProcessEngineConfiguration processEngineConfiguration = null;
	private boolean isStarted = false;
	@Override
	public boolean start(){
		try {
			createProcessEngine();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return true;
	}

	@Override
	public boolean stop() {
		ProcessEngines.destroy(); 
		isStarted = false;
		return true;
	}

	private Boolean createProcessEngine() throws Exception{
		if (isStarted) {
			return true;
		}
		StandaloneProcessEngineConfiguration conf = (StandaloneProcessEngineConfiguration) ProcessEngineConfiguration
		.createStandaloneProcessEngineConfiguration();
//		conf.setDatabaseSchema("cwbase35_9999");
		conf.setDataSource(DbKit.getDataSource())
		.setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE)
		.setDbHistoryUsed(true);
//		conf.setTransactionsExternallyManaged(true); // 使用托管事务工厂
		conf.setTransactionFactory(new ActivitiTransactionFactory());
		ActivitiPlugin.processEngine = conf.buildProcessEngine();
		isStarted = true;
		//开启流程引擎
		System.out.println("启动流程引擎.......");
		
		/**
		 * 部署流程定义
		 * 以后可以拿出去
		 * */
//		ProcessEngine pe = ProcessEngines.getDefaultProcessEngine();
//		pe.getRepositoryService()
//		.createDeployment()
//		.name("督察催办")
//		.addClasspathResource("/com/****/jbsf/oa/bpmn/Urge.bpmn")
//		.addClasspathResource("/com/****/jbsf/oa/bpmn/Urge.png")
//		.deploy();
//		convertToModel(ActivitiPlugin.processEngine,"Urge:4:17504");
//		createModel(ActivitiPlugin.processEngine);
		return isStarted;
	}

	// 开启流程服务引擎
	public static ProcessEngine buildProcessEngine() {
		if (processEngine == null)
			if (processEngineConfiguration != null) {
				processEngine = processEngineConfiguration.buildProcessEngine();
			}
			return processEngine;
	}
	
	
	/**
	 * 创建新模型
	 * @throws UnsupportedEncodingException 
	 * */
	public void createModel(ProcessEngine pe) throws UnsupportedEncodingException{
		RepositoryService repositoryService = pe.getRepositoryService();
        ObjectMapper objectMapper = new ObjectMapper();
        ObjectNode editorNode = objectMapper.createObjectNode();
        editorNode.put("id", "canvas");
        editorNode.put("resourceId", "canvas");
        ObjectNode stencilSetNode = objectMapper.createObjectNode();
        stencilSetNode.put("namespace", "http://b3mn.org/stencilset/bpmn2.0#");
        editorNode.put("stencilset", stencilSetNode);
        Model modelData = repositoryService.newModel();

        ObjectNode modelObjectNode = objectMapper.createObjectNode();
        modelObjectNode.put(ModelDataJsonConstants.MODEL_NAME, "模型名称");
        modelObjectNode.put(ModelDataJsonConstants.MODEL_REVISION, 1);
        String description = StringUtils.defaultString("模型描述信息");
        modelObjectNode.put(ModelDataJsonConstants.MODEL_DESCRIPTION, description);
        modelData.setMetaInfo(modelObjectNode.toString());
        modelData.setName("模型名称");
        modelData.setKey(StringUtils.defaultString("Urge"));

        repositoryService.saveModel(modelData);
        repositoryService.addModelEditorSource(modelData.getId(), editorNode.toString().getBytes("utf-8"));
	}
	/**
	 * 流程定义转模型
	 * */
	public void convertToModel(ProcessEngine pe,String processDefinitionId) throws Exception{
		RepositoryService repositoryService = pe.getRepositoryService();
        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
                .processDefinitionId(processDefinitionId).singleResult();
        InputStream bpmnStream = repositoryService.getResourceAsStream(processDefinition.getDeploymentId(),
                processDefinition.getResourceName());
        XMLInputFactory xif = XMLInputFactory.newInstance();
        InputStreamReader in = new InputStreamReader(bpmnStream, "UTF-8");
        XMLStreamReader xtr = xif.createXMLStreamReader(in);
        BpmnModel bpmnModel = new BpmnXMLConverter().convertToBpmnModel(xtr);

        BpmnJsonConverter converter = new BpmnJsonConverter();
        com.fasterxml.jackson.databind.node.ObjectNode modelNode = converter.convertToJson(bpmnModel);
        Model modelData = repositoryService.newModel();
        modelData.setKey(processDefinition.getKey());
        modelData.setName(processDefinition.getResourceName());
        modelData.setCategory(processDefinition.getDeploymentId());

        ObjectNode modelObjectNode = new ObjectMapper().createObjectNode();
        modelObjectNode.put(ModelDataJsonConstants.MODEL_NAME, processDefinition.getName());
        modelObjectNode.put(ModelDataJsonConstants.MODEL_REVISION, 1);
        modelObjectNode.put(ModelDataJsonConstants.MODEL_DESCRIPTION, processDefinition.getDescription());
        modelData.setMetaInfo(modelObjectNode.toString());

        repositoryService.saveModel(modelData);

        repositoryService.addModelEditorSource(modelData.getId(), modelNode.toString().getBytes("utf-8"));

    }
}

然后在jfinal插件中注册便可

代码如下

	@Override
	public void configPlugin(Plugins me) {
**************省略代码**********
		ActivitiPlugin ap = new ActivitiPlugin();
		me.add(ap);
		_MappingKit.mapping(arp);//注册所有model-bean
**************省略代码**********
	}

 

作者:丶Lion