activiti内部默认配置了许多命令拦截器,组成了一个拦截器链,用于在执行命令前后执行拦截器中的逻辑,称为CommandInceptor。
配置拦截器Interceptor
customPreCommandInceptors: 配置在默认拦截器之前
customPostCommandInceptors: 配置在默认拦截器之后
commandInvoker:配置在拦截器链的最后的执行器
示例
下面就是一个示例,通过配置一个拦截器customPreCommandInceptors,来记录整个命令执行时长。
首先配置activiti.cfg.xml文件:
<bean id="processEngineConfiguration" class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration">
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/db_activiti" />
<property name="jdbcDriver" value="com.mysql.jdbc.Driver" />
<property name="jdbcUsername" value="root" />
<property name="jdbcPassword" value="abc123" />
<property name="customPreCommandInterceptors">
<list>
<bean class="com.activiti.inceptor.DuartionCommandInceptor"></bean>
</list>
</property>
</bean>
这样在执行命令之前,先执行拦截器DuartionCommandInceptor中的方法。
下面是这个拦截器的具体实现:
public class DuartionCommandInceptor extends AbstractCommandInterceptor {
private static final Logger logger = LoggerFactory.getLogger(HelloWorld.class);
public <T> T execute(CommandConfig config, Command<T> command) {
Long startTime = System.currentTimeMillis();
try{
return this.getNext().execute(config,command);
} finally {
Long endTime = System.currentTimeMillis();
logger.info("{}执行时长:{}",command.getClass().getSimpleName(),endTime-startTime);
}
}
}
在拦截器类中首先获取当前时间,执行语句this.getNext().execute(config,command);就会递归去调用拦截器链中的后面的拦截器,当拦截器链中的所有拦截器都执行完后,才会获取结束时间,计算整个过程的耗时。最终输出结果如下 :
SchemaOperationsProcessEngineBuild执行时长:40
ValidateExecutionRelatedEntityCountCfgCmd执行时长:5
GetNextIdBlockCmd执行时长:9
GetProcessDefinitionInfoCmd执行时长:4
...
下面来看这几个拦截器是怎么添加到拦截器链的,在ProcessEngineConfigurationImpl配置类的初始化函数中:
public void initCommandInterceptors() {
if (commandInterceptors == null) {
commandInterceptors = new ArrayList<CommandInterceptor>();
if (customPreCommandInterceptors != null) {
commandInterceptors.addAll(customPreCommandInterceptors);
}
commandInterceptors.addAll(getDefaultCommandInterceptors());
if (customPostCommandInterceptors != null) {
commandInterceptors.addAll(customPostCommandInterceptors);
}
commandInterceptors.add(commandInvoker);
}
}
可以看到依次如果我们配置了这几个拦截器,初始化的时候就会自动将它们加到拦截器链中。