Activiti工作流Day02-Activiti配置

2021-04-07  本文已影响0人  攻城狮Chova

创建ProcessEngine

ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine()

它会在classpath下搜索activiti.cfg.xml,并基于这个文件中的配置构建引擎

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans   http://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="jobExecutorActivate" value="false" />

    <property name="mailServerHost" value="mail.my-corp.com" />
    <property name="mailServerPort" value="5025" />
  </bean>

</beans>

配置文件中使用的ProcessEngineConfiguration可以通过编程方式创建,可以配置不同的bean id

ProcessEngineConfiguration.createProcessEngineConfigurationFromResourceDefault();
ProcessEngineConfiguration.createProcessEngineConfigurationFromResource(String resource);
ProcessEngineConfiguration.createProcessEngineConfigurationFromResource(String resource, String beanName);  // 配置不同的bean id
ProcessEngineConfiguration.createProcessEngineConfigurationFromInputStream(InputStream inputStream);
ProcessEngineConfiguration.createProcessEngineConfigurationFromInputStream(InputStream inputStream, String beanName);

如果不使用配置文件进行配置,就会基于默认创建配置

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

ProcessEngineConfiguration bean

 <bean id="processEngineConfiguration" class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration">

这个bean会用来构建ProcessEngine. 有多个类可以用来定义processEngineConfiguration. 这些类对应不同的环境,并设置了对应的默认值:

数据库配置

定义数据库配置参数

使用javax.sql.DataSource配置

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" >
  <property name="driverClassName" value="com.mysql.jdbc.Driver" />
  <property name="url" value="jdbc:mysql://localhost:3306/activiti" />
  <property name="username" value="activiti" />
  <property name="password" value="activiti" />
  <property name="defaultAutoCommit" value="false" />
</bean>

<bean id="processEngineConfiguration" class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration">

    <property name="dataSource" ref="dataSource" />
    ...
</bean>

JNDI数据库配置

JNDI的使用

<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
    <property name="jndiName" value="java:comp/env/jdbc/activitiDB"/>
</bean>
<?xml version="1.0" encoding="UTF-8"?>
<Context antiJARLocking="true" path="/activiti-explorer2">
    <Resource auth="Container"
              name="jdbc/activitiDB"
              type="javax.sql.DataSource"
              scope="Shareable"
              description="JDBC DataSource"
              url="jdbc:h2:mem:activiti;DB_CLOSE_DELAY=1000"
              driverClassName="org.h2.Driver"
              username="sa"
              password=""
              defaultAutoCommit="false"
              initialSize="5"
              maxWait="5000"
              maxActive="120"
              maxIdle="5"/>
</Context>
<?xml version="1.0" encoding="UTF-8"?>
<Context antiJARLocking="true" path="/activiti-rest2">
    <Resource auth="Container"
              name="jdbc/activitiDB"
              type="javax.sql.DataSource"
              scope="Shareable"
              description="JDBC DataSource"
              url="jdbc:h2:mem:activiti;DB_CLOSE_DELAY=-1"
              driverClassName="org.h2.Driver"
              username="sa"
              password=""
              defaultAutoCommit="false"
              initialSize="5"
              maxWait="5000"
              maxActive="120"
              maxIdle="5"/>
</Context>

JNDI的配置

<?xml version="1.0" encoding="UTF-8"?>
    <Context antiJARLocking="true" path="/activiti-explorer2">
        <Resource auth="Container"
            name="jdbc/activitiDB"
            type="javax.sql.DataSource"
            description="JDBC DataSource"
            url="jdbc:mysql://localhost:3306/activiti"
            driverClassName="com.mysql.jdbc.Driver"
            username="sa"
            password=""
            defaultAutoCommit="false"
            initialSize="5"
            maxWait="5000"
            maxActive="120"
            maxIdle="5"/>
    </Context>

Activiti支持的数据库

创建数据库表

SQL DDL语句可以从Activiti下载页或Activiti发布目录里找到,在database子目录下.
脚本也包含在引擎的jar中:activiti-engine-x.jar在org/activiti/db/create包下,drop目录里是删除语句

- SQL文件的命名方式如下:
[activiti.{db}.{create|drop}.{type}.sql]
type 是:
- engine:引擎执行的表,必须
- identity:包含用户,群组,用户与组之间的关系的表.这些表是可选的,只有使用引擎自带的默认身份管理时才需要
- history:包含历史和审计信息的表,可选的.历史级别设为none时不会使用. 注意这也会引用一些需要把数据保存到历史表中的功能

数据库表名理解

数据库升级

<beans ... >

  <bean id="processEngineConfiguration" class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration">
    <!-- ... -->
    <property name="databaseSchemaUpdate" value="true" />
    <!-- ... -->
  </bean>

</beans>

启用Job执行器

<property name="jobExecutorActivate" value="false" />

配置邮件服务器

配置历史存储

<property name="history" value="audit" />

表达式和脚本暴露配置

配置部署缓存

<property name="processDefinitionCacheLimit" value="10" />

这个配置会把默认的HashMap缓存替换成LRU缓存来提供限制. 这个配置的最佳值跟流程定义的总数有关,实际使用中会具体使用多少流程定义也有关

<property name="processDefinitionCache">
  <bean class="org.activiti.MyCache" />
</property>

日志

<dependency>
  <groupId>org.slf4j</groupId>
  <artifactId>slf4j-log4j12</artifactId>
</dependency>
<dependency>
  <groupId>org.slf4j</groupId>
  <artifactId>jcl-over-slf4j</artifactId>
</dependency>

映射诊断上下文

 log4j.appender.consoleAppender.layout.ConversionPattern =ProcessDefinitionId=%X{mdcProcessDefinitionID}
executionId=%X{mdcExecutionId}mdcProcessInstanceID=%X{mdcProcessInstanceID} mdcBusinessKey=%X{mdcBusinessKey} %m%n"

当系统进行高风险任务,日志必须严格检查时,这个功能就非常有用,要使用日志分析的情况

事件处理

事件监听器实现

public class MyEventListener implements ActivitiEventListener {

  @Override
  public void onEvent(ActivitiEvent event) {
    switch (event.getType()) {

      case JOB_EXECUTION_SUCCESS:
        System.out.println("A job well done!");
        break;

      case JOB_EXECUTION_FAILURE:
        System.out.println("A job has failed...");
        break;

      default:
        System.out.println("Event received: " + event.getType());
    }
  }

  @Override
  public boolean isFailOnException() {
    // The logic in the onEvent method of this listener is not critical, exceptions
    // can be ignored if logging fails...
    return false;
  }
}

isFailOnException(): 决定了当事件分发时onEvent(..) 方法抛出异常时的行为

事件监听器的配置安装

<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>

分发事件的顺序是由监听器添加时的顺序决定的

运行阶段添加监听器

/**
 * 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);

流程定义添加监听器

监听器执行自定义逻辑
<process id="testEventListeners">
  <extensionElements>
    <activiti:eventListener class="org.activiti.engine.test.MyEventListener" />
    <activiti:eventListener delegateExpression="${testEventListener}" events="JOB_EXECUTION_SUCCESS,JOB_EXECUTION_FAILURE" />
  </extensionElements>
    ...
</process>
<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>
监听抛出BPMN事件
<process id="testEventListeners">
  <extensionElements>
    <activiti:eventListener throwEvent="signal" signalName="My signal" events="TASK_ASSIGNED" />
  </extensionElements>
</process>
<process id="testEventListeners">
  <extensionElements>
    <activiti:eventListener throwEvent="globalSignal" signalName="My signal" events="TASK_ASSIGNED" />
  </extensionElements>
</process>
<process id="testEventListeners">
  <extensionElements>
    <activiti:eventListener throwEvent="message" messageName="My message" events="TASK_ASSIGNED" />
  </extensionElements>
</process>
<process id="testEventListeners">
  <extensionElements>
    <activiti:eventListener throwEvent="error" errorCode="123" events="TASK_ASSIGNED" />
  </extensionElements>
</process>
流程定义监听器注意点

通过API分发事件

/**
 * 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);

支持的事件类型

事件名称 事件描述 事件类型
ENGINE_CREATED 监听器监听的流程引擎已经创建,准备好接受API调用 ActivitiEvent
ENGINE_CLOSED 监听器监听的流程引擎已经关闭,不再接受API调用 ActivitiEvent
ENTITY_CREATED 创建了一个新实体,实体包含在事件中 ActivitiEntityEvent
ENTITY_INITIALIZED 创建了一个新实体,初始化也完成了.如果这个实体的创建会包含子实体的创建,这个事件会在子实体都创建/初始化完成后被触发,这是与ENTITY_CREATED的区别 ActivitiEntityEvent
ENTITY_UPDATED 更新了已存在的实体,实体包含在事件中 ActivitiEntityEvent
ENTITY_DELETED 删除了已存在的实体,实体包含在事件中 ActivitiEntityEvent
ENTITY_SUSPENDED 暂停了已存在的实体,实体包含在事件中.会被ProcessDefinitions,ProcessInstances和Tasks抛出 ActivitiEntityEvent
ENTITY_ACTIVATED 激活了已存在的实体,实体包含在事件中.会被ProcessDefinitions,ProcessInstances和Tasks抛出 ActivitiEntityEvent
JOB_EXECUTION_SUCCESS 作业执行成功,job包含在事件中 ActivitiEntityEvent
JOB_EXECUTION_FAILURE 作业执行失败,作业和异常信息包含在事件中 ActivitiEntityEvent<br />ActivitiExceptionEvent
JOB_RETRIES_DECREMENTED 因为作业执行失败,导致重试次数减少.作业包含在事件中 ActivitiEntityEvent
TIMER_FIRED 触发了定时器,job包含在事件中 ActivitiEntityEvent
JOB_CANCELED 取消了一个作业.事件包含取消的作业.作业可以通过API调用取消,任务完成后对应的边界定时器也会取消,在新流程定义发布时也会取消 ActivitiEntityEvent
ACTIVITY_STARTED 一个节点开始执行 ActivitiActivityEvent
ACTIVITY_COMPLETED 一个节点成功结束 ActivitiActivityEvent
ACTIVITY_SIGNALED 一个节点收到了一个信号 ActivitiSignalEvent
ACTIVITY_MESSAGE_RECEIVED 一个节点收到了一个消息.在节点收到消息之前触发,收到后,会触发ACTIVITY_SIGNALACTIVITY_STARTED, 这会根据节点的类型:边界事件,事件子流程开始事件 ActivitiMessageEvent
ACTIVITY_ERROR_RECEIVED 一个节点收到了一个错误事件.在节点实际处理错误之前触发, 事件的activityId对应着处理错误的节点.这个事件后续会是ACTIVITY_SIGNALLEDACTIVITY_COMPLETE, 如果错误发送成功的话 ActivitiErrorEvent
UNCAUGHT_BPMN_ERROR 抛出了未捕获的BPMN错误.流程没有提供针对这个错误的处理器.事件的activityId为空 ActivitiErrorEvent
ACTIVITY_COMPENSATE 一个节点将要被补偿.事件包含了将要执行补偿的节点id ActivitiActivityEvent
VARIABLE_CREATED 创建了一个变量.事件包含变量名,变量值和对应的分支或任务(如果存在) ActivitiVariableEvent
VARIABLE_UPDATED 更新了一个变量.事件包含变量名,变量值和对应的分支或任务(如果存在) ActivitiVariableEvent
VARIABLE_DELETED 删除了一个变量.事件包含变量名,变量值和对应的分支或任务(如果存在) ActivitiVariableEvent
TASK_ASSIGNED 任务被分配给了一个人员.事件包含任务 ActivitiEntityEvent
TASK_CREATED 创建了新任务.它位于ENTITY_CREATE事件之后.当任务是由流程创建时,这个事件会在TaskListener执行之前被执行 ActivitiEntityEvent
TASK_COMPLETED 任务完成.它会在ENTITY_DELETE事件之前触发.当任务是流程一部分时,事件会在流程继续运行之前, 后续事件将是ACTIVITY_COMPLETE,对应着完成任务的节点 ActivitiEntityEvent
TASK_TIMEOUT 任务已超时.在TIMER_FIRED事件之后,会触发用户任务的超时事件,当这个任务分配了一个定时器的时候 ActivitiEntityEvent
PROCESS_COMPLETED 流程已结束.在最后一个节点的ACTIVITY_COMPLETED事件之后触发.当流程到达的状态,没有任何后续连线时,流程就会结束 ActivitiEntityEvent
MEMBERSHIP_CREATED 用户被添加到一个组里.事件包含了用户和组的id ActivitiMembershipEvent
MEMBERSHIP_DELETED 用户被从一个组中删除.事件包含了用户和组的id ActivitiMembershipEvent
MEMBERSHIPS_DELETED 所有成员被从一个组中删除.在成员删除之前触发这个事件,所以他们都是可以访问的.因为性能方面的考虑,不会为每个成员触发单独的MEMBERSHIP_DELETED事件 ActivitiMembershipEvent

注意

上一篇下一篇

猜你喜欢

热点阅读