Activiti入门教程四(自定义Activiti命令拦截器)

本文详细介绍了如何在Activiti中自定义命令拦截器,通过继承ProcessEngineConfigurationImpl并实现相关方法。讲解了拦截器的执行过程,涉及命令模式和责任链设计模式。并展示了从创建拦截器到配置流程引擎,以及XML数据库配置的完整步骤,最后提供了测试类的效果展示。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

               

     上一篇博客中在末尾提到了自定义属于自己的引擎配置,然后自定义一个类,直接继承ProcessEngineConfigurationImpl类即可,但必须要实现两个抽象的方法,如下

 protected abstract Collection< ? extends CommandInterceptor> getDefaultCommandInterceptorsTxRequired();

 protected abstract Collection< ? extends CommandInterceptor> getDefaultCommandInterceptorsTxRequiresNew();


     如果英文好的人,应该就看出来了,这就是Activiti中的拦截器,其实拦截器的原理采用了设计模式中的命令模式和责任链模式,关于设计模式请参考职责链模式


     下面就先来通过源码分析,来谈一下Activiti中拦截器的执行过程。

     当初始化流程引擎的时候,会执行下面的方法

 

<span style="font-family:Comic Sans MS;font-size:18px;"><span style="font-family:Comic Sans MS;font-size:18px;"> public ProcessEngine buildProcessEngine() {    init();    return new ProcessEngineImpl(this);  }</span></span>

     下面我们再通过源码来看一下Init()方法

<span style="font-family:Comic Sans MS;font-size:18px;"><span style="font-family:Comic Sans MS;font-size:18px;">protected void init() {    initHistoryLevel();    initExpressionManager();    initVariableTypes();    initBeans();    initFormEngines();    initFormTypes();    initScriptingEngines();    initBusinessCalendarManager();    initCommandContextFactory();    initTransactionContextFactory();    initCommandExecutors();    initServices();    initIdGenerator();    initDeployers();    initJobExecutor();    initDataSource();    initTransactionFactory();    initSqlSessionFactory();    initSessionFactories();    initJpa();    initDelegateInterceptor();    initEventHandlers();    initFailedJobCommandFactory();    initConfigurators();  }</span></span>


     我们看到init()方法,初始化了很多操作,其中就有我们的 initCommandExecutors(),添加拦截器的操作,那么什么时候拦截器起作用呢?我们接着来看一下 return new ProcessEngineImpl(this)方法的实现操作

<span style="font-family:Comic Sans MS;font-size:18px;"><span style="font-family:Comic Sans MS;font-size:18px;"> public ProcessEngineImpl(ProcessEngineConfigurationImpl processEngineConfiguration) {    this.processEngineConfiguration = processEngineConfiguration;    this.name = processEngineConfiguration.getProcessEngineName();    this.repositoryService = processEngineConfiguration.getRepositoryService();    this.runtimeService = processEngineConfiguration.getRuntimeService();    this.historicDataService = processEngineConfiguration.getHistoryService();    this.identityService = processEngineConfiguration.getIdentityService();    this.taskService = processEngineConfiguration.getTaskService();    this.formService = processEngineConfiguration.getFormService();    this.managementService = processEngineConfiguration.getManagementService();    this.databaseSchemaUpdate = processEngineConfiguration.getDatabaseSchemaUpdate();    this.jobExecutor = processEngineConfiguration.getJobExecutor();    this.commandExecutor = processEngineConfiguration.getCommandExecutorTxRequired();    this.sessionFactories = processEngineConfiguration.getSessionFactories();    this.transactionContextFactory = processEngineConfiguration.getTransactionContextFactory();        commandExecutor.execute(new SchemaOperationsProcessEngineBuild());    if (name == null) {      log.info("default activiti ProcessEngine created");    } else {      log.info("ProcessEngine {} created", name);    }        ProcessEngines.registerProcessEngine(this);    if ((jobExecutor != null) && (jobExecutor.isAutoActivate())) {      jobExecutor.start();    }        if(processEngineConfiguration.getProcessEngineLifecycleListener() != null)    {      processEngineConfiguration.getProcessEngineLifecycleListener().onProcessEngineBuilt(this);    }  }</span></span>


     可以看到在这个方法中,实例化了很多引擎对象,关键的一句在于 commandExecutor.execute(new SchemaOperationsProcessEngineBuild()),该语句就触发了拦截器操作,通过责任链来执行我们的拦截器。


     上面讲述了拦截器的执行时机,下面就来自定义一个拦截器

     拦截器A

<span style="font-family:Comic Sans MS;font-size:18px;"><span style="font-family:Comic Sans MS;font-size:18px;">package org.crazyit.activiti;import org.activiti.engine.impl.interceptor.Command;import org.activiti.engine.impl.interceptor.CommandInterceptor;/** * 拦截器实现A *  */public class InterceptorA extends CommandInterceptor public <T> T execute(Command<T> command) {  // 输出字符串和命令  System.out.println("this is interceptor A "    + command.getClass().getName());  // 然后让责任链中的下一请求处理者处理命令  return next.execute(command); }}</span></span>



    拦截器B

<span style="font-family:Comic Sans MS;font-size:18px;"><span style="font-family:Comic Sans MS;font-size:18px;">package org.crazyit.activiti;import org.activiti.engine.impl.interceptor.Command;import org.activiti.engine.impl.interceptor.CommandInterceptor;public class InterceptorB extends CommandInterceptor @Override public <T> T execute(Command<T> command) {  // 输出字符串和命令  System.out.println("this is interceptor B "    + command.getClass().getName());  // 然后让责任链中的下一请求处理者处理命令  return next.execute(command); }}</span></span>


     然后自定义流程引擎配置,并在其中添加我们的拦截器即可

<span style="font-family:Comic Sans MS;font-size:18px;"><span style="font-family:Comic Sans MS;font-size:18px;">package org.crazyit.activiti;import java.util.ArrayList;import java.util.Collection;import java.util.List;import org.activiti.engine.ProcessEngine;import org.activiti.engine.impl.cfg.ProcessEngineConfigurationImpl;import org.activiti.engine.impl.context.Context;import org.activiti.engine.impl.interceptor.CommandContextInterceptor;import org.activiti.engine.impl.interceptor.CommandInterceptor;import org.activiti.engine.impl.interceptor.LogInterceptor;/** * 自定义配置类 */public class TestConfiguration extends ProcessEngineConfigurationImpl protected Collection<? extends CommandInterceptor> getDefaultCommandInterceptorsTxRequired() {  // 创建一个拦截器集合  List<CommandInterceptor> defaultCommandInterceptorsTxRequired = new ArrayList<CommandInterceptor>();  // 添加自定义拦截器A  defaultCommandInterceptorsTxRequired.add(new InterceptorA());  // 添加系统的拦截器  defaultCommandInterceptorsTxRequired.add(new CommandContextInterceptor(    commandContextFactory, this));  return defaultCommandInterceptorsTxRequired; } protected Collection<? extends CommandInterceptor> getDefaultCommandInterceptorsTxRequiresNew() {  // 创建一个拦截器集合  List<CommandInterceptor> defaultCommandInterceptorsTxRequired = new ArrayList<CommandInterceptor>();  // 添加自定义拦截器  defaultCommandInterceptorsTxRequired.add(new InterceptorB());  return defaultCommandInterceptorsTxRequired; }}</span></span>


     这样就完成了我们的自定义拦截器的操作,下面来通过XML文件配置相关的数据库信息

<span style="font-family:Comic Sans MS;font-size:18px;"><?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.crazyit.activiti.TestConfiguration">  <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/activiti" />  <property name="jdbcDriver" value="com.mysql.jdbc.Driver" />  <property name="jdbcUsername" value="root" />  <property name="jdbcPassword" value="" />  <property name="databaseSchemaUpdate" value="true"></property> </bean></beans></span>



     最后看一下测试类

<span style="font-family:Comic Sans MS;font-size:18px;">package org.crazyit.activiti;import java.util.HashMap;import java.util.Map;import org.activiti.engine.ProcessEngine;import org.activiti.engine.ProcessEngineConfiguration;import org.activiti.engine.ProcessEngines;public class MyConfig /**  * @param args  */ public static void main(String[] args) {  ProcessEngines.getDefaultProcessEngine();  // 创建Activiti配置对象  ProcessEngineConfiguration config = ProcessEngineConfiguration    .createProcessEngineConfigurationFromResource("my-config.xml");  // 初始化流程引擎  ProcessEngine engine = config.buildProcessEngine();  // 部署一个最简单的流程  engine.getRepositoryService().createDeployment()    .addClasspathResource("bpmn/config.bpmn20.xml").deploy();  // 构建流程参数  Map<String, Object> vars = new HashMap<String, Object>();  vars.put("day", 10);  // 开始流程  engine.getRuntimeService().startProcessInstanceByKey("vacationProcess",    vars); }}</span>


     效果如下






           

再分享一下我老师大神的人工智能教程吧。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!https://blog.youkuaiyun.com/jiangjunshow

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值