SnakerFlow是一款类似于Activiti和BPMN的流程引擎,2014年已停更了,但并不影响使用。建议使用2.4.0版本别问我为什么,可以分别看看他们的源码就明白了。
最近公司需要使用该流程插件,所以就去研究了一下
首先在pom文件中引入Snaker的三个主要的依赖还有一个定时任务的依赖根据需求加
com.github.snakerflow
snaker-core
2.4.0
org.slf4j
slf4j-api
com.github.snakerflow
snaker-spring
2.4.0
org.slf4j
slf4j-api
com.github.snakerflow
snaker-mybatis
2.4.0
接下来就是配置Snaker自定义一个配置文件application-snakerflow.xml
之后还需要在spring中进行配置,在spring配置文件中需要引入mybaits的配置文件,而该配置文件理扫描的是snaker-core里的snaker所要用的mapper文件所以需要对其进行扫描再由spring容器进行事务管理。
而spring中在配置sqlSessionfactory bean时需要引入mybaits配置文件,之后就是对snaker中的方法进行事务管理
这样你就可以正常运行了,至于使用springboot怎么使spring文件和snaker配置文件生效,这就是另外的方面了 个人使用注解引入外部配置文件,用着也很方便,
使用的话我提供一个引擎大家可以复制下来对其进行调整,其实就是在作者的基础上进行了改进而已
/* Copyright 2013-2015 www.snakerflow.com
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alijk.bq.workflow.engine.impl;
import com.alijk.bq.workflow.engine.SnakerEngineFacade;
import org.apache.commons.lang.StringUtils;
import org.snaker.engine.DBAccess;
import org.snaker.engine.IProcessService;
import org.snaker.engine.SnakerEngine;
import org.snaker.engine.access.Page;
import org.snaker.engine.access.QueryFilter;
import org.snaker.engine.core.AccessService;
import org.snaker.engine.core.SnakerEngineImpl;
import org.snaker.engine.entity.*;
import org.snaker.engine.entity.Process;
import org.snaker.engine.model.TaskModel.TaskType;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @Component(把普通pojo实例化到spring容器中,相当于配置文件中的 )
*
*/
@Component("snakerEngineFacade")
public class SnakerEngineFacadeImpl implements SnakerEngineFacade, InitializingBean {
@Autowired
private SnakerEngine engine;
private IProcessService process;
public SnakerEngine getEngine() {
return engine;
}
@Override
public void afterPropertiesSet() throws Exception {
process = engine.process();
}
public IProcessService getProcess() {
return process;
}
/**
* 得到所有流程定义的名称
*
* @return
*/
public List getAllProcessNames() {
List list = engine.process().getProcesss(new QueryFilter());
List names = new ArrayList();
for (Process entity : list) {
if (names.contains(entity.getName())) {
continue;
} else {
names.add(entity.getName());
}
}
return names;
}
public Order startInstanceById(String processId, String operator, Map args) {
return engine.startInstanceById(processId, operator, args);
}
public Order startInstanceByName(String name, Integer version, String operator, Map args) {
return engine.startInstanceByName(name, version, operator, args);
}
public Order startAndExecute(String name, Integer version, String operator, Map args) {
Order order = engine.startInstanceByName(name, version, operator, args);
List tasks = engine.query().getActiveTasks(new QueryFilter().setOrderId(order.getId()));
List newTasks = new ArrayList();
if (tasks != null && tasks.size() > 0) {
Task task = tasks.get(0);
newTasks.addAll(engine.executeTask(task.getId(), operator, args));
}
return order;
}
public Order startAndExecute(String processId, String operator, Map args) {
Order order = engine.startInstanceById(processId, operator, args);
List tasks = engine.query().getActiveTasks(new QueryFilter().setOrderId(order.getId()));
List newTasks = new ArrayList();
if (tasks != null && tasks.size() > 0) {
Task task = tasks.get(0);
newTasks.addAll(engine.executeTask(task.getId(), operator, args));
}
return order;
}
public List execute(String taskId, String operator, Map args) {
return engine.executeTask(taskId, operator, args);
}
public List executeAndJump(String taskId, String operator, Map args, String nodeName) {
return engine.executeAndJumpTask(taskId, operator, args, nodeName);
}
public List transferMajor(String taskId, String operator, String... actors) {
List tasks = engine.task().createNewTask(taskId, TaskType.Major.ordinal(), actors);
engine.task().complete(taskId, operator);
return tasks;
}
public List transferAidant(String taskId, String operator, String... actors) {
List tasks = engine.task().createNewTask(taskId, TaskType.Aidant.ordinal(), actors);
engine.task().complete(taskId, operator);
return tasks;
}
public Map flowData(String orderId, String taskName) {
Map data = new HashMap();
if (StringUtils.isNotEmpty(orderId) && StringUtils.isNotEmpty(taskName)) {
List histTasks = engine.query()
.getHistoryTasks(
new QueryFilter().setOrderId(orderId).setName(
taskName));
List
public interface SnakerEngineFacade {
/**
* 得到所有流程定义的名称
*
* @return
*/
public List getAllProcessNames();
public Order startInstanceById(String processId, String operator, Map args);
public Order startInstanceByName(String name, Integer version, String operator, Map args);
public Order startAndExecute(String name, Integer version, String operator, Map args);
public Order startAndExecute(String processId, String operator, Map args);
public List execute(String taskId, String operator, Map args);
public List executeAndJump(String taskId, String operator, Map args, String nodeName);
public List transferMajor(String taskId, String operator, String... actors);
public List transferAidant(String taskId, String operator, String... actors);
public Map flowData(String orderId, String taskName);
public void addSurrogate(Surrogate entity) ;
public void deleteSurrogate(String id);
public Surrogate getSurrogate(String id);
public List searchSurrogate(Page page, QueryFilter filter);
}
@Autowired
private SnakerEngineFacadeImpl snakerEngineFacade;
这样你就可以调用其中的接口了 其实可以根据个人需求进行修改。
在最初使用snaker时在网上找的博客文档都是存在一些问题的,几乎没有和springboot整合的,好像只有一个但很简单,其实不管是springmvc、Struts还是springboot都只是一个框架,都不印象它的使用,个人在对snaker还是存在一些看法,打算在公司忙完项目之后对其进行修整,比如剔除hibernate作为持久层,以及对个别需求进行改进。到时候会跟大家分享。同时也会尊重原创作者snaker。一位了不起的大佬。