Activiti 工作流编程

本文主要摘自activiti的官方文档。每次都去搜索官方文档比较费劲,所以将文档和实践结合,抽取核心内容,方便以后开发使用。

activiti的配置

activiti提供了方便的配置方式。

1 在不使用Spring的时候,可以通过activiti.cfg.xml文件配置。
在代码中调用ProcessEngine启动activiti。

ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine()

processEngine会自动在classpath下查找activiti.cfg.xml文件,并通过文件的内容初始化ProcessEngine。文件配置实例如下:

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd">
  <bean id="processEngineConfiguration" class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration">
    <property name="jdbcUrl" value="jdbc:h2:mem:activiti;DB_CLOSE_DELAY=1000" />
    <property name="jdbcDriver" value="org.h2.Driver" />
    <property name="jdbcUsername" value="sa" />
    <property name="jdbcPassword" value="" />
    <property name="databaseSchemaUpdate" value="true" />
    <property name="asyncExecutorActivate" value="false" />
    <property name="mailServerHost" value="mail.my-corp.com" />
    <property name="mailServerPort" value="5025" />
  </bean>
</beans>

2 可以直接通过代码初始化

ProcessEngine processEngine = ProcessEngineConfiguration
    .createStandaloneInMemProcessEngineConfiguration() 
    .setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_FALSE) 
    .setJdbcUrl("jdbc:h2:mem:my-own-db;DB_CLOSE_DELAY=1000") 
    .setAsyncExecutorActivate(false) 
    .buildProcessEngine();

3 通过spring的方式创建

<bean id="processEngineConfiguration" class="org.activiti.spring.SpringProcessEngineConfiguration">
    ...
</bean>

<bean id="processEngine" class="org.activiti.spring.ProcessEngineFactoryBean">
  <property name="processEngineConfiguration" ref="processEngineConfiguration" />
</bean>

spring activiti会在不设置事务管理器的时候,会自动将数据源包裹默认的事务管理器:org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy。
如果在初始化SpringProcessEngineConfiguration的时候传入了事务管理器,则activiti不会再做额外的工作。
配置实例如下:

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx-3.0.xsd">

  <bean id="dataSource" class="org.springframework.jdbc.datasource.SimpleDriverDataSource">
    <property name="driverClass" value="org.h2.Driver" />
    <property name="url" value="jdbc:h2:mem:activiti;DB_CLOSE_DELAY=1000" />
    <property name="username" value="sa" />
    <property name="password" value="" />
  </bean>

  <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource" />
  </bean>

  <bean id="processEngineConfiguration" class="org.activiti.spring.SpringProcessEngineConfiguration">
    <property name="dataSource" ref="dataSource" />
    <property name="transactionManager" ref="transactionManager" />
    <property name="databaseSchemaUpdate" value="true" />
    <property name="asyncExecutorActivate" value="false" />
  </bean>

  <bean id="processEngine" class="org.activiti.spring.ProcessEngineFactoryBean">
    <property name="processEngineConfiguration" ref="processEngineConfiguration" />
  </bean>

  <bean id="repositoryService" factory-bean="processEngine" factory-method="getRepositoryService" />
  <bean id="runtimeService" factory-bean="processEngine" factory-method="getRuntimeService" />
  <bean id="taskService" factory-bean="processEngine" factory-method="getTaskService" />
  <bean id="historyService" factory-bean="processEngine" factory-method="getHistoryService" />
  <bean id="managementService" factory-bean="processEngine" factory-method="getManagementService" />

...

activiti的数据库配置

activiti提供了四种processEngineConfiguration:

配置类描述,使用场景
org.activiti.engine.impl.cfg.StandaloneProcessEngineConfigurationstandalone模式。Activiti接管所有的事物。默认情况下,只有在engine启动的时候才会检查数据库。
org.activiti.engine.impl.cfg.StandaloneInMemProcessEngineConfiguration为单元测试提供了便捷的实现。Activiti会接管事物。默认使用H2数据库。在engine的启动和停止时创建和删除数据库。在使用的时候不需要额外的配置。
org.activiti.spring.SpringProcessEngineConfiguration在Spring的环境中使用。
org.activiti.engine.impl.cfg.JtaProcessEngineConfigurationengine在standalone的模式下使用。但是采用了JTA的事务管理。

activiti支持的数据库:

h2jdbc:h2:tcp://localhost/activitiDefault configured database
mysqljdbc:mysql://localhost:3306/activiti?autoReconnect=trueTested using mysql-connector-java database driver
oraclejdbc:oracle:thin:@localhost:1521:xe
postgresjdbc:postgresql://localhost:5432/activiti
db2jdbc:db2://localhost:50000/activiti
mssqljdbc:sqlserver://localhost:1433;databaseName=activiti(jdbc.driver=com.microsoft.sqlserver.jdbc.SQLServerDriver) OR jdbc:jtds:sqlserver://localhost:1433/activiti (jdbc.driver=net.sourceforge.jtds.jdbc.Driver)Tested using Microsoft JDBC Driver 4.0 (sqljdbc4.jar) and JTDS Driver

activiti数据库表名说明:

ACT_RE_*RE代表repository。存储静态信息,例如process定义,process资源等
ACT_RU_*RU代表runtime。运行时的信息表,包含process实例的运行时数据,用户task,变量,job等。activiti在process实例运行的时候,在runtime表有记录。当运行结束,将会从runtime表中删除。
ACT_ID_*ID代表identity。包含认证信息,如user,group
ACT_HI_*HI代表history。包含历史数据,比如以前的process实例,变量,task等。
ACT_GE_*general数据,用处多样化。

event处理器

所有的event类型:

Event nameDescriptionEvent classes
ENGINE_CREATEDThe process-engine this listener is attached to, has been created and is ready for API-calls.engine被创建成功,且为API调用准备就绪的时候触发。
ENGINE_CLOSEDThe process-engine this listener is attached to, has been closed. API-calls to the engine are no longer possible.org.activiti…ActivitiEvent
ENTITY_CREATEDA new entity is created. The new entity is contained in the event.org.activiti…ActivitiEntityEvent
ENTITY_INITIALIZEDA 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_CREATE event.org.activiti…ActivitiEntityEvent
ENTITY_UPDATEDAn existing is updated. The updated entity is contained in the event.org.activiti…ActivitiEntityEvent
ENTITY_DELETEDAn existing entity is deleted. The deleted entity is contained in the event.org.activiti…ActivitiEntityEvent
ENTITY_SUSPENDEDAn existing entity is suspended. The suspended entity is contained in the event. Will be dispatched for ProcessDefinitions, ProcessInstances and Tasks.org.activiti…ActivitiEntityEvent
ENTITY_ACTIVATEDAn existing entity is activated. The activated entity is contained in the event. Will be dispatched for ProcessDefinitions, ProcessInstances and Tasks.org.activiti…ActivitiEntityEvent
JOB_EXECUTION_SUCCESSA job has been executed successfully. The event contains the job that was executed.org.activiti…ActivitiEntityEvent
JOB_EXECUTION_FAILUREThe execution of a job has failed. The event contains the job that was executed and the exception.org.activiti…ActivitiEntityEventand org.activiti…ActivitiExceptionEvent
JOB_RETRIES_DECREMENTEDThe number of job retries have been decremented due to a failed job. The event contains the job that was updated.org.activiti…ActivitiEntityEvent
TIMER_FIREDA timer has been fired. The event contains the job that was executed?org.activiti…ActivitiEntityEvent
JOB_CANCELEDA 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.org.activiti…ActivitiEntityEvent
ACTIVITY_STARTEDAn activity is starting to executeorg.activiti…ActivitiActivityEvent
ACTIVITY_COMPLETEDAn activity is completed successfullyorg.activiti…ActivitiActivityEvent
ACTIVITY_CANCELLEDAn activity is going to be cancelled. There can be three reasons for activity cancellation (MessageEventSubscriptionEntity, SignalEventSubscriptionEntity, TimerEntity).org.activiti…ActivitiActivityCancelledEvent
ACTIVITY_SIGNALEDAn activity received a signalorg.activiti…ActivitiSignalEvent
ACTIVITY_MESSAGE_RECEIVEDAn activity received a message. Dispatched before the activity receives the message. When received, a ACTIVITY_SIGNAL or ACTIVITY_STARTED will be dispatched for this activity, depending on the type (boundary-event or event-subprocess start-event)org.activiti…ActivitiMessageEvent
ACTIVITY_ERROR_RECEIVEDAn activity has received an error event. Dispatched before the actual error has been handled by the activity. The event’s activityId contains a reference to the error-handling activity. This event will be either followed by a ACTIVITY_SIGNALLEDevent or ACTIVITY_COMPLETE for the involved activity, if the error was delivered successfully.org.activiti…ActivitiErrorEvent
UNCAUGHT_BPMN_ERRORAn uncaught BPMN error has been thrown. The process did not have any handlers for that specific error. The event’s activityIdwill be empty.org.activiti…ActivitiErrorEvent
ACTIVITY_COMPENSATEAn activity is about to be compensated. The event contains the id of the activity that is will be executed for compensation.org.activiti…ActivitiActivityEvent
VARIABLE_CREATEDA variable has been created. The event contains the variable name, value and related execution and task (if any).org.activiti…ActivitiVariableEvent
VARIABLE_UPDATEDAn existing variable has been updated. The event contains the variable name, updated value and related execution and task (if any).org.activiti…ActivitiVariableEvent
VARIABLE_DELETEDAn existing variable has been deleted. The event contains the variable name, last known value and related execution and task (if any).org.activiti…ActivitiVariableEvent
TASK_ASSIGNEDA task has been assigned to a user. The event contains the taskorg.activiti…ActivitiEntityEvent
TASK_CREATEDA task has been created. This is dispatched after the ENTITY_CREATE event. In case the task is part of a process, this event will be fired before the task listeners are executed.org.activiti…ActivitiEntityEvent
TASK_COMPLETEDA task has been completed. This is dispatched before the ENTITY_DELETEevent. In case the task is part of a process, this event will be fired before the process has moved on and will be followed by a ACTIVITY_COMPLETE event, targeting the activity that represents the completed task.org.activiti…ActivitiEntityEvent
PROCESS_COMPLETEDA process has been completed. Dispatched after the last activity ACTIVITY_COMPLETEDevent. Process is completed when it reaches state in which process instance does not have any transition to take.org.activiti…ActivitiEntityEvent
PROCESS_CANCELLEDA process has been cancelled. Dispatched before the process instance is deleted from runtime. Process instance is cancelled by API call RuntimeService.deleteProcessInstanceorg.activiti…ActivitiCancelledEvent
MEMBERSHIP_CREATEDA user has been added to a group. The event contains the ids of the user and group involved.org.activiti…ActivitiMembershipEvent
MEMBERSHIP_DELETEDA user has been removed from a group. The event contains the ids of the user and group involved.org.activiti…ActivitiMembershipEvent
MEMBERSHIPS_DELETEDAll members will be removed from a group. The event is thrown before the members are removed, so they are still accessible. No individual MEMBERSHIP_DELETED events will be thrown if all members are deleted at once, for performance reasons.org.activiti…ActivitiMembershipEvent

event处理器的注册时机:可以在配置文件中定义engine级别的消息监听器,也可以在运行期使用API注册engine级别的消息监听器,也可以在process配置文件中定义process的消息监听器。
event listener配置:
1 engine的event listener
监听所有的消息类型:

<bean id="processEngineConfiguration" class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration">
    ...
    <property name="eventListeners">
      <list>
         <bean class="org.activiti.engine.example.MyEventListener" />
      </list>
    </property>
</bean>

监听指定的消息类型:

<bean id="processEngineConfiguration" class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration">
    ...
    <property name="typedEventListeners">
      <map>
        <entry key="JOB_EXECUTION_SUCCESS,JOB_EXECUTION_FAILURE" >
          <list>
            <bean class="org.activiti.engine.example.MyJobEventListener" />
          </list>
        </entry>
      </map>
    </property>
</bean>

运行期添加event listener:
使用RuntimeService的API添加。

/**
* Adds an event-listener which will be notified of ALL events by the dispatcher.
* @param listenerToAdd the listener to add
*/
void addEventListener(ActivitiEventListener listenerToAdd);

/**
* Adds an event-listener which will only be notified when an event occurs, which type is in the given types.
* @param listenerToAdd the listener to add
* @param types types of events the listener should be notified for
*/
void addEventListener(ActivitiEventListener listenerToAdd, ActivitiEventType... types);

/**
* Removes the given listener from this dispatcher. The listener will no longer be notified,
* regardless of the type(s) it was registered for in the first place.
* @param listenerToRemove listener to remove
*/
void removeEventListener(ActivitiEventListener listenerToRemove);

2 process定义的event listener
process定义中可以注册event listener。这些listener将会在相关的process以及相关process的实例产生消息时被调用。listener可以通过类的全名配置,也可以通过表达式指向实现listener接口的bean,也可以配置成抛出message/signal/error等类型的event的listener。
在配置时,可以定义类的全名,产生event的实体类型,event 类型等信息。

<process id="testEventListeners">
  <extensionElements>
    <activiti:eventListener class="org.activiti.engine.test.MyEventListener" entityType="task" />
    <activiti:eventListener delegateExpression="${testEventListener}" events="ENTITY_CREATED" entityType="task" />
  </extensionElements>

  ...

</process>

支持的实体类型(entityType):attachment, comment, execution, identity-link, job, process-instance, process-definition, task
配置抛出event的listener

<process id="testEventListeners">
  <extensionElements>
    <activiti:eventListener throwEvent="signal" signalName="My signal" events="TASK_ASSIGNED" />
  </extensionElements>
</process>

3 dispatch event
activiti将event-dispatch的机制暴露出来,用户可以自定义event分发机制。但是推荐只自定义CUSTOM类型的event。
可以使用RuntimeService的接口实现event的自定义分发:

/**
* Dispatches the given event to any listeners that are registered.
* @param event event to dispatch.
*
* @throws ActivitiException if an exception occurs when dispatching the event or when the {@link ActivitiEventDispatcher}
* is disabled.
* @throws ActivitiIllegalArgumentException when the given event is not suitable for dispatching.
*/
void dispatchEvent(ActivitiEvent event);

Activiti API

ProcessEngine是Activiti的开始点。任何操作接口都可以从ProcessEngine获得,如下图。ProcessEngine,以及暴露的*Service都是线程安全的。下面是摘自官网的结构图。
在这里插入图片描述

RuntimeService runtimeService = processEngine.getRuntimeService();process运行时实例的API
RepositoryService repositoryService = processEngine.getRepositoryService();管理部署,静态process操作的API:查询部署情况,查询process。挂起或激活指定的process或者所有process。获取process产生的各种资源,比如文件。获取process定义的java对象版本,而不是xml版本。
TaskService taskService = processEngine.getTaskService();运行时task的API:查询分配给user或group的任务。创建独立于process实例的task。task分配规则。声明,完成task。
ManagementService managementService = processEngine.getManagementService();用户自己的应用中用不到。可以获取数据库表以及表的元数据信息。可以获取Job的信息。
IdentityService identityService = processEngine.getIdentityService();user,group的增删改查。运行期,activiti并不检查task的user,group的合法性。
HistoryService historyService = processEngine.getHistoryService();历史记录API。当process实例执行的时候,许多数据被记录下来,例如process实例的开始时间,task的执行人,task的耗时,process实例的执行路径。
FormService formService = processEngine.getFormService();可选service。activiti完全可以在没有formservice的情况下运行。DynamicBpmnService dynamicBpmnService = processEngine.getDynamicBpmnService();动态修改process定义的信息,而不需要重新部署。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值