本節繼續對activiti流程引擎的配置進行學習
1、EventLog配置
1.1、配置EventLog
首先在activiti_eventlog.cfg.xml中配置eventlog屬性爲true
1.1.1測試代碼
編寫一個eventlog測試代碼 ConfigEventLogTest.java
import org.activiti.engine.event.EventLogEntry;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.activiti.engine.test.ActivitiRule;
import org.activiti.engine.test.Deployment;
import org.junit.Rule;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.List;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
/**
* Describe:
*
* @author cwqsolo
* @date 2020/01/07
*/
public class ConfigEventLogTest {
private static final Logger logger = LoggerFactory.getLogger(ConfigEventLogTest.class);
//這裏已經包含了流程引擎的創建
@Rule
public ActivitiRule activitiRule = new ActivitiRule("activiti_eventlog.cfg.xml");
@Test
@Deployment(resources = {"./my-process.bpmn20.xml"})
public void configMDCTest1() {
ProcessInstance processInstance = activitiRule.getRuntimeService().startProcessInstanceByKey("my-process");
List<Task> list = activitiRule.getTaskService().createTaskQuery().list();
activitiRule.getTaskService().complete(list.get(0).getId());
List<EventLogEntry> eventLogEntries = activitiRule.getManagementService()
.getEventLogEntriesByProcessInstanceId(processInstance.getProcessInstanceId());
for (EventLogEntry eventLogEntry : eventLogEntries) {
logger.info("eventlog.type= {}, eventlog.data ={}", eventLogEntry.getType().toString(), new String( eventLogEntry.getData()) );
}
logger.info("eventlogEntryies size={}", eventLogEntries.size());
}
}
1.2 執行日誌
執行日誌情況如下:
源碼查看
在ProcessEngineConfigurationImpl.java類中有創建時間監聽器的代碼
這裏創建了一個新的EventLogger對象,這個對象是實現了一個監聽器
在這個類的初始化函數裏面,設置了各種事件的監聽處理類
另外,當監聽到事件後,調用 onEvent方法:
2、 事件與監聽器原理
2.1 配置監聽器
有三種類型的監聽器
eventListeners:監聽所有事件派發的通知
typedEventListeners:監聽指定事件類型的通知
activiti:eventListener:只監聽特定流程定義的事件
相關api對象:
ActivitiEvent 事件對象
ActivitiEventListener 監聽器
ActivitiEventType 事件類型,是枚舉類型,監聽器針對具體的類型進行操作
2.2 通過eventListener監聽事件
首先在配置文件中添加監聽的配置
生成一個事件監聽類的具體實現ProcessEventListener.java
package com.study.activiti.event;
import org.activiti.engine.delegate.event.ActivitiEvent;
import org.activiti.engine.delegate.event.ActivitiEventListener;
import org.activiti.engine.delegate.event.ActivitiEventType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Describe:
*
* @author cwqsolo
* @date 2020/01/09
*/
public class ProcessEventListener implements ActivitiEventListener {
private static final Logger logger = LoggerFactory.getLogger(ProcessEventListener.class);
@Override
public void onEvent(ActivitiEvent event) {
ActivitiEventType type = event.getType();
if( ActivitiEventType.PROCESS_STARTED.equals( type)){
logger.info("流程啓動 {} \t 流程實例id={}", type, event.getProcessInstanceId());
}
if( ActivitiEventType.PROCESS_COMPLETED.equals( type)){
logger.info("流程啓動 {} \t 流程實例id={}", type, event.getProcessInstanceId());
}
}
@Override
public boolean isFailOnException() {
return false;
}
}
創建測試代碼ConfigEventListenerTest
import com.study.activiti.event.CustomEventListener;
import org.activiti.engine.delegate.event.ActivitiEventType;
import org.activiti.engine.delegate.event.impl.ActivitiActivityEventImpl;
import org.activiti.engine.event.EventLogEntry;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.activiti.engine.test.ActivitiRule;
import org.activiti.engine.test.Deployment;
import org.junit.Rule;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.List;
/**
* Describe:
*
* @author cwqsolo
* @date 2020/01/07
*/
public class ConfigEventListenerTest {
private static final Logger logger = LoggerFactory.getLogger(ConfigEventListenerTest.class);
//這裏已經包含了流程引擎的創建
@Rule
public ActivitiRule activitiRule = new ActivitiRule("activiti_eventListener.cfg.xml");
@Test
@Deployment(resources = {"./my-process.bpmn20.xml"})
public void test1() {
ProcessInstance processInstance = activitiRule.getRuntimeService().startProcessInstanceByKey("my-process");
List<Task> list = activitiRule.getTaskService().createTaskQuery().list();
activitiRule.getTaskService().complete(list.get(0).getId());
List<EventLogEntry> eventLogEntries = activitiRule.getManagementService()
.getEventLogEntriesByProcessInstanceId(processInstance.getProcessInstanceId());
for (EventLogEntry eventLogEntry : eventLogEntries) {
logger.info("eventlog.type= {}, eventlog.data ={}", eventLogEntry.getType().toString(), new String( eventLogEntry.getData()) );
}
logger.info("eventlogEntryies size={}", eventLogEntries.size());
}
}
執行日誌中會打印出來剛纔監聽實現中的打印信息
2.3 通過eventTypeListener監聽事件
下面在上面基礎上添加eventTpyeListener的功能。這個功能是通過監聽指定類型的事件作出響應
創建針對指定類型的事件監聽類ProcessEventTypeListener.java
package com.study.activiti.event;
import org.activiti.engine.delegate.event.ActivitiEvent;
import org.activiti.engine.delegate.event.ActivitiEventListener;
import org.activiti.engine.delegate.event.ActivitiEventType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Describe:
*
* @author cwqsolo
* @date 2020/01/09
*/
public class ProcessEventTypeListener implements ActivitiEventListener {
private static final Logger logger = LoggerFactory.getLogger(ProcessEventTypeListener.class);
@Override
public void onEvent(ActivitiEvent event) {
ActivitiEventType type = event.getType();
if( ActivitiEventType.ACTIVITY_COMPLETED .equals( type)){
logger.info("活動結束 {} \t 流程實例id={}", type, event.getProcessInstanceId());
}
}
@Override
public boolean isFailOnException() {
return false;
}
}
在配置文件中添加對應的配置內容
執行的時候,我們可以看到在原來的監聽基礎上,我們還多了事件類型的監聽處理
2.4 監聽用戶自定義事件
我們還可以進行用戶自定義的監聽,需要3個步驟:
首先添加一個事件監聽的自定義處理
流程事件處理中dispatch一個自定義事件
在配置文件中添加這個事件的處理配置
下面我們看一下上面的三個步驟具體實現
- 創建一個類CustomEventListener.java
package com.study.activiti.event;
import org.activiti.engine.delegate.event.ActivitiEvent;
import org.activiti.engine.delegate.event.ActivitiEventListener;
import org.activiti.engine.delegate.event.ActivitiEventType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Describe:
*
* @author cwqsolo
* @date 2020/01/09
*/
public class CustomEventListener implements ActivitiEventListener {
private static final Logger logger = LoggerFactory.getLogger(CustomEventListener.class);
@Override
public void onEvent(ActivitiEvent event) {
ActivitiEventType type = event.getType();
if( ActivitiEventType.CUSTOM.equals( type)){
logger.info("監聽到用戶事件 {} \t 流程實例id={}", type, event.getProcessInstanceId());
}
}
@Override
public boolean isFailOnException() {
return false;
}
}
2 修改流程處理中內容,在測試代碼中添加下面語句
3、修改配置文件
最後我們看一下執行結果
2.5 源碼中事件監聽的層級
3、命令攔截器
3.1 創建一個攔截器
在下列位置創建一個攔截器
這個類的代碼如下:
package com.study.activiti.interceptor;
import org.activiti.engine.impl.interceptor.AbstractCommandInterceptor;
import org.activiti.engine.impl.interceptor.Command;
import org.activiti.engine.impl.interceptor.CommandConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Describe:
*
* @author cwqsolo
* @date 2020/01/13
*/
public class DurationCommandInterceptor extends AbstractCommandInterceptor {
private static final Logger logger = LoggerFactory.getLogger(DurationCommandInterceptor.class);
@Override
public <T> T execute(CommandConfig config, Command<T> command) {
long start = System.currentTimeMillis();
try{
return this.getNext().execute(config, command);
}finally{
long duration = System.currentTimeMillis()- start;
logger.info("{} 執行時長 {} 毫秒", command.getClass().getSimpleName(), duration);
}
}
}
3.2 創建配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<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.StandaloneInMemProcessEngineConfiguration">
<property name="dataSource" ref="dataSource"></property> <!-- dataSource bean -->
<property name="databaseSchemaUpdate"
value="false"></property> <!--activiti這個屬性可以進行庫表創建 true, false , create-drop -->
<property name="commandInvoker" ref="commandInvoker"/>
<property name="customPreCommandInterceptors">
<list>
<bean class="com.study.activiti.interceptor.DurationCommandInterceptor"/>
</list>
</property>
</bean>
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName"
value="com.mysql.jdbc.Driver"></property> <!-- 數據庫驅動類 mysql是這個,其它的數據庫修改一下即可 -->
<property name="url"
value="jdbc:mysql://localhost:3306/activiti6?characterEncoding=UTF-8"></property> <!-- 數據庫URL,我放在名爲activiti數據庫中 -->
<property name="username" value="root"></property> <!-- 連接數據庫的賬號 -->
<property name="password" value="root123"></property> <!-- 連接數據庫的密碼 -->
<property name="initialSize" value="1"></property> <!-- -->
<property name="maxActive" value="20"></property> <!-- -->
<property name="filters" value="stat,slf4j"></property> <!-- -->
</bean>
<!--將我們自定義的流程引擎打印信息用的攔截器設置到流程引擎裏面 -->
<bean id="commandInvoker" class="com.study.activiti.interceptor.MDCCommandInvoke"/>
</beans>
3.3 創建測視類
創建一個測試類ConfigInterceptorTest.java
import org.activiti.engine.delegate.event.ActivitiEventType;
import org.activiti.engine.delegate.event.impl.ActivitiActivityEventImpl;
import org.activiti.engine.event.EventLogEntry;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.activiti.engine.test.ActivitiRule;
import org.activiti.engine.test.Deployment;
import org.junit.Rule;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.List;
/**
* Describe:
*
* @author cwqsolo
* @date 2020/01/07
*/
public class ConfigInterceptorTest {
private static final Logger logger = LoggerFactory.getLogger(ConfigInterceptorTest.class);
//這裏已經包含了流程引擎的創建
@Rule
public ActivitiRule activitiRule = new ActivitiRule("activiti_interceptor.cfg.xml");
@Test
@Deployment(resources = {"./my-process.bpmn20.xml"})
public void test1() {
ProcessInstance processInstance = activitiRule.getRuntimeService().startProcessInstanceByKey("my-process");
List<Task> list = activitiRule.getTaskService().createTaskQuery().list();
activitiRule.getTaskService().complete(list.get(0).getId());
}
}
3.4 執行結果
下圖爲執行日誌
4、作業執行器
作業執行器的相關配置有:
作業執行器的配置
配置自定義線程池
流程定義定時啓動配置
一些重要的配置參數:
asyncExecutorActivate 激活作業執行器,asyncExecutorXXX 異步執行配置,asyncExecutor, 一步執行器器bean
自定義線程池 ExecutorService: corePoolSize核心線程數 maxPoolSize最大線程數
QueueCapacity:堵塞隊列大小
作業執行定時開始事件(Timer Start Event):
timeDate, 指定啓動時間
timeDuration: 指定持續時間間隔後執行
timeCycle:指定週期執行
下面我們實現一個基於job的流程,並進行監聽,打印job執行的相關信息
4.1 創建一個定時執行流程定義文件
首先創建一個bpmc的xml文件
<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:activiti="http://activiti.org/bpmn"
xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC"
xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" typeLanguage="http://www.w3.org/2001/XMLSchema"
expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://www.activiti.org/test">
<process id="my-process">
<!-- <startEvent id="start" />-->
<startEvent id="start" >
<timerEventDefinition>
<timeCycle>R5/PT10S</timeCycle>
</timerEventDefinition>
</startEvent>
<sequenceFlow id="flow1" sourceRef="start" targetRef="someTask" />
<userTask id="someTask" name="Activiti is awesome!" />
<sequenceFlow id="flow2" sourceRef="someTask" targetRef="end" />
<endEvent id="end" />
</process>
</definitions>
4.2 創建指定JOB監聽器
創建一個只監聽job的監聽器:JobEventListener.java
package com.study.activiti.event;
import org.activiti.engine.delegate.event.ActivitiEvent;
import org.activiti.engine.delegate.event.ActivitiEventListener;
import org.activiti.engine.delegate.event.ActivitiEventType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Describe:
*
* @author cwqsolo
* @date 2020/01/09
*/
public class JobEventListener implements ActivitiEventListener {
private static final Logger logger = LoggerFactory.getLogger(JobEventListener.class);
@Override
public void onEvent(ActivitiEvent event) {
ActivitiEventType type = event.getType();
String name = type.name();
if( name.startsWith("TIMER") || name.startsWith("JOB")){
logger.info("監聽到用戶事件 {} \t 流程實例id={}", type, event.getProcessInstanceId());
}
}
@Override
public boolean isFailOnException() {
return false;
}
}
4.3 創建配置文件
創建對應的配置文件activiti-job.cfg.xml
<?xml version="1.0" encoding="UTF-8"?>
<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.StandaloneInMemProcessEngineConfiguration">
<property name="dataSource" ref="dataSource"></property> <!-- dataSource bean -->
<property name="databaseSchemaUpdate"
value="false"></property> <!--activiti這個屬性可以進行庫表創建 true, false , create-drop -->
<property name="enableDatabaseEventLogging" value="true" />
<property name="asyncExecutorActivate" value="true"></property> <!--打開系統自帶的異步線程池 -->
<property name="asyncExecutor" ref="asyncExecutor"/>
<property name="eventListeners">
<list>
<bean class="com.study.activiti.event.JobEventListener"/>
</list>
</property>
</bean>
<bean id="asyncExecutor" class="org.activiti.engine.impl.asyncexecutor.DefaultAsyncJobExecutor">
<property name="executorService" ref="executorService"/>
</bean>
<bean id="executorService" class ="org.springframework.scheduling.concurrent.ThreadPoolExecutorFactoryBean">
<property name="threadNamePrefix" value="act-job-"/>
<property name="corePoolSize" value="5"/>
<property name="maxPoolSize" value="20"/>
<property name="queueCapacity" value="100"/>
<property name="rejectedExecutionHandler">
<bean class="java.util.concurrent.ThreadPoolExecutor$AbortPolicy"/>
</property>
</bean>
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName"
value="com.mysql.jdbc.Driver"></property> <!-- 數據庫驅動類 mysql是這個,其它的數據庫修改一下即可 -->
<property name="url"
value="jdbc:mysql://localhost:3306/activiti6?characterEncoding=UTF-8"></property> <!-- 數據庫URL,我放在名爲activiti數據庫中 -->
<property name="username" value="root"></property> <!-- 連接數據庫的賬號 -->
<property name="password" value="root123"></property> <!-- 連接數據庫的密碼 -->
<property name="initialSize" value="1"></property> <!-- -->
<property name="maxActive" value="20"></property> <!-- -->
<property name="filters" value="stat,slf4j"></property> <!-- -->
</bean>
<!--將我們自定義的流程引擎打印信息用的攔截器設置到流程引擎裏面 -->
<bean id="commandInvoker" class="com.study.activiti.interceptor.MDCCommandInvoke" />
</beans>
4.4 創建測試類
創建一個測視類,主要是打印定時job啓動後的任務執行信息,任務執行信息是通過監聽器來傳遞的。
import org.activiti.engine.event.EventLogEntry;
import org.activiti.engine.runtime.Job;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.activiti.engine.test.ActivitiRule;
import org.activiti.engine.test.Deployment;
import org.junit.Rule;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.List;
/**
* Describe:
*
* @author cwqsolo
* @date 2020/01/07
*/
public class ConfigJobTest {
private static final Logger logger = LoggerFactory.getLogger(ConfigJobTest.class);
//這裏已經包含了流程引擎的創建
@Rule
public ActivitiRule activitiRule = new ActivitiRule("activiti_job.cfg.xml");
@Test
@Deployment(resources = {"./my-process-job.bpmn20.xml"})
public void Test1() throws InterruptedException {
logger.info("start");
List<Job> jobs = activitiRule.getManagementService().createTimerJobQuery().listPage(0, 100);
for (Job job:jobs){
logger.info("定時任務={}, 默認重試次數={}", job, job.getRetries());
}
logger.info("jobs.size={}", jobs.size());
Thread.sleep(1000*100);
logger.info("end");
}
}
4.5 執行結果
在監聽器中,我們代碼指定了如果事件的類似爲TIMER或者JOB的需要進行處理(打印)
5、與Spring集成
集成spring需要添加pom依賴activi-spring,基於Spring的默認配置是activiti-context.xml,核心服務需要注入Spring容器。如果需要單元測試,還需要在pom中添加spring-test,輔助測試Rule:ActivitiRule。下面通過一個demo來演示如何進行spring集成。思路是:先集成spring,然後通過自定義個bean,注入到流程的某個環節中。
5.1 創建一下配置文件
創建一個配置文件activiti-context.xml,內容如下:
<?xml version="1.0" encoding="UTF-8"?>
<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="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName"
value="com.mysql.jdbc.Driver"></property> <!-- 數據庫驅動類 mysql是這個,其它的數據庫修改一下即可 -->
<property name="url"
value="jdbc:mysql://localhost:3306/activiti6?characterEncoding=UTF-8"></property> <!-- 數據庫URL,我放在名爲activiti數據庫中 -->
<property name="username" value="root"></property> <!-- 連接數據庫的賬號 -->
<property name="password" value="root123"></property> <!-- 連接數據庫的密碼 -->
<property name="initialSize" value="1"></property> <!-- -->
<property name="maxActive" value="20"></property> <!-- -->
<property name="filters" value="stat,slf4j"></property> <!-- -->
</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> <!-- dataSource bean -->
<property name="transactionManager" ref="transactionManager"/>
<property name="databaseSchemaUpdate" value="true"></property>
</bean>
<!-- 指定流程引擎配置對象工廠bean-->
<bean id="processEngine" class="org.activiti.spring.ProcessEngineFactoryBean">
<property name="processEngineConfiguration" ref="processEngineConfiguration"/>
</bean>
<!--服務注入 -->
<bean id="runtimeService" factory-bean="processEngine" factory-method="getRuntimeService"/>
<bean id="repositoryService" factory-bean="processEngine" factory-method="getRepositoryService"/>
<bean id="formService" factory-bean="processEngine" factory-method="getFormService"/>
<bean id="taskService" factory-bean="processEngine" factory-method="getTaskService"/>
<bean id="historyService" factory-bean="processEngine" factory-method="getHistoryService"/>
<bean id="activitiRule" class="org.activiti.engine.test.ActivitiRule">
<property name="processEngine" ref="processEngine"></property>
</bean>
</beans>
5.2 創建測試類
創建一個測試類可以進行spring集成測試
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.activiti.engine.test.ActivitiRule;
import org.activiti.engine.test.Deployment;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import java.util.List;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
/**
* Describe:
*
* @author cwqsolo
* @date 2020/01/07
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:activiti_context.xml"})
public class ConfigSpringTest {
private static final Logger logger = LoggerFactory.getLogger(ConfigSpringTest.class);
//這裏自動裝配配置文件中的activitirule
@Rule
@Autowired
public ActivitiRule activitiRule;
@Autowired
private RuntimeService runtimeService;
@Autowired
private TaskService taskService;
@Test
@Deployment(resources = {"./my-process.bpmn20.xml"})
public void test() {
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("my-process");
;
assertNotNull(processInstance);
List<Task> list = taskService.createTaskQuery().list();
for (Task task : list
) {
taskService.complete(task.getId());
}
}
}
5.3 執行日誌
下圖是執行日誌的情況:
注意一下,spring需要junit的版本在4.12以上,否則會報告如下錯誤。
5.4 設計自定義bean
下面設計一個自定義的bean,並注入到流程執行過程中。在流程配置文件中添加一個節點,並且這個節點執行這個bean的sayHello方法。創建一個類HelloBean
package com.study.activiti.delegate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Describe:
*
* @author cwqsolo
* @date 2020/01/29
*/
public class HelloBean {
private static final Logger logger = LoggerFactory.getLogger(HelloBean.class);
public void sayHello(){
logger.info("Hello world");
}
}
在配置文件activiti_context.xml裏配置bean的地方,加上這個bean的配置
5.5 創建一個新的流程定義
下面創建一個新的流程定義文件,在某個環節中配置上我們的自定義類
5.6 流程結合自定義bean執行日誌
執行我們的測試類,在打印的信息中可以看到下面內容: