目录
1 项目启动时CommandInterceptor 责任链的初始化
b. SpringTransactionInterceptor:
d. TransactionContextInterceptor:
概述:
Activiti在对外提供流程处理功能的设计模式为典型的命令模式+责任链模式, activiti将处理业务的逻辑直接封装成一个个实现Command接口的类, 提供execute() 函数来处理相应的业务逻辑;
1 项目启动时CommandInterceptor 责任链的初始化
org.activiti.engine.impl.cfg.ProcessEngineConfigurationImpl#initCommandExecutors
public void initCommandExecutors() {
//初始化拦截器配置和五个主要对象
initDefaultCommandConfig();
initSchemaCommandConfig();
initCommandInvoker();
initCommandInterceptors();
initCommandExecutor();//创建责任链
}
public void initCommandExecutor() {
if (commandExecutor == null) {
CommandInterceptor first = initInterceptorChain(commandInterceptors);
commandExecutor = new CommandExecutorImpl(getDefaultCommandConfig(), first);
}
}
public CommandInterceptor initInterceptorChain(List<CommandInterceptor> chain) {
if (chain == null || chain.isEmpty()) {
throw new ActivitiException("invalid command interceptor chain configuration: " + chain);
}
for (int i = 0; i < chain.size() - 1; i++) {
chain.get(i).setNext(chain.get(i + 1));
}
return chain.get(0);
}
2 拦截器调用顺序和职责
五个主要拦截器:LogInterceptor、SpringTransactionInterceptor、CommandContextInterceptor、TransactionContextInterceptor、CommandInvoker
a. LogInterceptor:
打印目前在执行哪个command
b. SpringTransactionInterceptor:
加入spring事务来处理
c. CommandContextInterceptor:
将当前command包装成CommandContext ,放入核心对象Context中,并管理CommandContext的声明周期
d. TransactionContextInterceptor:
将CommandContext 包装成TransactionContext,并放入Context中
e. CommandInvoker:
调用Command对象的入口
public <T> T execute(final CommandConfig config, final Command<T> command) {
final CommandContext commandContext = Context.getCommandContext();
// Execute the command.
// This will produce operations that will be put on the agenda.
commandContext.getAgenda().planOperation(new Runnable() {
@Override
public void run() {
commandContext.setResult(command.execute(commandContext));//保存命令对象
}
});
// Run loop for agenda
executeOperations(commandContext);//调用命令对象
// At the end, call the execution tree change listeners.
// TODO: optimization: only do this when the tree has actually changed (ie check dbSqlSession).
if (commandContext.hasInvolvedExecutions()) {
Context.getAgenda().planExecuteInactiveBehaviorsOperation();
executeOperations(commandContext);
}
return (T) commandContext.getResult();
}
总结:
Command
命令接口,具体的命令逻辑须要实现该类,拦截器会调用该类的execute方法执行具体业务逻辑,做到了解耦和单一职责原则CommandContext和Context在拦截器链路里多次使用, 具体作用,以后补充