Activiti总体框架分析

参考资料

Engine解析

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

可以获得的服务包括:
RepositoryService
RuntimeService
TaskService
IdentityService
ManagementService
HistoryService
FormService
org.activiti.engine.implengine模块的核心,包含了:
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. 定义了流程管理服务的接口:RepositoryServiceRuntimeService、 FormServiceTaskServiceHistoryServiceIdentityService、 ManagementService 。

  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. 实现了流程管理服务RepositoryServiceImplRuntimeServiceImplFormServiceImplTaskServiceImplHistoryServiceImplIdentityServiceImplManagementServiceImpl

  2. 实现流程虚拟机PVM

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

  4. 命令接口的定义

package描述
org.activiti.engine.impl.asyncexecutorjob调度,主要管理调度线程
org.activiti.engine.impl.bpmn部署文件,BPMN元素管理
org.activiti.engine.impl.calendar时间,日期管理
org.activiti.engine.impl.cfgProcessEngineConfiguration的实现
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是流程管理服务的基类,它的派生类包括RepositoryServiceImplRuntimeServiceImplFormServiceImplTaskServiceImplHistoryServiceImplIdentityServiceImplManagementServiceImpl,它定义了配置管理服务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));
    }

from: https://haibinpark.gitbooks.io/activiti-develop-plan/content/activiti_analysis/whole_framework.html#%E5%8F%82%E8%80%83%E8%B5%84%E6%96%99

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值