activiti总体框架分析

作者: 西普士 | 来源:发表于2016-08-11 10:07 被阅读1144次

    Engine解析

    activiti包.png

    1. org.activiti.engine

    1. 定义了流程管理服务的接口:RepositoryServiceRuntimeServiceFormServiceTaskServiceHistoryServiceIdentityServiceManagementService
    • 定义了引擎配置管理接口ProcessEngineConfiguration

    • 定义了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
    • 实现流程虚拟机PVM

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

    • 命令接口的定义

    命令接口包.png

    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. 流程实例的启动和结束
    • 选中一条连线
    • 节点的开始和结束
    • 网关的开始和结束
    • 中间事件的开始和结束
    • 开始时间结束或结束事件开始
    执行监听器

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

    参考资料

    相关文章

      网友评论

        本文标题:activiti总体框架分析

        本文链接:https://www.haomeiwen.com/subject/ngojsttx.html