Engine解析
1. org.activiti.engine
- 定义了流程管理服务的接口:
RepositoryService
、RuntimeService
、FormService
、TaskService
、HistoryService
、IdentityService
、ManagementService
。
定义了引擎配置管理接口
ProcessEngineConfiguration
。定义了activiti异常类
ActivitiException
。
org.activiti.engine是activiti的核心功能,控制工作流的流转。几个核心的类如下图所示:
1.1 ProcessEngine
ProcessEngine
接口继承EngineServices
,EngineServices
包括很多工作流/BPM方法的服务,它们都是线程安全的。EngineServices
提供的服务包括:
RepositoryService:
提供了管理和控制流程定义的操作。RuntimeService:
提供了管理和控制流程实例的操作。FormService:
提供了管理流程表单的操作,即使不用FormService
,activiti也可以完美运行。TaskService:
提供了任务管理的操作,包括实例任务挂起
、激活
、完成
、暂停
、查询
。HistoryService:
提供对历史流程,历史任务,历史变量的查询操作。IdentityService:
提供用户和组管理的操作(创建,更新,删除,查询...)。ManagementService:
提供了查询和管理异步操作(定时器,异步操作, 延迟暂停、激活等)的功能,它还可以查询到数据库的表和表的元数据。
EngineServices
代码如下所示:
public interface EngineServices {
RepositoryService getRepositoryService();
RuntimeService getRuntimeService();
FormService getFormService();
TaskService getTaskService();
HistoryService getHistoryService();
IdentityService getIdentityService();
ManagementService getManagementService();
ProcessEngineConfiguration getProcessEngineConfiguration();
}
ProcessEngine
代码如下所示:
public interface ProcessEngine extends EngineServices {
/** the version of the activiti library */
public static String VERSION = "5.17.0.2";
/** The name as specified in 'process-engine-name' in
* the activiti.cfg.xml configuration file.
* The default name for a process engine is 'default */
String getName();
void close();
}
1.2 ProcessEngineConfiguration
ProcessEngineConfiguration
是配置管理类,它管理的对象包括ProcessEngine,XXservice,数据库session等。ProcessEngineConfiguration
的配置,activiti默认会从activiti.cfg.xml中读取,也可以在Spring的配置文件中读取。ProcessEngineConfiguration
的实现包括:
ProcessEngineConfigurationImpl
继承ProcessEngineConfiguration
,实现了各种Service的初始化StandaloneProcessEngineConfiguration
是单独运行的流程引擎,继承ProcessEngineConfigurationImpl
。代码如下:
public class StandaloneProcessEngineConfiguration extends ProcessEngineConfigurationImpl {
@Override
protected CommandInterceptor createTransactionInterceptor() {
return null;
}
}
-
StandaloneInMemProcessEngineConfiguration
是单元测试时的辅助类,继承StandaloneProcessEngineConfiguration
,默认使用H2内存数据库。数据库表会在引擎启动时创建,关闭时删除。代码如下所示:
public class StandaloneInMemProcessEngineConfiguration extends StandaloneProcessEngineConfiguration {
public StandaloneInMemProcessEngineConfiguration() {
this.databaseSchemaUpdate = DB_SCHEMA_UPDATE_CREATE_DROP;
this.jdbcUrl = "jdbc:h2:mem:activiti";
}
}
SpringProcessEngineConfiguration
是Spring环境下使用的流程引擎。JtaProcessEngineConfiguration
单独运行的流程引擎,并使用JTA事务。
1.3 ActivitiException
activiti的基础异常类是org.activiti.engine.ActivitiException
,一个非检查异常。Activiti的异常都是通过org.activiti.engine.ActivitiException
抛出,但存在以下特殊情况:
ActivitiWrongDbException:
当Activiti引擎发现数据库版本号和引擎版本号不一致时抛出。ActivitiOptimisticLockingException:
对同一数据进行并发方法并出现乐观锁时抛出。ActivitiClassLoadingException:
当无法找到需要加载的类或在加载类时出现了错误(比如,JavaDelegate,TaskListener等。ActivitiObjectNotFoundException:
当请求或操作的对应不存在时抛出。ActivitiIllegalArgumentException:
这个异常表示调用Activiti API时传入了一个非法的参数,可能是引擎配置中的非法值,或提供了一个非法制,或流程定义中使用的非法值。ActivitiTaskAlreadyClaimedException:
当任务已经被认领了,再调用taskService.claim(...)就会抛出。BpmnError:
流程部署错误,如流程定义文件不合法。JobNotFoundException:
JOB不存在。
2. org.activiti.engine.impl
- 实现了流程管理服务
RepositoryServiceImpl
,RuntimeServiceImpl
,FormServiceImpl
,TaskServiceImpl
,HistoryServiceImpl
,IdentityServiceImpl
,ManagementServiceImpl
实现流程虚拟机PVM
数据持久化,脚本任务,条件表达式EL的解析等等
命令接口的定义
2.1 org.activiti.engine.impl.ServiceImpl
-
XXService
的定义
org.activiti.engine.impl.ServiceImpl
是流程管理服务的基类,它的派生类包括RepositoryServiceImpl
, RuntimeServiceImpl
, FormServiceImpl
, TaskServiceImpl
, HistoryServiceImpl
, IdentityServiceImpl
, ManagementServiceImpl
,它定义了配置管理服务processEngineConfiguration
、命令执行接口commandExecutor
(activiti方法调用都通过命令模式)。源码如下所示:
public class ServiceImpl {
protected ProcessEngineConfigurationImpl processEngineConfiguration;
public ServiceImpl() {
}
public ServiceImpl(ProcessEngineConfigurationImpl processEngineConfiguration) {
this.processEngineConfiguration = processEngineConfiguration;
}
protected CommandExecutor commandExecutor;
public CommandExecutor getCommandExecutor() {
return commandExecutor;
}
public void setCommandExecutor(CommandExecutor commandExecutor) {
this.commandExecutor = commandExecutor;
}
}
XXServiceImpl
继承类org.activiti.engine.impl.ServiceImpl
,并且实现对应的XXService
接口。下面是RepositoryServiceImpl
示例代码:
public class RepositoryServiceImpl extends ServiceImpl implements RepositoryService {
}
-
XXService
的初始化
XXService
的初始化在ProcessEngineConfigurationImpl中
protected RepositoryService repositoryService = new RepositoryServiceImpl();
protected RuntimeService runtimeService = new RuntimeServiceImpl();
protected HistoryService historyService = new HistoryServiceImpl(this);
protected IdentityService identityService = new IdentityServiceImpl();
protected TaskService taskService = new TaskServiceImpl(this);
protected FormService formService = new FormServiceImpl();
protected ManagementService managementService = new ManagementServiceImpl();
XXService
的commandExecutor
初始化在ProcessEngineConfigurationImpl的initService中
protected void initService(Object service) {
if (service instanceof ServiceImpl) {
((ServiceImpl)service).setCommandExecutor(commandExecutor);
}
}
2.2 org.activiti.engine.impl.interceptor
包org.activiti.engine.impl.interceptor
定义了拦截器和命令。activiti里面所有的指令都是通过命令模式执行,在命令执行之前,可以切入多个拦截器。
commandContext
是命令上下文。command
是命令接口,command
中定义了execute
方法,代码如下所示:
public interface Command {
T execute(CommandContext commandContext);
}
-
CommandExecutor
这个是命令的执行方法,CommandConfig
是CommandExecutor
的配置。CommandExecutor
代码如下所示:
public interface CommandExecutor {
/**
* @return the default {@link CommandConfig}, used if none is provided.
*/
CommandConfig getDefaultConfig();
/**
* Execute a command with the specified {@link CommandConfig}.
*/
T execute(CommandConfig config, Command command);
/**
* Execute a command with the default {@link CommandConfig}.
*/
T execute(Command command);
}
-
CommandInterceptor
拦截器,在命令执行之前进行拦截,一个命令可以有多个拦截器,这些拦截器通过链表链接起来顺序执行。CommandInterceptor
代码如下:
public interface CommandInterceptor {
T execute(CommandConfig config, Command command);
CommandInterceptor getNext();
void setNext(CommandInterceptor next);
}
- commandExecutor到底是如何注入的?
以RuntimeServiceImpl
为例, RuntimeServiceImpl
继承类ServiceImpl
,ServiceImpl
包含CommandExecutor
属性
在ProcessEngineConfigurationImpl
中有个init方法,里面有对于executor和intecerptor的初始化
// 初始化各种服务
protected void initServices() {
initService(repositoryService);
initService(runtimeService);
initService(historyService);
initService(identityService);
initService(taskService);
initService(formService);
initService(managementService);
}
// 初始化服务方法
protected void initService(Object service) {
if (service instanceof ServiceImpl) {
((ServiceImpl)service).setCommandExecutor(commandExecutor);
}
}
// 初始化拦截器
protected void initCommandInterceptors() {
if (commandInterceptors==null) {
commandInterceptors = new ArrayList();
if (customPreCommandInterceptors!=null) {
commandInterceptors.addAll(customPreCommandInterceptors);
}
commandInterceptors.addAll(getDefaultCommandInterceptors());
if (customPostCommandInterceptors!=null) {
commandInterceptors.addAll(customPostCommandInterceptors);
}
commandInterceptors.add(commandInvoker);
}
}
// 将拦截器初始化成链式结构
protected void initCommandExecutor() {
if (commandExecutor==null) {
CommandInterceptor first = initInterceptorChain(commandInterceptors);
commandExecutor = new CommandExecutorImpl(getDefaultCommandConfig(), first);
}
}
2.3 org.activiti.engine.impl.delegate
包org.activiti.engine.impl.delegate
实现了监听器和事件处理,activiti 允许客户端代码介入流程的执行,为此提供了这个基础组件。
activiti5.16 用户手册的介绍,监听器,事件处理。
2.3.1 监听器
监听器可以捕获的事件包括:
- 流程实例的启动和结束
- 选中一条连线
- 节点的开始和结束
- 网关的开始和结束
- 中间事件的开始和结束
- 开始时间结束或结束事件开始
DelegateInterceptor
是事件拦截器接口,DelegateInvocation
是事件调用接口,XXXInvocation
是DelegateInvocation
的实现类,XXXInvocation
里面包含监听接口XXXListener
。
- 怎样添加监听
下面的流程定义文件包含2个监听器,event
表示时间类型,class
表示处理事件的java类。
CreateTaskDelegate
是客户端实现的监听类,
TaskListener``是activiti的监听接口。
package com.alfrescoblog.MyTest.imple;
import org.activiti.engine.delegate.DelegateTask;
import org.activiti.engine.delegate.TaskListener;
public class CreateTaskDelegate implements TaskListener {
public void notify(DelegateTask delegateTask) {
// TODO Auto-generated method stub
System.out.println("创建任务啦!!");
}
}
TaskListener
代码如下所示:
public interface TaskListener extends Serializable {
String EVENTNAME_CREATE = "create";
String EVENTNAME_ASSIGNMENT = "assignment";
String EVENTNAME_COMPLETE = "complete";
String EVENTNAME_DELETE = "delete";
/**
* Not an actual event, used as a marker-value for {@link TaskListener}s that should be called for all events,
* including {@link #EVENTNAME_CREATE}, {@link #EVENTNAME_ASSIGNMENT} and {@link #EVENTNAME_COMPLETE} and {@link #EVENTNAME_DELETE}.
*/
String EVENTNAME_ALL_EVENTS = "all";
void notify(DelegateTask delegateTask);
}
- 监听怎样被注入的
BPMN流程文件部署的时候会注入各种listener。比如TaskListener在org.activiti.engine.impl.task.TaskDefinition的addTaskListener方法中被注入,代码如下:
public void addTaskListener(String eventName, TaskListener taskListener) {
if(TaskListener.EVENTNAME_ALL_EVENTS.equals(eventName)) {
// In order to prevent having to merge the "all" tasklisteners with the ones for a specific eventName,
// every time "getTaskListener()" is called, we add the listener explicitally to the individual lists
this.addTaskListener(TaskListener.EVENTNAME_CREATE, taskListener);
this.addTaskListener(TaskListener.EVENTNAME_ASSIGNMENT, taskListener);
this.addTaskListener(TaskListener.EVENTNAME_COMPLETE, taskListener);
this.addTaskListener(TaskListener.EVENTNAME_DELETE, taskListener);
} else {
List taskEventListeners = taskListeners.get(eventName);
if (taskEventListeners == null) {
taskEventListeners = new ArrayList();
taskListeners.put(eventName, taskEventListeners);
}
taskEventListeners.add(taskListener);
}
}
- 监听在什么时候触发的
以TaskListener为例,调用链:UserTaskActivityBehavior.execute()
→ task.fireEvent(TaskListener.EVENTNAME_CREATE);
→ DelegateInterceptor.handleInvocation()
→ DefaultDelegateInterceptor.handleInvocation()
→ DelegateInvocation.proceed()
→ TaskListenerInvocation.invoke()
→ TaskListener.notify()
UserTaskActivityBehavior
是任务新增、修改、删除行为,UserTask节点解析(UserTaskParseHandler.executeParse)的时候设置到activiti中,触发的代码还没找到。
protected void executeParse(BpmnParse bpmnParse, UserTask userTask) {
ActivityImpl activity = createActivityOnCurrentScope(bpmnParse, userTask, BpmnXMLConstants.ELEMENT_TASK_USER);
activity.setAsync(userTask.isAsynchronous());
activity.setExclusive(!userTask.isNotExclusive());
TaskDefinition taskDefinition = parseTaskDefinition(bpmnParse, userTask, userTask.getId(), (ProcessDefinitionEntity) bpmnParse.getCurrentScope().getProcessDefinition());
activity.setProperty(PROPERTY_TASK_DEFINITION, taskDefinition);
activity.setActivityBehavior(bpmnParse.getActivityBehaviorFactory().createUserTaskActivityBehavior(userTask, taskDefinition));
}
参考资料
- activiti数据表结构
- Activiti 5.16 用户手册
- Activiti User Guide
- activiti与BPMN
- activiti源码
- activiti_doc文档