什么是命令模式?
大都很熟悉的设计模式,此问题不在本文介绍范围内。
activiti中的命令模式
activiti使用命令模式作为基础开发模型。把每个操作都封装为一个命令,降低代码的耦合度,避免臃肿的大类的出现。
activiti是怎样运用的命令模式?
相信看activiti手册的都会看到这张图:
这张图描述了ProcessEngine与XXXservice的关系。而XXXService提供了执行流程的所有方法。XXXService的每个方法都执行对应一个cmd。
如启动流程方法:
RuntimeServiceImpl.startProcessInstanceByKey
public ProcessInstance startProcessInstanceByKey(String processDefinitionKey, String businessKey, Map<String, Object> variables) {
return commandExecutor.execute(new StartProcessInstanceCmd<ProcessInstance>(processDefinitionKey, null, businessKey, variables));
}
StartProcessInstanceCmd:就为启动流程的命令,里面为启动流程的相关逻辑代码。
上面是执行的典型例子,下面看是如何执行的Cmd呢?
先看XXXService的结构
commandExecutor:从名字可以看出,命令执行器,它提供一个执行命令的方法execute。
不难看出,commandExecutor是命令执行的关键。
看CommnadExecutor的结构图:
下面将从命令环境的初始化到命令执行完的整个过程看看。
以与Spring结合为例
1。初始化命令执行环境:
在ProcessEngineConfigurationImpl的初始化方法中初始化命令执行环境:
protected void init() {
initHistoryLevel();
initExpressionManager();
initVariableTypes();
initBeans();
initFormEngines();
initFormTypes();
initScriptingEngines();
initBusinessCalendarManager();
initCommandContextFactory();
initTransactionContextFactory();
initCommandExecutors();
initServices();
initIdGenerator();
initDeployers();
initJobExecutor();
initMailScanner();
initDataSource();
initTransactionFactory();
initSqlSessionFactory();
initSessionFactories();
initJpa();
initDelegateInterceptor();
initEventHandlers();
}
protected void initCommandExecutors() {
initActualCommandExecutor();
initCommandInterceptorsTxRequired();
initCommandExecutorTxRequired();
initCommandInterceptorsTxRequiresNew();
initCommandExecutorTxRequiresNew();
}
a. 初始化CommandExecutorImpl
protected void initActualCommandExecutor() {
actualCommandExecutor = new CommandExecutorImpl();
}
protected void initCommandInterceptorsTxRequired() {
if (commandInterceptorsTxRequired==null) {
if (customPreCommandInterceptorsTxRequired!=null) {
commandInterceptorsTxRequired = new ArrayList<CommandInterceptor>(customPreCommandInterceptorsTxRequired);
} else {
commandInterceptorsTxRequired = new ArrayList<CommandInterceptor>();
}
commandInterceptorsTxRequired.addAll(getDefaultCommandInterceptorsTxRequired());
if (customPostCommandInterceptorsTxRequired!=null) {
commandInterceptorsTxRequired.addAll(customPostCommandInterceptorsTxRequired);
}
commandInterceptorsTxRequired.add(actualCommandExecutor);
}
}
看SpringProcessEngineConfiguration实现了ProcessEngineConfigurationImpl的getDefaultCommandInterceptorsTxRequired
将LogInterceptor、SpringTransactionInterceptor和CommandContextInterceptor都添加到命令列表中
protected Collection< ? extends CommandInterceptor> getDefaultCommandInterceptorsTxRequired() {
if (transactionManager==null) {
throw new ActivitiException("transactionManager is required property for SpringProcessEngineConfiguration, use "+StandaloneProcessEngineConfiguration.class.getName()+" otherwise");
}
List<CommandInterceptor> defaultCommandInterceptorsTxRequired = new ArrayList<CommandInterceptor>();
defaultCommandInterceptorsTxRequired.add(new LogInterceptor());
defaultCommandInterceptorsTxRequired.add(new SpringTransactionInterceptor(transactionManager, TransactionTemplate.PROPAGATION_REQUIRED));
CommandContextInterceptor commandContextInterceptor = new CommandContextInterceptor(commandContextFactory, this);
defaultCommandInterceptorsTxRequired.add(commandContextInterceptor);
return defaultCommandInterceptorsTxRequired;
}
依次设置拦截器的下一个拦截器是谁,在执行的过程中,按顺序执行的拦截器。这里将LogInterceptor作为第一个拦截器。
protected void initCommandExecutorTxRequired() {
if (commandExecutorTxRequired==null) {
commandExecutorTxRequired = initInterceptorChain(commandInterceptorsTxRequired);
}
}
protected 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);
}
从以上代码可以看出,一共添加了四个拦截器,分别为:LogInterceptor、SpringTransactionInterceptor、CommandContextInterceptor和CommandExecutorImpl
protected void initCommandInterceptorsTxRequiresNew() {
if (commandInterceptorsTxRequiresNew==null) {
if (customPreCommandInterceptorsTxRequiresNew!=null) {
commandInterceptorsTxRequiresNew = new ArrayList<CommandInterceptor>(customPreCommandInterceptorsTxRequiresNew);
} else {
commandInterceptorsTxRequiresNew = new ArrayList<CommandInterceptor>();
}
commandInterceptorsTxRequiresNew.addAll(getDefaultCommandInterceptorsTxRequiresNew());
if (customPostCommandInterceptorsTxRequiresNew!=null) {
commandInterceptorsTxRequiresNew.addAll(customPostCommandInterceptorsTxRequiresNew);
}
commandInterceptorsTxRequiresNew.add(actualCommandExecutor);
}
}
protected void initCommandExecutorTxRequiresNew() {
if (commandExecutorTxRequiresNew==null) {
commandExecutorTxRequiresNew = initInterceptorChain(commandInterceptorsTxRequiresNew);
}
}
2.初始化Services,将CommandExecutor对象赋值给Service,这里的CommandExecutor为LogInterceptor。
protected void initServices() {
initService(repositoryService);
initService(runtimeService);
initService(historyService);
initService(identityService);
initService(taskService);
initService(formService);
initService(managementService);
}
protected void initService(Object service) {
if (service instanceof ServiceImpl) {
((ServiceImpl)service).setCommandExecutor(commandExecutorTxRequired);
}
}
3.以启动流程为例,看Command的执行过程
a.调用RuntimeServcie的启动流程方法:
public ProcessInstance startProcessInstanceByKey(String processDefinitionKey, Map<String, Object> variables) {
return commandExecutor.execute(new StartProcessInstanceCmd<ProcessInstance>(processDefinitionKey, null, null, variables));
}
b.从上面初始化过程可知,此时的commandExecutor为LogInterceptor,即执行LogInterceptor的execute方法
public <T> T execute(Command<T> command) {
log.fine(" ");
log.fine("--- starting " + ClassNameUtil.getClassNameWithoutPackage(command) + " --------------------------------------------------------");
try {
return next.execute(command);
} finally {
log.fine("--- " + ClassNameUtil.getClassNameWithoutPackage(command) + " finished --------------------------------------------------------");
log.fine(" ");
}
}
c.从上面初始化过程可知,LogInterceptor的next为SpringTransactionInterceptor,即执行SpringTransactionInterceptor的execute方法(SpringTransactionInterceptor的作用是进行事务管理)
public class SpringTransactionInterceptor extends CommandInterceptor {
protected PlatformTransactionManager transactionManager;
protected int transactionPropagation;
public SpringTransactionInterceptor(PlatformTransactionManager transactionManager, int transactionPropagation) {
this.transactionManager = transactionManager;
this.transactionPropagation = transactionPropagation;
}
@SuppressWarnings("unchecked")
public <T> T execute(final Command<T> command) {
TransactionTemplate transactionTemplate = new TransactionTemplate(transactionManager);
transactionTemplate.setPropagationBehavior(transactionPropagation);
T result = (T) transactionTemplate.execute(new TransactionCallback() {
public Object doInTransaction(TransactionStatus status) {
return next.execute(command);
}
});
return result;
}
}
d.从上面的初始化过程可知,SpringTransactionInterceptor的next为CommandContextInterceptor,这个CommnadContextInterceptor很关键,系统中的命令上下文就是在这里初始化并传入到Cmd的。命令上下文保存了Cmd执行时不可缺少的如持久化需要的session等重要的对象。非常重要。
public <T> T execute(Command<T> command) {
CommandContext context = commandContextFactory.createCommandContext(command);
try {
Context.setCommandContext(context);
Context.setProcessEngineConfiguration(processEngineConfiguration);
return next.execute(command);
} catch (Exception e) {
context.exception(e);
} finally {
try {
context.close();
} finally {
Context.removeCommandContext();
Context.removeProcessEngineConfiguration();
}
}
return null;
}
e.从上面的初始化过程可知,CommandContextInterceptor的next为CommnadExecutorImpl
public class CommandExecutorImpl extends CommandInterceptor {
public <T> T execute(Command<T> command) {
return command.execute(Context.getCommandContext());
}
}
e.执行cmd的execute方法
此时执行完毕。