创立ProcessEngine

  • Activiti流程引擎的配置文件是名为activiti.cfg.xml的XML文件.留神与应用Spring形式创立流程引擎是不一样的
  • 应用org.activiti.engine.ProcessEngines类,取得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 idProcessEngineConfiguration.createProcessEngineConfigurationFromInputStream(InputStream inputStream);ProcessEngineConfiguration.createProcessEngineConfigurationFromInputStream(InputStream inputStream, String beanName);

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

  • ProcessEngineConfiguration.createXXX() 办法都会返回ProcessEngineConfiguration,后续能够调整成所需的对象. 在调用buildProcessEngine()后, 就会创立一个ProcessEngine:

    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

  • activiti.cfg.xml必须蕴含一个id='processEngineConfiguration' 的bean

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

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

    • org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration: 独自运行的流程引擎.Activiti会本人处理事务.默认数据库只在引擎启动时检测(如果没有Activiti的表或者表构造不正确就会抛出异样)
    • org.activiti.engine.impl.cfg.StandaloneInMemProcessEngineConfiguration: 单元测试时的辅助类.Activiti会本人管制事务. 默认应用H2内存数据库,数据库表会在引擎启动时创立,敞开时删除.应用它时,不须要其余配置(除非应用job执行器或邮件性能)
    • org.activiti.spring.SpringProcessEngineConfiguration: 在Spring环境下应用流程引擎
    • org.activiti.engine.impl.cfg.JtaProcessEngineConfiguration: 独自运行流程引擎,并应用JTA事务

      数据库配置

      定义数据库配置参数

  • 基于数据库配置参数定义数据库连贯配置

    • jdbcUrl: 数据库的JDBC URL
    • jdbcDriver: 对应不同数据库类型的驱动
    • jdbcUsername: 连贯数据库的用户名
    • jdbcPassword: 连贯数据库的明码
  • 基于JDBC参数配置的数据库连贯 会应用默认的MyBatis连接池,配置MyBatis连接池:

    • jdbcMaxActiveConnections: 连接池中处于被应用状态的连贯的最大值.默认为10
    • jdbcMaxIdleConnections: 连接池中处于闲暇状态的连贯的最大值
    • jdbcMaxCheckoutTime: 连贯被取出应用的最长工夫,超过工夫会被强制回收. 默认为20000(20秒)
    • jdbcMaxWaitTime: 这是一个底层配置,让连接池能够在长时间无奈取得连贯时, 打印一条日志,并从新尝试获取一个连贯.(防止因为谬误配置导致缄默的操作失败) 默认为20000(20秒)

      应用javax.sql.DataSource配置

  • Activiti的公布包中没有这些类, 要把对应的类放到classpath下

    <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>
  • 无论应用JDBC还是DataSource,都能够设置上面的配置:

    • databaseType:

      • 个别不必设置,因为能够主动通过数据库连贯的元数据获取
      • 只有自动检测失败时才须要设置.可能的值有:{h2,mysql,oracle,postgres,mssql,db2}
      • 如果没应用默认的H2数据库就必须设置这项.这个配置会决定应用哪些创立/删除脚本和查问语句
    • databaseSchemaUpdate: 设置流程引擎启动和敞开时如何解决数据库表

      • false:默认, 查看数据库表的版本和依赖库的版本,如果版本不匹配就抛出异样
      • true: 构建流程引擎时,执行查看,如果须要就执行更新. 如果表不存在,就创立
      • create-drop: 构建流程引擎时创立数据库表,敞开流程引擎时删除这些表

        JNDI数据库配置

  • 在默认状况下,Activiti的数据库配置会放在web利用的WEB-INF/classes目录下的db.properties文件中. 这样做比拟繁琐,因为要用户在每次公布时,都批改Activiti源码中的db.properties并从新编译war文件,或者解压缩war文件,批改其中的db.properties
  • 应用 JNDI(Java命名和目录接口) 来获取数据库连贯,连贯是由servlet容器治理的,能够在war部署外边治理配置. 与db.properties相比,它也容许对连贯进行更多的配置

    JNDI的应用

  • Activiti Explorer和Activiti Rest利用从db.properties转换为应用JNDI数据库配置:

    • 须要关上原始的Spring配置文件:

      • activiti-webapp-explorer/src/main/webapp/WEB-INF/activiti-standalone-context.xml
      • activiti-webapp-rest2/src/main/resources/activiti-context.xml
    • 删除dbPropertiesdataSource两个bean,而后增加如下bean:

      <bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean"><property name="jndiName" value="java:comp/env/jdbc/activitiDB"/></bean>
  • 咱们须要增加蕴含了默认的H2配置的context.xml文件
  • 如果曾经有了JNDI配置,会笼罩这些配置.对应的配置文件activiti-webapp-explorer2/src/main/webapp/META-INF/context.xml:

    <?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>
  • 如果是Activiti REST利用,则增加activiti-webapp-rest2/src/main/webapp/META-INF/context.xml:

    <?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>
  • 最初删除Activiti Explorer和Activiti Rest两个利用中不再应用的db.properties文件

    JNDI的配置

  • JNDI数据库配置会因为应用的Servlet container不同而不同
  • Tomcat容器中的JNDI配置如下:

    • JNDI资源配置在CATALINA_BASE/conf/[enginename]/[hostname]/[warname].xml(对于Activiti Explorer来说,通常是在CATALINA_BASE/conf/Catalina/localhost/activiti-explorer.war) 当利用第一次公布时,会把这个文件从war中复制进去.所以如果这个文件曾经存在了,须要替换它.批改JNDI资源让利用连贯mysql而不是H2:

      <?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反对的数据库

  • h2: 默认配置的数据库
  • mysql
  • oracle
  • postgres
  • db2
  • mssql

    创立数据库表

  • 创立数据库表的办法:

    • activiti-engine的jar放到classpath下
    • 增加对应的数据库驱动
    • 把Activiti配置文件(activiti.cfg.xml)放到classpath下,指向你的数据库
    • 执行DbSchemaCreate类的main办法
    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时不会应用. 留神这也会援用一些须要把数据保留到历史表中的性能

  • Activiti的表都以ACT_结尾, 第二局部是示意表的用处的两个字母标识.用处和服务的API对应

    • ACT_RE_*: RE示意repository. 这个前缀的表蕴含了流程定义和流程动态资源
    • ACT_RU_*: RU示意runtime. 这些是运行时的表,蕴含流程实例,工作,变量,异步工作等运行中的数据. Activiti只在流程实例执行过程中保留这些数据, 在流程完结时就会删除这些记录.这样运行时表能够始终很小速度很快
    • ACT_ID_*: ID 示意identity. 这些表蕴含身份信息. 比方用户,组等等
    • ACT_HI_*: HI 示意history. 这些表蕴含历史数据. 比方历史流程实例, 变量,工作等等
    • ACT_GE_*: 通用数据. 用于不同场景下

      数据库降级

  • 在执行更新之前要先应用数据库的备份性能备份数据库
  • 默认状况下,每次构建流程引擎时都会进行版本检测.这一切都在利用启动或Activiti webapp启动时产生.如果Activiti发现数据库表的版本与依赖库的版本不同,就会抛出异样
  • 对activiti.cfg.xml配置文件进行配置来降级:

    <beans ... ><bean id="processEngineConfiguration" class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration">  <!-- ... -->  <property name="databaseSchemaUpdate" value="true" />  <!-- ... --></bean></beans>
  • 而后,把对应的数据库驱动放到classpath里.降级利用的Activiti依赖,启动一个新版本的Activiti指向蕴含旧版本的数据库,将databaseSchemaUpdate设置为true,Activiti会主动将数据库表降级到新版本
  • 当发现依赖和数据库表版本不通过时,也能够执行更新降级DDL语句
  • 也能够执行数据库脚本,能够在Activiti下载页找到

    启用Job执行器

  • JobExecutor是治理一系列线程的组件,能够触发定时器(蕴含后续的异步音讯).
  • 在单元测试场景下,很难应用多线程.因而API容许查问Job(ManagementService.createJobQuery)执行Job (ManagementService.executeJob),
  • 因而Job能够在单元测试中管制, 要防止与job执行器抵触,能够敞开它
  • 默认,JobExecutor在流程引擎启动时就会激活. 如果不想在流程引擎启动后主动激活JobExecutor,能够设置

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

    配置邮件服务器

  • Activiti反对在业务流程中发送邮件,能够在配置中配置邮件服务器
  • 配置SMTP邮件服务器来发送邮件

    配置历史存储

  • Activiti能够配置来定制历史存储信息

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

    表达式和脚本裸露配置

  • 默认状况下,activiti.cfg.xml和Spring配置文件中所有bean 都能够在表达式和脚本中应用
  • 如果要限度配置文件中的bean的可见性,能够通过配置流程引擎配置的beans来配置
  • ProcessEngineConfiguration的beans是一个map.当指定了这个参数,只有蕴含这个map中的bean能够在表达式和脚本中应用.通过在map中指定的名称来决定裸露的bean

    配置部署缓存

  • 因为流程定义的数据是不会扭转的,为了防止每次应用拜访数据库,所有流程定义在解析之后都会被缓存
  • 默认状况下,不会限度这个缓存.如果想限度流程定义缓存,能够增加如下配置

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

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

  • 也能够注入自定义的缓存实现,这个bean必须实现org.activiti.engine.impl.persistence.deploy.DeploymentCache接口

    <property name="processDefinitionCache"><bean class="org.activiti.MyCache" /></property>
  • 相似的配置有knowledgeBaseCacheLimitknowledgeBaseCache, 它们是配置规定缓存的.只有流程中应用规定工作时才用

    日志

  • 从Activiti 5.12开始,所有日志(activiti,spring,,mybatis等等)都转发给slf4j容许自定义日志实现
  • 引入Maven依赖log4j实现,须要增加版本

    <dependency><groupId>org.slf4j</groupId><artifactId>slf4j-log4j12</artifactId></dependency>
  • 应用Maven的实例,疏忽版本

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

    映射诊断上下文

  • Activiti反对slf4j的MDC性能, 如下的根底信息会传递到日志中记录:

    • 流程定义ID: mdcProcessDefinitionID
    • 流程实例ID: mdcProcessInstanceID
    • 分支ID: mdcexecutionId
  • 默认不会记录这些信息,能够配置日志应用冀望的格局来显示它们,扩大通常的日志信息. 比方,通过log4j配置定义会让日志显示下面的信息:

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

    当零碎进行高风险工作,日志必须严格查看时,这个性能就十分有用,要应用日志剖析的状况

    事件处理

  • Activiti中实现了一种事件机制,它容许在引擎触发事件时取得揭示
  • 为对应的事件类型注册监听器,在这个类型的任何工夫触发时都会收到揭示:

    • 能够增加引擎范畴的事件监听器,能够通过配置增加引擎范畴的事件监听器在运行阶段应用API
    • 增加event-listener到特定流程定义的BPMN XML中
  • 所有散发的事件,都是org.activiti.engine.delegate.event.ActivitiEvent的子类.事件蕴含type,executionId,processInstanceId和processDefinitionId. 对应的事件会蕴含事件产生时对应上下文的额定信息

    事件监听器实现

  • 实现事件监听器要实现org.activiti.engine.delegate.event.ActivitiEventListener.
  • 上面监听器的实现会把所有监听到的事件打印到规范输入中,包含job执行的事件异样:

    public class MyEventListener implements ActivitiEventListener {@Overridepublic 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());  }}@Overridepublic 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(..) 办法抛出异样时的行为

    • 返回false,会疏忽异样
    • 返回true,异样不会疏忽,持续向上流传,迅速导致以后命令失败
    • 当事件是一个API调用的一部分时(或其余事务性操作,比方job执行), 事务就会回滚
    • 当事件监听器中的行为不是业务性时,倡议返回false
  • activiti提供了一些根底的实现,实现了事件监听器的罕用场景能够用来作为基类或监听器实现的样例

    • org.activiti.engine.delegate.event.BaseEntityEventListener:

      • 这个事件监听器的基类能够用来监听实体相干的事件,能够针对某一类型实体,也能够是全副实体
      • 暗藏了类型检测,并提供了三个须要重写的办法:

        • onCreate(..)
        • onUpdate(..)
        • onDelete(..)
        • 当实体创立,更新,或删除时调用
      • 对于其余实体相干的事件,会调用onEntityEvent(..)

        事件监听器的配置装置

  • 把事件监听器配置到流程引擎配置中,会在流程引擎启动时激活,并在引擎启动过程中继续工作
  • eventListeners属性须要org.activiti.engine.delegate.event.ActivitiEventListener的队列

    • 通常,咱们能够申明一个外部的bean定义,或应用ref援用已定义的bean.上面的代码,向配置增加了一个事件监听器,任何事件触发时都会揭示它,无论事件是什么类型:

      <bean id="processEngineConfiguration" class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration">...<property name="eventListeners">  <list>     <bean class="org.activiti.engine.example.MyEventListener" />  </list></property></bean>
  • 为了监听特定类型的事件

    • 能够应用typedEventListeners属性
    • 它须要一个map参数
    • map的key是逗号分隔的事件名或独自的事件名
    • map的value是org.activiti.engine.delegate.event.ActivitiEventListener队列
  • 上面的代码演示了向配置中增加一个事件监听器,能够监听job执行胜利或失败:

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

    散发事件的程序是由监听器增加时的程序决定的

    • 首先,会调用所有一般的事件监听器(eventListeners属性),依照它们在list中的秩序
    • 而后,会调用所有对应类型的监听器(typedEventListeners属性),对应类型的事件被触发

      运行阶段增加监听器

  • 通过API:RuntimeService, 在运行阶段增加或删除额定的事件监听器:

    /** * 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);
  • 运行阶段增加的监听器引擎重启后就隐没

    流程定义增加监听器

  • 特定流程定义增加监听器:

    • 监听器只会监听与这个流程定义相干的事件以及这个流程定义上发动的所有流程实例的事件
  • 监听器实现:

    • 能够应用全类名定义
    • 援用实现了监听器接口的表达式
    • 配置为抛出一个message,signal,errorBPMN事件

      监听器执行自定义逻辑
  • 上面代码为一个流程定义增加了两个监听器:

    • 第一个监听器会接管所有类型的事件,它是通过全类名定义的
    • 第二个监听器只接管作业胜利或失败的事件,它应用了定义在流程引擎配置中的beans属性中的一个bean

      <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>
  • entityType反对的值有:

    • attachment
    • comment
    • execution
    • identity-link
    • job
    • process-instance
    • process-definition
    • task

      监听抛出BPMN事件
  • 另一种处理事件的办法是抛出一个BPMN事件:

    • 只针对与抛出一个activiti事件类型的BPMN事件, 抛出一个BPMN事件,在流程实例删除时,会导致一个谬误
  • 上面的代码演示了如何在流程实例中抛出一个signal,把signal抛出到内部流程(全局),在流程实例中抛出一个音讯事件,在流程实例中抛出一个谬误事件.除了应用classdelegateExpression, 还应用了throwEvent属性,通过额定属性,指定了抛出事件的类型

    <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>
  • 如果须要申明额定的逻辑,是否抛出BPMN事件,能够扩大activiti提供的监听器类:

    • 在子类中重写isValidEvent(ActivitiEvent event), 能够避免抛出BPMN事件.对应的类是:

      • org.activiti.engine.impl.bpmn.helper.MessageThrowingEventListener
      • org.activiti.engine.test.api.event.SignalThrowingEventListenerTest
      • org.activiti.engine.impl.bpmn.helper.ErrorThrowingEventListener

        流程定义监听器留神点
  • 事件监听器只能申明在process元素中,作为extensionElements的子元素.监听器不能定义在流程的单个activity下
  • delegateExpression中的表达式无法访问execution上下文,这与其余表达式不同(比方gateway).它只能援用定义在流程引擎配置的beans属性中申明的bean, 或者应用spring(未应用beans属性)中所有实现了监听器接口的spring-bean
  • 应用监听器的class属性时,只会创立一个实例.监听器实现不会依赖成员变量,是多线程平安的
  • 当一个非法的事件类型用在events属性或throwEvent中时,流程定义公布时就会抛出异样(会导致部署失败)

    • 如果class或delegateExecution由问题:类不存在,不存在的bean援用,或代理类没有实现监听器接口

      • 在流程启动时抛出异样
      • 在第一个无效的流程定义事件被监听器接管时
    • 所以要保障援用的类正确的放在classpath下,表达式也要援用一个无效的实例

      通过API散发事件

  • Activiti咱们提供了通过API应用事件机制的办法,容许触发定义在引擎中的任何自定义事件
  • 倡议只触发类型为CUSTOMActivitiEvents.能够通过RuntimeService触发事件:

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

    反对的事件类型

  • 引擎中每个事件类型都对应org.activiti.engine.delegate.event.ActivitiEventType中的一个枚举值
事件名称事件形容事件类型
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
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一个节点将要被弥补.事件蕴含了将要执行弥补的节点idActivitiActivityEvent
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用户被增加到一个组里.事件蕴含了用户和组的idActivitiMembershipEvent
MEMBERSHIP_DELETED用户被从一个组中删除.事件蕴含了用户和组的idActivitiMembershipEvent
MEMBERSHIPS_DELETED所有成员被从一个组中删除.在成员删除之前触发这个事件,所以他们都是能够拜访的.因为性能方面的思考,不会为每个成员触发独自的MEMBERSHIP_DELETED事件ActivitiMembershipEvent
  • 引擎外部所有ENTITY_* 事件都是与实体相干的,实体事件与实体的对应关系:

    • [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中
  • 对应的事件类型都蕴含对应的实体.依据类型或事件,这些实体不能再进行更新(比方,当实例以被删除).可能的话,应用事件提供的EngineServices来以平安的形式来操作引擎.即使如此,也要小心的对事件对应的实体进行更新,操作
  • 没有对应历史的实体事件,因为它们都有运行阶段的对应实体