`

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的关闭,里头干了不少事情啊 

 

写道
public void close() {

// the intention of this method is that all resources are closed properly,

// even

// if exceptions occur in close or flush methods of the sessions or the

// transaction context.



try {

try {

try {



if (exception == null) {

flushSessions();//会话提交

}



} catch (Throwable exception) {

exception(exception);

} finally {



try {

if (exception == null) {

transactionContext.commit();//事务提交

}

} catch (Throwable exception) {

exception(exception);

}



if (exception != null) {

log.log(Level.SEVERE, "Error while closing command context", exception);

transactionContext.rollback();//遇到异常事务回滚

}

}

} catch (Throwable exception) {

exception(exception);

} finally {

closeSessions();//关闭会话



}

} catch (Throwable exception) {

exception(exception);

}



// rethrow the original exception if there was one

if (exception != null) {

if (exception instanceof Error) {

throw (Error) exception;

} else if (exception instanceof RuntimeException) {

throw (RuntimeException) exception;

} else {

throw new ActivitiException("exception while executing command " + command, exception);

}

}

}

 

 如上可见,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

分享到:
评论

相关推荐

    activiti-engine-5.21.0-API文档-中文版.zip

    赠送jar包:activiti-engine-5.21.0.jar; 赠送原API文档:activiti-engine-5.21.0-javadoc.jar; 赠送源代码:activiti-engine-5.21.0-sources.jar; 赠送Maven依赖信息文件:activiti-engine-5.21.0.pom; 包含...

    activiti-6.0.0.zip

    activiti-6.0.0.zip 工作流官网包 ...3. wars 三个工程 (activiti5的activiti-explorer没有了,多了activiti-admin 和activiti-app) activiti-admin的用户名密码:admin/admin activiti-app的用户名密码:admin/test

    activiti-json-converter-5.21.0-API文档-中英对照版.zip

    赠送jar包:activiti-json-converter-5.21.0.jar; 赠送原API文档:activiti-json-converter-5.21.0-javadoc.jar; 赠送源代码:activiti-json-converter-5.21.0-sources.jar; 赠送Maven依赖信息文件:activiti-...

    activiti-5.22.0官方版本 用于activiti-explorer.zip

    在这个特定的版本——activiti-5.22.0,我们关注的是一个用于流程设计的官方工具,即 activiti-explorer。这个工具为用户提供了一个直观的界面,以便于设计、部署和管理业务流程。 首先,让我们深入了解一下 ...

    activiti-explorer-eclipse项目

    在深入探讨activiti-explorer-eclipse项目之前,我们先了解一下Activiti的核心特性: 1. BPMN 2.0 支持:Activiti完全遵循BPMN 2.0标准,使得业务流程建模变得简单且具有广泛接受度。 2. 强大的图形化设计工具:通过...

    activiti-image-generator-5.21.0-API文档-中文版.zip

    赠送jar包:activiti-image-generator-5.21.0.jar; 赠送原API文档:activiti-image-generator-5.21.0-javadoc.jar; 赠送源代码:activiti-image-generator-5.21.0-sources.jar; 赠送Maven依赖信息文件:activiti-...

    activiti-json-converter-5.21.0-API文档-中文版.zip

    赠送jar包:activiti-json-converter-5.21.0.jar; 赠送原API文档:activiti-json-converter-5.21.0-javadoc.jar; 赠送源代码:activiti-json-converter-5.21.0-sources.jar; 赠送Maven依赖信息文件:activiti-...

    activiti-app6-汉化.zip

    默认使用的H2,如果要使用mysql等其它数据库需要修改activiti-app\WEB-INF\classes\META-INF\activiti-app包下的activiti-app.properties文件。如果数据库连接失败可以需要更新数据库驱动包,activiti-app\WEB-INF\...

    activiti-5.22.0zip下载

    标题中的 "activiti-5.22.0zip下载" 指的是Activiti的一个特定版本——5.22.0的压缩包文件,通常包含了该版本的所有源码、库文件、文档和示例。 在Activiti 5.22.0中,主要包含以下几个关键知识点: 1. **Activiti...

    activiti-common-rest-5.21.0-API文档-中英对照版.zip

    赠送jar包:activiti-common-rest-5.21.0.jar; 赠送原API文档:activiti-common-rest-5.21.0-javadoc.jar; 赠送源代码:activiti-common-rest-5.21.0-sources.jar; 赠送Maven依赖信息文件:activiti-common-rest-...

    activiti-image-generator-5.21.0-API文档-中英对照版.zip

    赠送jar包:activiti-image-generator-5.21.0.jar; 赠送原API文档:activiti-image-generator-5.21.0-javadoc.jar; 赠送源代码:activiti-image-generator-5.21.0-sources.jar; 赠送Maven依赖信息文件:activiti-...

    activiti-bpmn-model-5.21.0-API文档-中文版.zip

    赠送jar包:activiti-bpmn-model-5.21.0.jar; 赠送原API文档:activiti-bpmn-model-5.21.0-javadoc.jar; 赠送源代码:activiti-bpmn-model-5.21.0-sources.jar; 赠送Maven依赖信息文件:activiti-bpmn-model-...

    Activiti-APP最全汉化包

    这个“Activiti-APP最全汉化包”是专门为Activiti的应用程序界面提供了完整的中文本地化支持,使得国内用户在使用过程中能够更加方便地理解和操作。 在 Activiti 的应用中,汉化包的重要性不言而喻。对于非英语背景...

    activiti-spring-boot-starter-basic-6.0.0适配springboot2.1.2

    activiti-spring-boot-starter-basic-6.0.0适配springboot2.1.2

    activiti-bpmn-converter-5.18.0-sources.jar

    activiti-bpmn-converter-5.18.0-sources.jar

    activiti-spring-boot-starter-7.1.0.M1.jar

    activiti-spring-boot-starter-7.1.0.M1

    activiti-app6.0汉化版

    activiti-app6.0汉化版,对界面进行汉化,流程设计器里的英文无法汉化,没有对应的国际化文件

    activiti-crystalball-5.21.0-API文档-中文版.zip

    赠送jar包:activiti-crystalball-5.21.0.jar; 赠送原API文档:activiti-crystalball-5.21.0-javadoc.jar; 赠送源代码:activiti-crystalball-5.21.0-sources.jar; 赠送Maven依赖信息文件:activiti-crystalball-...

    activiti-app6.0中文版.zip

    5. **文件结构**:"activiti-app6.0中文版"很可能包含了一系列的文件和目录,比如HTML、CSS、JavaScript、图片以及配置文件等,这些文件共同构成了Activiti App的Web应用。用户可能需要对Web应用的基础架构有所了解...

    activiti-process-validation-5.21.0-API文档-中文版.zip

    赠送jar包:activiti-process-validation-5.21.0.jar; 赠送原API文档:activiti-process-validation-5.21.0-javadoc.jar; 赠送源代码:activiti-process-validation-5.21.0-sources.jar; 赠送Maven依赖信息文件:...

Global site tag (gtag.js) - Google Analytics