您的位置:首页 > 其它

ACTIVITI 源码研究之命令模式执行

2017-05-03 10:38 956 查看
流程引擎所有的操作都采用命令模式,使用命令执行器进行执行,命令执行器是一个采用拦截器链式执行模式。

-

命令执行器:CommandExecutor

其实现类CommandExecutorImpl的代码:

public class CommandExecutorImpl implements CommandExecutor {
private final CommandConfig defaultConfig;
private final CommandInterceptor first;

//构造一个命令执行器
public CommandExecutorImpl(CommandConfig defaultConfig, CommandInterceptor first) {
this.defaultConfig = defaultConfig;
this.first = first;
}

...

//执行器执行一个命令
public <T> T execute(Command<T> command) {
return execute(this.defaultConfig, command);
}
//开始拦截器的链式调用
public <T> T execute(CommandConfig config, Command<T> command) {
return this.first.execute(config, command);
}
}


获取拦截器列表

拦截器列表的初始化在ProcessEngineConfigurationImpl中的initCommandExecutors();进行的

protected void initCommandExecutors() {
initDefaultCommandConfig();
initSchemaCommandConfig();
//命令调用器
initCommandInvoker();
//初始化命令拦截器
initCommandInterceptors();
//初始化命令执行器
initCommandExecutor();
}


初始化拦截器列表:客户自定义前置拦截器、默认拦截器、后置拦截器

protected void initCommandInterceptors() {
if (this.commandInterceptors == null) {
this.commandInterceptors = new ArrayList();
if (this.customPreCommandInterceptors != null) {
//客户自定义前置拦截器
this.commandInterceptors.addAll(this.customPreCommandInterceptors);
}
//默认拦截器
this.commandInterceptors.addAll(getDefaultCommandInterceptors());
if (this.customPostCommandInterceptors != null) {
//后置拦截器
this.commandInterceptors.addAll(this.customPostCommandInterceptors);
}
//命令调用器,拦截器最后的一个,为调用具体的命令
this.commandInterceptors.add(this.commandInvoker);
}
}


activiti默认的拦截器

protected Collection<? extends CommandInterceptor> getDefaultCommandInterceptors() {
List interceptors = new ArrayList();
//添加一个日志拦截器
interceptors.add(new LogInterceptor());

//添加一个事务控制拦截器
CommandInterceptor transactionInterceptor = createTransactionInterceptor();
if (transactionInterceptor != null) {
interceptors.add(transactionInterceptor);
}
//CommandContext拦截器,进行命令的保存
interceptors.add(new CommandContextInterceptor(this.commandContextFactory, this));
return interceptors;
}


初始化命令执行器

protected void initCommandExecutor() {
if (this.commandExecutor == null) {
//初始化命令拦截器链,并返回第一个拦截器
CommandInterceptor first = initInterceptorChain(this.commandInterceptors);
//初始化命令执行器
this.commandExecutor = new CommandExecutorImpl(getDefaultCommandConfig(), first);
}
}


初始化命令拦截器链

protected CommandInterceptor initInterceptorChain(List<CommandInterceptor> chain) {
if ((chain == null) || (chain.isEmpty())) {
throw new ActivitiException(new StringBuilder().append("invalid command interceptor chain configuration: ")
.append(chain).toString());
}
//构建拦截器链,即上一个拦截器中存放着下一个拦截器
for (int i = 0; i < chain.size() - 1; ++i) {
((CommandInterceptor) chain.get(i)).setNext((CommandInterceptor) chain.get(i + 1));
}
return ((CommandInterceptor) chain.get(0));
}


在执行拦截器链执行的关键代码,它会调用下一个CommandInterceptor的execute方法。

this.next.execute(config, command)


最后会调用CommandInvoker的execute方法,执行真正的命令,完成整个命令的周期

public class CommandInvoker extends AbstractCommandInterceptor {
public <T> T execute(CommandConfig config, Command<T> command) {
return command.execute(Context.getCommandContext());
}
...
}


我们以启动流程命令为例,探讨RuntimeService如何进行命令的执行。

public class RuntimeServiceImpl extends ServiceImpl implements RuntimeService {
public ProcessInstance startProcessInstanceByKey(String processDefinitionKey) {
return ((ProcessInstance) this.commandExecutor
.execute(new StartProcessInstanceCmd(processDefinitionKey, null, null, null)));

af50
}
....
}


值得注意的是commandExecutor是如何注入RuntimeService的呢。

在RuntimeServiceImpl 的基类ServiceImpl 存在commandExecutor属性。

我们在ProcessEngineConfigurationImpl的 init()方法中可以看出,在初始化命令执行器后,进行了服务的初始化,而RuntimeService在其中。

protected void init() {
...
initCommandExecutors();
initServices();
...
}


服务的初始化

protected void initServices() {
...
initService(this.runtimeService);
...
}


Runtime服务的初始化,将命令执行器set进runtimeService中

protected void initService(Object service) {
if (service instanceof ServiceImpl)
((ServiceImpl) service).setCommandExecutor(this.commandExecutor);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息