【命令模式】-Flow中的应用,浅读flowable源码

Flowable使用命令模式处理主要方法执行,通过CommandExecutor初始化流程引擎。在执行业务方法时,构建Command对象并由CommandExecutor执行,其实现涉及责任链模式,每个CommandInterceptor处理一部分任务。这种设计使得业务逻辑解耦,提高了灵活性。

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

1.flow中的运用

flowable中主要运用了命令模式来处理几个主要方法的执行

1.1 CommandExecutor是在系统启动时,初始化流程引擎时加载出来


    public class ProcessEngineFactoryBean implements FactoryBean<ProcessEngine>, DisposableBean, ApplicationContextAware {
    @Override
    public ProcessEngine getObject() throws Exception {
        this.configureExpressionManager();
        this.configureExternallyManagedTransactions();
        if (this.processEngineConfiguration.getBeans() == null) {
            this.processEngineConfiguration.setBeans(new SpringBeanFactoryProxyMap(this.applicationContext));
        }
    	//初始化流程引擎
        this.processEngine = this.processEngineConfiguration.buildProcessEngine();
        return this.processEngine;
    }
      @Override
    public ProcessEngine buildProcessEngine() { 
    	  //初始化
		  init();
		  //....
		}
}

流程引擎工厂实现了FactoryBean,执行getObject方法时会初始流程引擎

1.2 流程在执行方法时(通过各种已经提前注册好的service),首先构建Command对象,通过CommandExecutor执行

  @Override
    public void complete(String taskId, Map<String, Object> variables) {
        commandExecutor.execute(new CompleteTaskCmd(taskId, variables));
    }
public class CompleteTaskCmd extends NeedsActiveTaskCmd<Void> {
      @Override
      protected Void execute(CommandContext commandContext, TaskEntity task) {
          //所有业务执行都在Cmd的实现类实现,最后通过CommandInvoker执行
      }
}

由于各个业务的service都是继承CommonEngineServiceImpl ,此时CommandExecutor已经提前注入。

1.3CommandExecutor执行CommandInterceptor责任链模式

public class CommandExecutorImpl implements CommandExecutor {
    protected CommandInterceptor first;
    @Override
    public <T> T execute(CommandConfig config, Command<T> command) {
        return first.execute(config, command, this);
    }
}

//责任链模式,每个CommandInterceptor实现类都会存储next
public interface CommandInterceptor {

    <T> T execute(CommandConfig config, Command<T> command, CommandExecutor commandExecutor);

    CommandInterceptor getNext();

    void setNext(CommandInterceptor next);

}

1.4 总结

flowable的业务逻辑通过命令模式配合责任链模式解决了每个业务的执行与调度解耦。通过封装业务需要的命令,配合责任链共同组成每一个业务执行需要的逻辑,逻辑间相互解耦。请求者只需要找到对应的service,然后创建命令类,拦截器相当于命令模式中的接收者,CommandExecutor相当于执行者,执行已经接收组装好的命令

Flowable 是一个流程引擎框架,条件判断是其中非常重要的一部分。Flowable 中的条件判断主要分为两类:表达式条件判断和脚本条件判断。下面分别介绍这两种条件判断的源码实现。 1. 表达式条件判断 表达式条件判断是通过表达式来判断条件是否成立。Flowable 中支持的表达式语言有 EL 表达式、Juel 表达式、Mvel 表达式等。这里以 EL 表达式为例。 首先我们看到 Flowable 中的表达式条件判断是通过 org.flowable.bpmn.model.SequenceFlow中的 conditionExpression 属性来实现的。该属性的类型为 String,表示一个表达式字符串。 在执行条件判断时,Flowable 会将这个表达式字符串解析成一个 EL 表达式对象,并将当前执行上下文中的变量传递给该表达式对象进行计算,最终得出判断结果。下面是相关源码实现: ```java public class SequenceFlow extends FlowElement { protected String conditionExpression; // ... public boolean hasCondition() { return StringUtils.isNotEmpty(conditionExpression); } public Expression getConditionExpression() { if (hasCondition()) { ExpressionManager expressionManager = Context.getProcessEngineConfiguration().getExpressionManager(); return expressionManager.createExpression(conditionExpression); } return null; } // ... } ``` 可以看到,当 conditionExpression 属性不为空时,调用 getConditionExpression 方法会将该属性解析成一个 EL 表达式对象返回。 接下来看一下条件判断的执行过程。在 Flowable 中,条件判断是通过 org.flowable.engine.impl.bpmn.behavior.ConditionalEventBehavior 类的 execute 方法实现的。该方法中会先获取 SequenceFlow 对象的 conditionExpression 属性,然后调用 getConditionExpression 方法解析成一个 EL 表达式对象。最后将当前执行上下文中的变量传递给该表达式对象进行计算,得出判断结果。下面是相关源码实现: ```java public class ConditionalEventBehavior extends FlowNodeActivityBehavior { // ... @Override public void execute(ActivityExecution execution) throws Exception { // ... SequenceFlow outgoingSequenceFlow = (SequenceFlow) conditionalEvent.getOutgoingFlows().get(0); if (outgoingSequenceFlow.hasCondition()) { Expression conditionExpression = outgoingSequenceFlow.getConditionExpression(); Object value = conditionExpression.getValue(execution); if (value instanceof Boolean && (Boolean) value) { leave(execution); } } else { leave(execution); } // ... } // ... } ``` 可以看到,当 SequenceFlow 对象的 conditionExpression 属性不为空时,会调用 getConditionExpression 方法获取一个 EL 表达式对象,并将当前执行上下文中的变量传递给该表达式对象进行计算。最终得出的判断结果为 true 时,会继续执行下一步任务,否则不会执行。 2. 脚本条件判断 脚本条件判断是通过脚本来判断条件是否成立。Flowable 中支持的脚本语言有 Groovy、JavaScript、Python 等。这里以 Groovy 为例。 在 Flowable 中,脚本条件判断是通过 org.flowable.bpmn.model.ScriptTask 类中的 script 属性来实现的。该属性的类型为 String,表示一个 Groovy 脚本字符串。 执行脚本条件判断的过程与表达式条件判断类似,在这里不再赘述。需要注意的是,在使用脚本条件判断时,需要在流程引擎配置中添加对应的脚本引擎。下面是相关源码实现: ```java public class ScriptTask extends TaskWithFieldExtensions { protected String scriptFormat; protected String script; // ... public boolean hasScript() { return StringUtils.isNotEmpty(script); } public Object executeScript(VariableScope variableScope) { ScriptingEngines scriptingEngines = Context.getProcessEngineConfiguration().getScriptingEngines(); ScriptEngine scriptEngine = scriptingEngines.getScriptEngine(scriptFormat); return scriptingEngines.evaluate(script, scriptEngine, variableScope); } // ... } ``` 可以看到,当 script 属性不为空时,调用 executeScript 方法会将该属性解析成一个 Groovy 脚本对象,并将当前执行上下文中的变量传递给该脚本对象进行计算,最终得出判断结果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值