activity(流程引擎)从零入门到实战学习
欢迎使用Markdown编辑器
从本编文章开始,将开始详细介绍activiti的源码,本片文章主要介绍内容有拉取activiti6源码,进行编译启动,最后在源码基础之上完成helloworld的编码,为之后我们的二次开发工作做好铺垫。
1.如何拉取源码?
actviti是基本apache2.0开源协议的开源项目,我们可以从activiti官网直接获取github仓库地址然后拉到自己仓库,在同步到本地即可,相信这些基础操作不用多作累述。
注意check到6.0分支,本专栏主要针对activiti6.0作介绍。
2.目录文件说明
distro—发布时的配置文件
eclipse—eclipse开发所用的一些配置文件
modules—最重要的源码包结构
qa—跟qa、质量相关的,还有测试所配置的一些脚本文件
scripts—跟启动相关的一些脚本文件
tooling—根据maven的规则定制的脚手架工具
activiti-app
我们首先关注activiti-app这个模块,这个模块即Activiti官方提供基于activiti流程引擎的B/S应用。其中又包含了几个具体模块如下:
activiti-ui整个模块中没有java代码,activiti-app这个模块是前端整个项目的入口,这里面配置了前端如何与后台注册服务等。打开activiti-app目录下的web.xml开始分析,在这里注册了一个叫WebConfigurer的listener。点进去可以看到当我们前端应用启动时,需要跟后台相互交互的内容。
这个WebConfigurer listener其实参考了SpringMvc对应的LoadContextListener,在初始化目的主要是为了构造spring容器。在SpringMVC中主要是配置dispatcherServlet过程,在activiti中同等配置了
两个Servlet(web3.0之后可以在代码中,通过代码构造servlet),一个对应APP目录,一个对应API目录。这里涉及到一个根容器和两个子容器。
AppContextDispatcherServlet | ApiContextDispatcherServlet |
---|---|
对应activiti业务暴露出来的url | 对应activiti-rest对外提供的一些API |
3.helloworld
从现在开始我们即将在activiti的基础功能之上,初次尝试去调用activiti的各个服务接口。现在我们做一个简单的流程图,并且调动activiti流程引擎去驱动它。整个过程的搭建所需要的工具如下:
定了一个简单的审批流程,流程图如下:
3.1创建流程
这里我们使用Eclipse集成activiti bpmn插件进行流程图的绘制,并且设置任务节点的需要参数,最终会生成.bpmn文件,其实里面全是XML格式的数据(所以也可以转json数据存储)。
eclipse安装插件的方法请参考:http://blog.yixao.net/share/14597.html
3.2创建maven工程
创建maven工程就不详细说明了,这里面只需要引入activiti的核心引擎包(当然还有一些测试,日志包就不单独提出来说了)即可。
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-engine</artifactId>
<version>6.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.1.11</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>20.0</version>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.3.176</version>
</dependency>
接下来,我们直接写一个main方法来把流程驱动起来。
主要代码如下:
![](/qrcode.jpg)
public static void main(String[] args) throws ParseException {
log.info("程序开始====================");
//1.创建流程引擎
ProcessEngine processEngine = getProcessEngine();
//2.部署流程定义文件
ProcessDefinition processDefinition = getProcessDefinition(processEngine);
//3.启动运行流程
ProcessInstance processInstance = getProcessInstance(processEngine, processDefinition);
//4.处理流程任务
Scanner scanner=new Scanner(System.in);
while(processInstance!=null&&!processInstance.isEnded()){
TaskService taskService = processEngine.getTaskService();
List<Task> tasks = taskService.createTaskQuery().list();
log.info("待处理任务数量:{}",tasks.size());
for (Task task:tasks){
log.info("待处理任务:{}",task.getName());
FormService formService = processEngine.getFormService();
TaskFormData taskFormData = formService.getTaskFormData(task.getId());
List<FormProperty> formProperties = taskFormData.getFormProperties();
Map<String,Object> variables= Maps.newHashMap();
for (FormProperty formProperty : formProperties) {
String line =null;
if(StringFormType.class.isInstance(formProperty.getType())){
log.info("请输出{}?",formProperty.getName());
line =scanner.nextLine();
variables.put(formProperty.getId(),line);
}else if(DateFormType.class.isInstance(formProperty.getType())){
log.info("请输出{}?格式(yyyy-MM-dd)",formProperty.getName());
line =scanner.nextLine();
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
Date date=simpleDateFormat.parse(line);
variables.put(formProperty.getId(),date);
}else{
log.info("类型暂不支持");
}
log.info("您输入的内容是:【{}】?",line);
}
//提交任务
taskService.complete(task.getId(),variables);
//获取流程实例最新状态
processInstance=processEngine.getRuntimeService().createProcessInstanceQuery()
.processInstanceId(processInstance.getId()).singleResult();
}
}
log.info("程序结束====================");
}
执行结果如下:
至此我们已经成功按照自己的方式,从定义一个流程图到代码驱动流程的整个过程(即实现了流程引擎的helloworld)。