前面关于eventType的属性值的配置简单的说了一下,activiti支持的值如下表所示:这是我摘抄的activiti官网的
Event 的名字 | 描述 | Event的类名 |
ENGINE_CREATED | The process-engine this listener is attached to, has been created and is ready for API-calls. |
|
ENGINE_CLOSED | The process-engine this listener is attached to, has been closed. API-calls to the engine are no longer possible. |
|
ENTITY_CREATED | A new entity is created. The new entity is contained in the event. |
|
ENTITY_INITIALIZED | A new entity has been created and is fully initialized. If any children are created as part of the creation of an entity, this event will be fired AFTER the create/initialisation of the child entities as opposed to the |
|
ENTITY_UPDATED | An existing is updated. The updated entity is contained in the event. |
|
ENTITY_DELETED | An existing entity is deleted. The deleted entity is contained in the event. |
|
ENTITY_SUSPENDED | An existing entity is suspended. The suspended entity is contained in the event. Will be dispatched for ProcessDefinitions, ProcessInstances and Tasks. |
|
ENTITY_ACTIVATED | An existing entity is activated. The activated entity is contained in the event. Will be dispatched for ProcessDefinitions, ProcessInstances and Tasks. |
|
JOB_EXECUTION_SUCCESS | A job has been executed successfully. The event contains the job that was executed. |
|
JOB_EXECUTION_FAILURE | The execution of a job has failed. The event contains the job that was executed and the exception. |
|
JOB_RETRIES_DECREMENTED | The number of job retries have been decremented due to a failed job. The event contains the job that was updated. |
|
TIMER_FIRED | A timer has been fired. The event contains the job that was executed? |
|
JOB_CANCELED | A job has been canceled. The event contains the job that was canceled. Job can be canceled by API call, task was completed and associated boundary timer was canceled, on the new process definition deployment. |
|
ACTIVITY_STARTED | An activity is starting to execute |
|
ACTIVITY_COMPLETED | An activity is completed successfully |
|
ACTIVITY_CANCELLED | An activity is going to be cancelled. There can be three reasons for activity cancellation (MessageEventSubscriptionEntity, SignalEventSubscriptionEntity, TimerEntity). |
|
ACTIVITY_SIGNALED | An activity received a signal |
|
ACTIVITY_MESSAGE_RECEIVED | An activity received a message. Dispatched before the activity receives the message. When received, a |
|
ACTIVITY_ERROR_RECEIVED | An activity has received an error event. Dispatched before the actual error has been handled by the activity. The event’s |
|
UNCAUGHT_BPMN_ERROR | An uncaught BPMN error has been thrown. The process did not have any handlers for that specific error. The event’s |
|
ACTIVITY_COMPENSATE | An activity is about to be compensated. The event contains the id of the activity that is will be executed for compensation. |
|
VARIABLE_CREATED | A variable has been created. The event contains the variable name, value and related execution and task (if any). |
|
VARIABLE_UPDATED | An existing variable has been updated. The event contains the variable name, updated value and related execution and task (if any). |
|
VARIABLE_DELETED | An existing variable has been deleted. The event contains the variable name, last known value and related execution and task (if any). |
|
TASK_ASSIGNED | A task has been assigned to a user. The event contains the task |
|
TASK_CREATED | A task has been created. This is dispatched after the |
|
TASK_COMPLETED | A task has been completed. This is dispatched before the |
|
PROCESS_COMPLETED | A process has been completed. Dispatched after the last activity |
|
PROCESS_CANCELLED | A process has been cancelled. Dispatched before the process instance is deleted from runtime. Process instance is cancelled by API call |
|
MEMBERSHIP_CREATED | A user has been added to a group. The event contains the ids of the user and group involved. |
|
MEMBERSHIP_DELETED | A user has been removed from a group. The event contains the ids of the user and group involved. |
|
MEMBERSHIPS_DELETED | All members will be removed from a group. The event is thrown before the members are removed, so they are still accessible. No individual |
|
简单的说明:
所有的ENTITY_\*事件关联流程引擎的entity-event事件,具体的entity-event监听的范围有这些:
ENTITY_CREATED, ENTITY_INITIALIZED, ENTITY_DELETED
: Attachment, Comment, Deployment, Execution, Group, IdentityLink, Job, Model, ProcessDefinition, ProcessInstance, Task, User.ENTITY_UPDATED
: Attachment, Deployment, Execution, Group, IdentityLink, Job, Model, ProcessDefinition, ProcessInstance, Task, User.ENTITY_SUSPENDED, ENTITY_ACTIVATED
: ProcessDefinition, ProcessInstance/Execution, Task.
补充说明:
事件监听器仅仅会监听流程引擎里面的事件发生,所以如果你有其他的引擎在运行同一个数据库里面,仅仅是在同一个流程引擎中注册的事件监听器会被调用,在其他流程引擎中注册的,即使在同一个JVM运行也不会生效。即使是这样,你需要谨慎和更新/操作实体参与派遣的事件。
三、工作流核心--流程引擎
Activiti的流程引擎穿插在整个工作流中,从ProcessEngine中你可以获取不同的service, ProcessEngine和Service对象都是线程安全的,所以在整个服务器中你只需要存在这些单例对象就可以了。
ProcessEngine和Service对象的创建方式如下:
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
RuntimeService runtimeService = processEngine.getRuntimeService();
RepositoryService repositoryService = processEngine.getRepositoryService();
TaskService taskService = processEngine.getTaskService();
ManagementService managementService = processEngine.getManagementService();
IdentityService identityService = processEngine.getIdentityService();
HistoryService historyService = processEngine.getHistoryService();
FormService formService = processEngine.getFormService();
ProcessEngines.getDefaultProcessEngine(),合理的关闭和初始化所有的ProcessEngine的方法是:ProcessEngines.destroy()和ProcessEngines.init() 。ProcessEngines对象将会扫描所有不同目录的activiti.cfg.xml和activiti-context.xml文件,对于所有的activiti.cfg.xml文件,内部都会调用Activiti底层的方法,ProcessEngineConfiguration.createProcessEngineConfigurationFromInputStream(inputStream).buildProcessEngine(),对于所有的activiti-context.xml,ProcessEngine将会被以Spring的方式创建,在Spring的上下文创建后,ProcessEngine将会被加进Spring的上下文中。
所有的Service是无状态的,这意味这你可以在具有多个节点的集群上面,每个相同的数据库上面进行调用这些Service,而不用关心是那一台机器调用的,任何服务的调用都是幂等的,无论它何处运行。
注:幂等:是一个数学与计算机学概念,常见于抽象代数中。 在编程中.一个幂等操作的特点是其任意多次执行所产生的影响均与一次执行的影响相同。
一般的,在Activiti的开发中都会先去获取RepositoryService,RepositoryService提供了管理和操作deployments和process definitions,这里就不用细说更多细节的东西了,一个流程定义的java对象其实就是BPMN 2.0文件的副本,流程定义对象也表现了每一步流程步骤的结构和行为。deployment是在工作流引擎里面打包的单位,也就是说它囊括了单个的bpmn文件到流程的文件夹和相关资源,在一个deployment中应该包含多少配置文件取决于开发者。RepositoryService允许发布文件夹,发布一个deployment意味着将会上传到引擎中,在存进数据库之前需要检查和解析,从那时起,deployment中所有的流程就可以启动了.
RepositoryService也提供了一些功能, 比如:
- 提供在流程引擎中流程定义和deployments的查询。
- 阻塞或者激活deployment中全部或者部分流程定义。阻塞的意思是指以后这些流程定义将不会执行,直到被激活为止。
- 获取各种资源文件,例如在deployment中的file,流程图等。
- 获取流程定义对象的版本信息。
RepositoryService保存了静态信息,而RuntimeService则相反, RuntimeService处理流程定义实例。综上所述,process definition对象是描述流程的结构和具体步骤的表现,而流程实例对象是这个流程定义对象的执行对象。同一时间每一个流程定义对象对应了多个流程实例在运行,RuntimeService同样可以获取存储process variables(流程变量),在流程实例中获取流程变量,在流程中作用于各种execution(比如排他网关通常使用流程变量来判断流程路线的走向),Runtimeservice也允许查询流程实例和执行实例,Executions是取用BPMN 2.0的概念,Execution(也就是执行实例)可以说一个指针指出当前的流程实例的位置。RuntimeService让流程实例的深入执行,一个流程实例有几种wait states,并且RunTimeService提供的不同的方式发信号(外部的触发器触发)给流程实例,流程实例向下执行。
Tasks(任务)在Activiti中需要被实际的人员去完成,关于所有的Task的事情都交给了TaskService处理,例如:
- 查询任务被分配的组或人员
- 额外创建任务,这些任务是和流程实例没有关系的。
- 任务的分配和相关人员的参与
- 领取任务和完成任务,领取任务就是说当前任务被人获得,并且该任务将由他来完成。完成任务就是执行任务工作,常见的就是填写表单。
IdentityService是很简单的,它就是对users和group的增删改查,重要提示:activiti在运行的时候并不会检测用户,比如现在一个任务可以分配给任何人做,但activiti并不会去检查这个人是否存在于系统里,要知道Activiti是被用来提供LDAP,Active Directory等服务的。
FormService是一个可选用的Service,意味着activiti没有它不会受到影响,不会因此少了功能。这个Service用来提供start form和task form的概念。start form指的是流程实例开始之前展示用户的表单,而task form在用户需要完成任务是展示的表单。Activiti允许用户将这些表单插入流程定义中,但是没必要内嵌进入activiti。
HistoryService提供所有关于工作流引擎的历史数据,在流程执行的时候,一大笔数据会被引擎保存起来,例如流程实例开始的时候,记录了谁在做任务,做了多久,流程实例的走向等等,HistoryService提供查询方法支持这些数据的获取。
ManagementService也是一个在工作流中可选的service,它允许从数据库表和元数据中获取数据,他也提供了对作业(job)的查询和管理,Job被用来处理这些事情:定时器,异步延迟等。
3.1 异常的处理策略
activiti里面最常用的是org.activiti.engine.ActivitiException,他是一个运行时异常,在整个工作流API中都可以抛出,但最好还是根据api在相应的地方使用对应提供的异常类。比如:在RuntimeService中的一个方法
/**
* Called when the task is successfully executed.
* @param taskId the id of the task to complete, cannot be null.
* @throws ActivitiObjectNotFoundException when no task exists with the given id.
*/
void complete(String taskId);
明确的说明的id不能为空,否则抛出ActivitiIllegalArgumentException.
尽管我们想避免抛出很宽泛的异常,但是在activiti的运行执行当中,仍然有超出我们预料的异常出现,不符合下面异常的都会抛出ActivitiException:
ActivitiWrongDbException:在工作流引擎发现数据库中工作流版本和引擎本身的版本不一致的时候抛出。
ActivitiOptimisticLockingException:在并发读写相同数据,乐观锁发生版本不一致抛出异常。
ActivitiClassLoadingException:类加载的时候没有找到或者加载它的时候发生错误会抛出异常。
ActivitiObjectNotFoundException:请求对象或者动作不存在的时候抛出。
ActivitiIllegalArgumentException:在调用含参API的时候,参数值非法。
ActivitiTaskAlreadyClaimedException:在任务已经被认领的时候。