阿西吧,写了一个多小时的博客不小心点到了360清理资源 ,直接给我关了。服了,直接放图了
命令模式:
command : 抽象的 命令接口
concretecommand:基于命名 接口的命令实现,定义命令具体做什么的
构造命令需要传入一个参数 也就是接收者
receiver:接收者,接收命令
在接收了以后,再根据接收者与命令实现创建出命令来
这个命令由invoker来执行它
其实命令执行器是间接的去调用命令实现concretecommand的execute()方法,最终再去调用receiver中的action()方法
client其实不属于命令模式,它只是作为客户调用命令模式的切入点。
命令模式时序图↓:
责任链模式:
哪怕不做任何配置,activiti也会产生一个默认的commandinterceptor的拦截器链(责任链)
在它之前我们可以配置customPreCommandInterceptors在它之后我们可以配置customPostCommandInterceptors或者我们的自定义拦截器,在这些都执行完了以后,最后会有一个command invoker 执行。
为什么会这样呢,因为它就是我们最终的命令执行者。从图中可以看出来,在我们执行customPre中的execute实现时,execute实现大多是调用了next的实现,一次类推,只有最后的command invoker执行时是调用了执行器,它就不再去考虑next下一个对象是什么了。
一环扣一环。
命令拦截器配置:
activiti6都有以下拦截器:
下面贴上测试代码:
自定义时长拦截器DurationCommandInterceptor:
public class DurationCommandInterceptor extends AbstractCommandInterceptor { private static final Logger LOGGER = LoggerFactory.getLogger(DurationCommandInterceptor.class); 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); } } }
拦截器配置文件activiti_interceptor.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"> <!-- 给引擎设置自定义的commandInvoker --> <property name="commandInvoker" ref="commandInvoker" /> <!-- 若为true则开启记录事件、节点的状态,完成后将完成状态插入数据库,若为false则关闭,不记录 --> <property name="enableDatabaseEventLogging" value="true"/> <!-- 配置命令拦截器 这里需知道customPreCommandInterceptors与 的区别--> <property name="customPreCommandInterceptors"> <list> <!-- 配置上时长拦截器 --> <bean class="com.yy.avtiviti.helloworld.intercept.DurationCommandInterceptor"/> </list> </property> <!--这个东西千万不能这样配置,否则流程无法正常运行,因为commandInterceptors是整个链的组合体<property name="commandInterceptors"/>--> <property name="customPostCommandInterceptors"> <list> <!-- 配置上时长拦截器 --> <bean class="com.yy.avtiviti.helloworld.intercept.DurationCommandInterceptor"/> </list> </property> </bean> <bean id="commandInvoker" class="com.yy.avtiviti.helloworld.intercept.MDCCommandInvoker"/> </beans>
最后贴上测试类configInterceptorTest:
public class configInterceptorTest { private static final Logger LOGGER = LoggerFactory.getLogger(configTest.class); @Rule public ActivitiRule activitiRule = new ActivitiRule("activiti_interceptor.cfg.xml");//传入自定义的mdc配置文件 @Test @Deployment(resources = {"my-process.bpmn20.xml"})//流程定义文件 public void test() { ProcessInstance processInstance = activitiRule.getRuntimeService().startProcessInstanceByKey("my-process"); Task task = activitiRule.getTaskService().createTaskQuery().singleResult(); activitiRule.getTaskService().complete(task.getId()); } }
测试结果如下: