首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 其他教程 > 开源软件 >

activiti-五 核心之CommandContext 转

2013-11-08 
activiti-5 核心之CommandContext转?众所周知,从以前的jbpm到现今的activiti,流程引擎的内部执行模式是com

activiti-5 核心之CommandContext 转

?众所周知,从以前的jbpm到现今的activiti,流程引擎的内部执行模式是command模式,不管是启动流程,

?还是推动流程等等,
?
?都采用了command的execute方法。
?
?而command执行依赖于CommandContext,直译就是command的上下文,那么,
?
?我们就来看看CommandContext里面的内容。

?首先是CommandContext本身的类变量和实例变量:

?

private static Logger log = Logger.getLogger(CommandContext.class.getName());private static final ThreadLocal<Stack<CommandContext>> txContextStacks = new ThreadLocal<Stack<CommandContext>>();protected Command< ? > command;protected TransactionContext transactionContext;protected Map<Class< ? >, Session> sessions = new HashMap<Class< ? >, Session>();protected Throwable exception = null;protected ProcessEngineConfigurationImpl processEngineConfiguration;

?

?

?其实从这个变量声明,我们就能够大致看出CommandContext的管辖范围,
?
?首先是提供线程安全的副本栈txContextStacks,然后是在当前上下文执行的command,
?
?事务上下文transactionContext,会话集合sessions ,流程引擎配置类processEngineConfiguration,
?
?至于log和exception肯定就不用说了。当然,实际来说,transactionContext其实只是为session管理服务的,稍后可见。

?为了避免线程冲突,每个command都在一个独立的commandContext中执行,如下:

?

?

  public static void setCurrentCommandContext(CommandContext commandContext) {    getContextStack(true).push(commandContext);  }   public static void removeCurrentCommandContext() {    getContextStack(true).pop();  }   public static CommandContext getCurrent() {    Stack<CommandContext> contextStack = getContextStack(false);    if ((contextStack == null) || (contextStack.isEmpty())) {      return null;    }    return contextStack.peek();//在非出栈情况下获取栈顶的CommandContext  }   private static Stack<CommandContext> getContextStack(boolean isInitializationRequired) {    Stack<CommandContext> txContextStack = txContextStacks.get();//获取当前线程一个栈变量副本    if (txContextStack == null && isInitializationRequired) {//初始化栈      txContextStack = new Stack<CommandContext>();      txContextStacks.set(txContextStack);    }    return txContextStack;  }

?

?

?

?看到这里,大家可能会产生一个疑问,ThreadLocal为啥限定类型为Stack,而不是Map之类的Collection呢?
?
?其实,在了解了command的执行过程后,就不会有这个问题了。

?一个command在生成之后交由CommandExecutor执行时,要经过一个CommandInterceptor,
?
?这个拦截器做了什么呢?它会使用一个CommandContextFactory为这个command生成
?
?【commandContextFactory.createCommandContext(command)】并指定【CommandContext.setCurrentCommandContext(context)】
?
?一个CommandContext,然后CommandExecutor执行command,执行完毕后,
?
?CommandInterceptor再将指定的CommandContext关闭【context.close()】并移除【CommandContext.removeCurrentCommandContext()】。
?
?在这个过程中我们可以看到,CommandContext的生成和移除正好对应了入栈和出栈,简单来说,就是
?
?创建CommandContext--执行command--移除CommandContext 这样一个过程,
?
?这个生命周期用栈来管理正是天作之合,如果用collection,势必增加不必要的开销且别扭。

?下面看看CommandContext的关闭,里头干了不少事情啊?

?


}

}

}

?

?如上可见,command执行完毕后的会话、事务和异常都在这儿统一管理了。

?

?之后就是通过map获取会话的一堆代码了:

写道
public <T> T getSession(Class<T> sessionClass) {

Session session = sessions.get(sessionClass);

if (session == null) {

SessionFactory sessionFactory = processEngineConfiguration.getSessionFactories().get(sessionClass);

if (sessionFactory==null) {

throw new ActivitiException("no session factory configured for "+sessionClass.getName());

}

session = sessionFactory.openSession();

sessions.put(sessionClass, session);

}



return (T) session;

}



public RepositorySession getRepositorySession() {

return getSession(RepositorySession.class);

}

public RuntimeSession getRuntimeSession() {

return getSession(RuntimeSession.class);

}

public IdentitySession getIdentitySession() {

return getSession(IdentitySession.class);

}

public MessageSession getMessageSession() {

return getSession(MessageSession.class);

}

public TimerSession getTimerSession() {

return getSession(TimerSession.class);

}

public TaskSession getTaskSession() {

return getSession(TaskSession.class);

}

public HistorySession getHistorySession() {

return getSession(HistorySession.class);

}

public ManagementSession getManagementSession() {

return getSession(ManagementSession.class);

}

public DbSqlSession getDbSqlSession() {

return getSession(DbSqlSession.class);

}

?

?得说一下,这一坨东西看上去真丑陋,不过考虑到这块估计也没什么扩展和改动了,就这样吧。

?

?

原文:http://blog.csdn.net/songry/article/details/5696624

?

www.ibuyincn.com

热点排行