参考资料

Engine解析

package 描述
org.activiti.engine 流程引擎公共API方法,均采用链式方式
一般通过ProcessEngineConfiguration创建

可以获得的服务包括:
RepositoryService
RuntimeService
TaskService
IdentityService
ManagementService
HistoryService
FormService
org.activiti.engine.impl engine模块的核心,包含了:
pvm的实现
接口方法的实现
命令模式
org.activiti.engine.cfg 配置接口
org.activiti.engine.ProcessEngine 引擎接口
org.activiti.engine.ProcessEngineConfiguration 配置管理
org.activiti.engine.ActivitiException 基础异常类
org.activiti.engine.delegate
org.activiti.engine.form 表单信息,和FormService相关联
org.activiti.engine.history 流程历史信息,和HistoryService相关联
org.activiti.engine.identity 用户、组管理信息,和IdentityService相关联
org.activiti.engine.logging 日志
org.activiti.engine.management 流程管理和控制信息,和ManagementService相关联
org.activiti.engine.repository 流程资源信息,和RepositoryService相关联
org.activiti.engine.runtime 流程运行时相关信息,和RuntimeService相关联
org.activiti.engine.task 表示任务相关信息,和TaskService相关联

1. org.activiti.engine

  1. 定义了流程管理服务的接口:RepositoryServiceRuntimeServiceFormServiceTaskServiceHistoryServiceIdentityServiceManagementService

  2. 定义了引擎配置管理接口ProcessEngineConfiguration

  3. 定义了activiti异常类ActivitiException

org.activiti.engine是activiti的核心功能,控制工作流的流转。几个核心的类如下图所示:

engine

1.1 ProcessEngine

ProcessEngine接口继承EngineServicesEngineServices包括很多工作流/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

  1. 实现了流程管理服务RepositoryServiceImpl, RuntimeServiceImpl, FormServiceImpl, TaskServiceImpl, HistoryServiceImpl, IdentityServiceImpl, ManagementServiceImpl

  2. 实现流程虚拟机PVM

  3. 数据持久化,脚本任务,条件表达式EL的解析等等

  4. 命令接口的定义

package 描述
org.activiti.engine.impl.asyncexecutor job调度,主要管理调度线程
org.activiti.engine.impl.bpmn 部署文件,BPMN元素管理
org.activiti.engine.impl.calendar 时间,日期管理
org.activiti.engine.impl.cfg ProcessEngineConfiguration的实现
org.activiti.engine.impl.cmd 命令模式的client,实现了各种命令
org.activiti.engine.impl.context 上下文定义文件,保存线程数据
org.activiti.engine.impl.db 数据库基本增删改操作
org.activiti.engine.impl.delegate 任务监听
org.activiti.engine.impl.el 表达式解析,执行
org.activiti.engine.impl.event 事件
org.activiti.engine.impl.form 表单
org.activiti.engine.impl.history 历史
org.activiti.engine.impl.interceptor 拦截器的定义
org.activiti.engine.impl.javax.el ????
org.activiti.engine.impl.jobexecutor 控制job的执行
org.activiti.engine.impl.juel 对el的扩展
org.activiti.engine.impl.persistence 数据库实体的定义
org.activiti.engine.impl.pvm 流程虚拟机,整个流程的流转,分支该怎么走都靠它了
org.activiti.engine.impl.transformer 基础类型转换,Long转String之类的
org.activiti.engine.impl.ServiceImpl 流程管理服务类

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();
    

    XXServicecommandExecutor初始化在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> {
      T execute(CommandContext commandContext);
    }
    
  • CommandExecutor这个是命令的执行方法,CommandConfigCommandExecutor的配置。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> T execute(CommandConfig config, Command<T> command);
    
      /**
       * Execute a command with the default {@link CommandConfig}.
       */
      <T> T execute(Command<T> command);
    
    }
    
  • CommandInterceptor拦截器,在命令执行之前进行拦截,一个命令可以有多个拦截器,这些拦截器通过链表链接起来顺序执行。CommandInterceptor代码如下:

    public interface CommandInterceptor {
    
      <T> T execute(CommandConfig config, Command<T> command);
    
      CommandInterceptor getNext();
    
      void setNext(CommandInterceptor next);
    
    }
    
  • commandExecutor到底是如何注入的?

    RuntimeServiceImpl为例, RuntimeServiceImpl继承类ServiceImplServiceImpl包含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<CommandInterceptor>();
          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 监听器

监听器可以捕获的事件包括:

  1. 流程实例的启动和结束
  2. 选中一条连线
  3. 节点的开始和结束
  4. 网关的开始和结束
  5. 中间事件的开始和结束
  6. 开始时间结束或结束事件开始

执行监听器

DelegateInterceptor是事件拦截器接口,DelegateInvocation是事件调用接口,XXXInvocationDelegateInvocation的实现类,XXXInvocation里面包含监听接口XXXListener

  • 怎样添加监听

    下面的流程定义文件包含2个监听器,event表示时间类型,class表示处理事件的java类。

    <extensionElements>
      <activiti:taskListener event="create" class="com.alfrescoblog.MyTest.imple.CreateTaskDelegate"></activiti:taskListener>
      <activiti:taskListener event="complete" class="com.alfrescoblog.MyTest.imple.MyJavaDelegate"></activiti:taskListener>
    </extensionElements>
    

    ``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<TaskListener> taskEventListeners = taskListeners.get(eventName);
        if (taskEventListeners == null) {
          taskEventListeners = new ArrayList<TaskListener>();
          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));
    }