- 浏览: 194809 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
官人与夫人:
我的也是,看完特地登陆来,赞一个!
SpringMVC JPA 事务,数据库保存操作没有异常但数据保存不成功 -
悲伤的小脑:
这个少了 种情况吧。就是一个时间段完全包含另外一个时间段,这应 ...
java 判断两个时间段是否有交集 -
nilm61:
vip3652204732 写道为什么会报NULL错误,路径是 ...
java调用ffmpeg获取视频信息函数代码 -
vip3652204732:
为什么会报NULL错误,
路径是对的啊。
68行报NULL错误 ...
java调用ffmpeg获取视频信息函数代码 -
liuxuejin:
好!真需要
java调用ffmpeg获取视频信息函数代码
众所周知,从以前的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的关闭,里头干了不少事情啊
// 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
发表评论
-
Liferay中的Portlet事件通信
2013-12-31 09:46 776Liferay中的Portlet事件通信在有的项目开发中是需 ... -
Spring+ quartz 之 多任务动态定时(任务中起任务)
2013-09-12 15:58 2373参见上一篇Spring+ quartz 多任务定时 执 ... -
Spring+ quartz 多任务定时 执行 与cronExpression表达式
2013-09-12 15:04 1096在JavaEE系统中,我们会经常用到定时任务, ... -
linux中更改java版本
2013-09-05 15:43 819一. 解压安装jdk 在shell终端下进入jdk-6u14 ... -
nginx+tomcat文件下载不完整
2013-08-05 18:56 1705直接访问tomcat可以正常下载文件 访问前端 ... -
linux配置java环境变量(详细)
2013-07-01 18:58 684一. 解压安装jdk 在shell ... -
查找Maven 依赖
2013-04-22 12:48 995用了Maven,所需的JAR包就不能再像往常一样, ... -
SpringMVC JPA 事务,数据库保存操作没有异常但数据保存不成功
2013-03-11 19:45 3386SpringMVC JPA 事务,数据库保存操作没有异常 ... -
svn错误 svn:Checksum mismatch while updating
2012-12-10 10:48 1999行svn update出错: svn: Checksum ... -
Liferay 验证码动态刷新
2012-07-23 19:11 13801.使用liferay标签生成 验证码的url < ... -
使用Ant编译大量java文件时出java.lang.OutOfMemoryError
2012-07-13 10:26 962一般的出现java.lang.OutOfMemoryError ... -
liferay6.1 启用logj4j.properties定义日志
2012-07-02 14:57 1327在编译好的环境下 即tomcat/webapp/ROOT/WE ... -
liferay6.1 环境搭建遇到点问题
2012-06-13 18:07 1088执行 ant all 出现问题 The enviro ... -
liferay 未了解的领域
2012-06-07 14:20 05.2中通过SharePoint协议与MS Office整合 ... -
mark liferay 表结构分析
2012-04-26 16:22 1349liferay中每个page(layout)的界面顺序是通过l ... -
几个liferay整合
2012-04-18 09:51 0Liferay integration with LDAP ... -
tomcat启动失败:Failed creating java jvm.dll
2012-03-23 11:59 1724在启动tomcat6时失败,错误信息是: [2011 ... -
Liunx/Solaris/Windows下修改war配置文件
2012-03-03 18:05 11341.将 .war 文件复制到临时目录。 写道 ... -
autoReconnect及查看和连接时间有关的系统变量与通常产生的异常
2012-03-03 11:40 2064MySQL官方不推荐使用autoReconnect=true, ... -
xpath
2012-01-14 16:53 0使用xpath获得父节点,并修改了父节点的属性的值之后,再去查 ...
相关推荐
赠送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 工作流官网包 ...3. wars 三个工程 (activiti5的activiti-explorer没有了,多了activiti-admin 和activiti-app) activiti-admin的用户名密码:admin/admin activiti-app的用户名密码:admin/test
赠送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。这个工具为用户提供了一个直观的界面,以便于设计、部署和管理业务流程。 首先,让我们深入了解一下 ...
在深入探讨activiti-explorer-eclipse项目之前,我们先了解一下Activiti的核心特性: 1. BPMN 2.0 支持:Activiti完全遵循BPMN 2.0标准,使得业务流程建模变得简单且具有广泛接受度。 2. 强大的图形化设计工具:通过...
赠送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-...
赠送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-...
默认使用的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.0的压缩包文件,通常包含了该版本的所有源码、库文件、文档和示例。 在Activiti 5.22.0中,主要包含以下几个关键知识点: 1. **Activiti...
赠送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-...
赠送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-...
赠送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的应用程序界面提供了完整的中文本地化支持,使得国内用户在使用过程中能够更加方便地理解和操作。 在 Activiti 的应用中,汉化包的重要性不言而喻。对于非英语背景...
activiti-spring-boot-starter-basic-6.0.0适配springboot2.1.2
activiti-bpmn-converter-5.18.0-sources.jar
activiti-spring-boot-starter-7.1.0.M1
activiti-app6.0汉化版,对界面进行汉化,流程设计器里的英文无法汉化,没有对应的国际化文件
赠送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-...
5. **文件结构**:"activiti-app6.0中文版"很可能包含了一系列的文件和目录,比如HTML、CSS、JavaScript、图片以及配置文件等,这些文件共同构成了Activiti App的Web应用。用户可能需要对Web应用的基础架构有所了解...
赠送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依赖信息文件:...