- 浏览: 640306 次
- 性别:
- 来自: 北京
最新评论
-
2047699523:
java hibernate demo使用实例教程源代码下载: ...
hibernate延迟加载的原理与实现 -
在世界的中心呼喚愛:
hantsy 写道这种lazy的解释只对了一半,按java p ...
hibernate延迟加载的原理与实现 -
moguicy:
看了下时间,不是楼主是否还在开发
【翻译】Wicket启示录——理论与实践(一) -
xfan0828:
"最后但并不是最不重要的一点就是" BZ, ...
【翻译】深入浅出 EJB3.1(上) -
doudou87323:
十分感谢,正在学习中,受益匪浅
【翻译】深入浅出 EJB3.1(上)
Global JNDI names( 统一的 全局 JNDI 命名 )
该特性已经渴望很久了,终于在 EJB 3.1 中得以实现。原来 EJB 的全局 JNDI 命名方式都是供应商各自的实现版本,在布署的时候有很多问题。同一个应用程序中的那些 session beans 在不同供应商的容器中很可能 JNDI 命名就不同,造成客户端的调用代码必须得调整修改。除此之外,支持 EJB3 的某些供应商将允许将本地业务接口配置在全局的 JDNI 中,而另一些供应商却将此特性排队在外,这也导致了兼容性问题。
规范定义了全局 JNDI 命名方式,采用统一的方式来获取注册的 session beans 。也就是说,我们终于可以使用兼容性的 JNDI 命名了。
每个兼容的全局 JNDI 命名都有如下语法规则:
java:global[/<app-name>]/<module-name>/<bean-name>[!<fully-qualified-interface-name>]
下面的表格是对不同的元素的解释:
名称 |
描述 |
必选 |
app-name |
应用程序的名称。如果没有在 application.xml 中指定,则默认的名称就是 EAR 的打包名称。
|
否 |
module-name |
模块的名称。如果没有在 ejb-jar.xml 中指定,则默认的名称就是 bundle 文件名
|
是 |
bean-name |
Bean 的名称。如果没有使用标注 @Stateless , @Stateful , @Singleton 或其它布署描述符,则默认的名称就是该 session bean 的类的完全限定名称。
|
是 |
Fully-qualified-interface-name |
暴露接口的限定名称。如果是一个 no-interface view ,则它的值为应该 bean 类的完全限定名称。
|
是 |
如果一个 bean 只想对客户端暴露一个对外接口,那么容器不公必须保证该 bean 在 JNDI 命名中是可用的,而且必须采用以下格式:
java:global[/<app-name>]/<module-name>/<bean-name>
为了简化 JDNI 的使用,容器分别也提供了 java:app 和 java:module 两种命名方式:
java:app[/<module-name>]/<bean-name>[!<fully-qualified-interface-name>]
java:module/<bean-name>[!<fully-qualified-interface-name>]
示例 1:
package com.pt.xyz; @Singleton public class BeanA { (...) }
Bean A 可以通过下面合法的 JNDI 命名来取得这个可用的 no-interface view :
- java:global/myapp/mybeans/BeanA
- ava:global/myapp/mybeans/BeanA!com.pt.xyz.BeanA
- java:app/mybeans/BeanA
- java:app/mybeans/BeanA!com.pt.xyz.BeanA
- java:module/BeanA
- java:module/BeanA!com.pt.xyz.BeanA
示例 2:
将下列代码打包到 mybeans.jar 中,但不放在任何 ear 包中。同样,我们没有使用任何布署描述符:
package com.pt.xyz; @Stateless(name="MyBeanB") public class BeanB implements BLocal, BRemote { (...) } package com.pt.xyz; @Local public interface BLocal { (...) } package com.pt.abc; @Remote public interface BRemote { (...) }
Blocal 接口可以通过以下 JNDI 命名获得:
- java:global/mybeans/MyBeanB!com.pt.xyz.BLocal
- java:app/MyBeanB!com.pt.xyz.BLocal
- java:module/MyBeanB!com.pt.xyz.Blocal
BRemote 接口可以通过以下 JNDI 命名获得:
- java:global/mybeans/MyBeanB!com.pt.abc.BRemote
- java:app/MyBeanB!com.pt.abc.BRemote
- java:module/MyBeanB!com.pt.abc.BRemote
Timer-Service( 调度服务 )
有相当一部分企业应用程序或多或少的有“ 时间驱动 ( time-driven ) ”的需求。长久以来, EJB 规范却一直忽略了这一点,于是开发人员被迫去采纳非标准的解决方案—— Quartz 或 Flux 。早在 EJB2.1 时就引入了 Timer Service ,容器提供 Timer 服务,允许 EJBs 在特定情况下使用 timer 回调从而实现任务调度。除外之外,任务调度还可以在事务上下文中完成。
虽然大家都知道 Timer 服务对某些应用是非常重要的环节,但 EJB 的专家组们考虑的非常有限,比如:
- 所有的 timer 必须编程式的创建。
- 在定制调度任务时,缺乏灵活性
- 不支持多个 JVM 的应用场合,也就是说不支持集群等。
到 EJB3.1 版本时,有两种方式来创建 timer :
- 编程式:使用现有的 TimerService 接口,并且为了更加灵活的创建 timer ,对原有接口有了很大的改进和提高。
- 声明式:使用 annotation 或布署描述符号来实现。采用这种方式的话, timer 就以静态的形式定义在应用程序中,然后在应用程序启动时,自动创建。
@Schedule 可用于自动创建一个 timer ,里面可以加入参数来限制调度时间。当一个方法被标注 @Schedule 后,到时间了就会自动被容器回调。如果采用编程式来创建 timer ,对一个 bean 来说,在哪个方法中调用 timer 都无所谓 ( 原文没有给出编程式的例子,我在网上找了一个 ) 。 如果是声明式的创建方式,只局限于被 @Schedule 标注过的方法才可以任务调度。 在接下来的两个 timer 例子中,一个定义了每周一的午夜开始调度;另一个其是每个月的最后一天开始调度。注意看 itIsMonday 和 itIsEndOfMonth 上面的 annotation :
//编程式的例子,timer在方法里创建,而哪个方法都可以执行调度 public String getHello(){ TimerService ts = sessionContext.getTimerService(); ts.createTimer(new Date(..), 10000, null); } //声明式的话,在应用程序启动的时候,就必须被创建完成,因而只有使用@Stateless 的方法才能执行调度。 @Stateless public class TimerEJB { @Schedule(dayOfWeek="Mon") public void itIsMonday(Timer timer) { (...) } @Schedule(dayOfMonth="Last") public void itIsEndOfMonth(Timer timer) { (...) } }
现在无论是声明式还是编程式都可以持久化(默认选项 )或非持久化。非持久化的 timer 在应用程序关闭或容器宕机时,并不会存活下来。可以使用 annotation 的持久化属性来实现持久化需求。对于编程式的话,可以将 TimerConfig 对象作为参数传递给 TimerService 接口的 createTimer 方法。 Timer 接口提供了新的 isPersistent 方法,判断是否允许持久化。
每个被持久化的 timer 相当于一个单独的 timer ,在应用程序分布式布署时,也不用考虑 JVM 的数量。这对集群的应用影响非常重大。现在我们假设一下这个场景,如何让一个应用程序更新一个现有的 timer 。在 EJB3.1 之前,如果是布署在单个 JVM 的应用程序中,很容易做到,直接替换即可。但在在多个 JVM 的环境下,如果只是其中某个 JVM 的 timer 被创建或更新了,对其它 JVM 来说是不可见的,自然容易出很多奇怪的问题 。这就意味着必须采用某种策略允许现有的所有 timers 对所有的 JVM 都是可见的。每次在出问题后,才知道是布署的应用程序不一致或其它低级错误造成的,这是一种非常差的实践方式。到 EJB3.1 时,开发人员再也不用关心布署时的跨 JVM 问题,这个工作留给容器去实现。
一个自动创建的非持久化 timer 在每次跨越 JVM 时,会在每个 JVM 中创建一个新的 timer 实例。
Timeout 的回调方法有两个可选的重载函数: void <METHOD> (Timer timer) 和 void <METHOD> () 。
对于定时调度而言,有了很大的改进。表达式采用了模仿 UNIX cron 的日历语法格式。有 8 个主要属性可以按照下列的规则使用:
属性 |
属性值 |
示例 |
second |
[0, 59] |
second = "10" |
minute |
[0, 59] |
minute = "30" |
hour |
[0, 23] |
hour = "10" |
dayOfMonth |
- [1, 31] - day of the month - Last - last day of the month - -[1, 7] - number of days before end of month - {"1st", "2nd", "3rd", "4th", "5th", ..., "Last"} {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}- identifies a single occurrence of a day of the month |
dayOfMonth = "3" dayOfMonth = "Last" dayOfMonth = "-5" dayOfMonth = "1st Tue" |
month |
- [1, 12] - month of the year - {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}- month name |
month = "7" month = "Jan" |
dayOfWeek |
- [0, 7]- day of the week where both 0 and 7 refer to Sunday - {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}- day's name |
dayOfWeek = "5"
dayOfWeek = "Wed" |
year |
Four digit calendar year |
year = "1978" |
timezone |
Id of the related timezone |
timezone = "America/New_York" |
每个属性值还有不同形式:
表达式类型 |
描述 |
示例 |
Single Value |
限制属性只有一个值 |
dayOfWeek = "Wed" |
Wild Card |
对于给定的属性,允许任意合法值 |
month = "*" |
List |
限制属性允许两个或两个以上的值,中间用逗号隔开 |
DayOfMonth = "3,10,23" dayOfWeek = "Wed,Sun" |
Range |
限制属性在一个封闭的区间段内 |
year = "1978-1984" |
Increments |
定义一个 x/y 的表达式。限制属性在每 y 秒调度一次,并且在 x 时开始。 |
second = "*/10" - every 10 seconds hour = "12/2"- every second hour starting at noon |
再来多看一些示例吧:
每周二上午 7:30 开始调度:
@Schedule(hour = "7", minute = "30", dayOfWeek = "Tue")
每周从周一到周五的, 7 点, 15 点, 20 点开始调度:
@Schedule(hour = "7, 15, 20", dayOfWeek = "Mon-Fri")
每周日的每个小时调度一次:
@Schedule(hour = "*", dayOfWeek = "0")
Last Friday of December, at 12
每年 12 月的最后一个周五 12 时调用一次:
@Schedule(hour = "12", dayOfMonth = "Last Fri", month="Dec")
2009 年每个月的最后三天的 20 点开始调用:
@Schedule(hour = "20", dayOfMonth = "-3", year="2009")
从下午三点开始,每个小时的第 5 分钟开始调用:
@Schedule(minute = "*/5", hour = "15/1")
TimerService 接口对编程式也进行了增强,可以使用类似于 cron 的表达式。这些表达式可以看作是 ScheduleExpression 类的实例,并在创建 timer 时,作为参数传递进去。
EJB Lite
EJB 必须按照规范去实现一系列 API 。从 EJB3.1 开始,这组 API 分成了两——最小配置和完整配置。最小配置就是 EJB3.1 Lite ,它的作为 EJB3.1 的子集基本足够应用程序的开发,没有必须实现整套 API 规范。这将带来很多好处:
提高了性能。削减大量 API ,为容器减了不少肥,自然变得更加轻快了,提供的服务也更加出色。
学习曲线降低。成为一名 EJB 开发人员可不是一件很简单的事,要求开发人员学习大量的知识。如果只是开发 EJB Lite 应用程序,开发人员就的学习曲线明显轻松很多,提高了生产率。
降低了开销。常常听到人们抱怨高昂的 EJB 容器价格,以及一大堆根本用不上的 API 。一个应用程序几乎没有用啥 stateless bean ,也根本用不着很多 EJB API 或特性,却还要承担这笔可观的费用。现在有了 EJB 完事版和 EJB Lite 版,供应商可以采用不同的许可费用,应用程序可以按需付费了。
EJB 3.1 Lite 包括下列特性:
- 支持 Stateless , Stateful 和 Singleton Session Beans ;只支持 local views 和 no-interface views ;只支持同步调用(不提供异步调用 )。
- 支持 Container-Managed Transactions 和 Bean-Managed Transactions 两种事务方式。
- 支持声明式和编程式的安全特性。
- 支持 Interceptors 。
- 支持布署描述符号
简化的 EJB 打包机制
ejb-jar 文件为 enterprise beans 的打包模块。在 EJB3.1 前,所有 Beans 都必须打包在该包下。那时考虑到的是所有 JavaEE 应用程序都由 web 前端和 EJB 后端组成,自然 ear 的目的就是分别将这两个模块 war 和 ejb-jar 打包成一个整体。将结构分为前端和后端感觉上是一个不错的最佳实践,但其实于于简单的应用程序来说反而难以忍受。
EJB 3.1 允许企业 enterprise beans 打包到 war 包中去。这些类可以放在 WEB-INF/classes 目录下,或者打成 jar 包扔到 WEB-INF/lib 中去。一个 war 包最多只能包含一个 ejb-jar.xml ,该文件可放在 WEB-INF/ejb.jar.xml 下,也可放在 WEB-INF/lib 某个 ejb-jar 中的 META-INF/ejb-jar.xml 下。
这种简化的打包方式必须是用在简单的应用程序布署环境中,如果你有更多的需求,还是切换回传统的 ear 包吧。
Embeddable EJB Containers (嵌入式的 EJB 容器)
传统意义上, EJB 总是同一大堆笨重的 Java EE 容器联系在一起,很难使用:
- 难于单元测试。
- 一个单独的批处理程序从 EJB 中捞不到闺半点好处,除非某个 JavaEE 容器真难提供批处理服务。
- EJB 的桌面管理控制台复杂难用。
EJB3.1 最具意义的特性之一就是提供了 embeddable container 。现在就连 JavaSE 客户端就可以在自己的 JVM 和 classloader ,实例化 EJB 容器。嵌入式的容器提供了一系列基本服务,允许客户端在享受 EJB 和同时,还不需要那些完整版的 JavaEE 容器。
embeddable container 会扫描 classpath 从而找到 EJB 模块。有两种方式来限定是否为 EJB 模块:
- 直接使用 ejb-jar 文件
- 有一个目录包含 META-INF/ejb-jar.xml 文件,或至少有一个类使用了 enterprise bean 标注。
同样一个 bean ,无论是跑在 embeddable container 还是标准的 Java EE 容器,都没有什么区别,也不要求你的代码做任何修改。这一点绝对保证是透明的。
embeddable container 原则上是应该至少实现 EJB 3.1 Lite 子集的。但仍然允许供应商去扩展 EJB3.1 其它更完整的功能。
EJBContainer 类在 embeddable container 中扮演了一个非常核心的角色。它的 static 方法 createEJBContainer 用于实例化一个新的容器;而当 close 方法调用时,先遍历所有 bean 的 PreDestroy 回调方法,最后关闭容器。 最后一项的要点是, getContext 方法用于返回一个 context ,然后客户端可以通过这个 context 将布署在 embeddable container 中的 session bean 都给 lookup 出来使用。
@Singleton @Startup public class ByeEJB { private Logger log; @PostConstruct public void initByeEJB() { log.info("ByeEJB is being initialized..."); (...) } public String sayBye() { log.info("ByeEJB is saying bye..."); return "Bye!"; } @PreDestroy public void destroyByeEJB() { log.info("ByeEJB is being destroyed..."); (...) } } public class Client { private Logger log; public static void main(String args[]) { log.info("Starting client..."); EJBContainer ec = EJBContainer.createEJBContainer(); log.info("Container created..."); Context ctx = ec.getContext(); //Gets the no-interface view ByeEJB byeEjb = ctx.lookup("java:global/bye/ByeEJB"); String msg = byeEjb.sayBye(); log.info("Got the following message: " + msg); ec.close(); log.info("Finishing client..."); } }
输出结果:
Log output
Starting client...
ByeEJB is being initialized...
Container created...
ByeEJB is saying bye...
Got the following message: Bye!
ByeEJB is being destroyed...
Finishing client...
接下来的热点
除了上述的新的特性外,还有一些细微的改进。比如说简化现有的功能。下面列出的就是相关话题:
- stateful 可以使用 @ AfterBegin , @ BeforeCompletion , @ AfterCompletion 标注来代替 SessionSynchronization 接口的实现。
- 可以对 stateful bean 设定一个 timeout ,来指示应该 stateful bean 从容器删除之前的存活时间。 @ StatefulTimeout 就可实现这样的效果。
- 对于 stateless 和 stateful beans 容器都有自己的并发调用机制。缺省情况下,允许并发访问 stateful beans ,具谁先谁后由容器自己决定。开发人员现在可以使用 @ConcurrencyManagement(CONCURRENCY_NOT_ALLOWED) 标注来指定 stateful bean 不支持并发访问。这样的话,同一个 stateful bean 每次只能处理一个客户端的请示。如果这个时候还有请求需要访问这个 bean 的时候,会就抛出 ConcurrentAccessException 异常。
- @ AroundTimeout 标注用于定义拦截方法 (interceptor method) 的超时时间。
结论
Java EE 即将发布最终版,上面提到的绝大多数特性非常接近最终版本。 2009 必将是 JavaEE 火爆的一年。
EJB 3.1 提供了更出色的架构,同时还为开发人员提供了更丰富的功能集,允许你去扩展现有设计和实现。这次发布的版本非常成熟完整,会使用 Java 服务端开发更加牢固。
由于技术总是在不断的自我完善,总难免会遗漏些更新的特性。计划是在下个版本推出下列特性:
- 支持对某个 bean 的实例个数的控制,即可以指定它的最少个数和最大个数。
- 提供应用程序的生命周期类,用于处理 pre-start, post-start, pre-stop 和 post-stop 四种应用程序状态。
- 增强 JMS ,增加一些流行的消息系统特性——消息群组和消息订单等。
- 支持 JAX-RS 。
我们应当庆幸专家为此而付出的极大努力,他们完成了一项高质量的工程。
关于作者
Paulo Moreira 是一个来自葡萄牙的职业软件工程师,目前供职于卢森堡的 Clearstream 银行。 Paulo Moreira 毕业于 葡萄牙米尼奥大学 ,拥有计算机科学和系统工程的硕士学位。他从 2001 年起,就一直从事于 java 服务端开发,涉及的领域主要有:通信,零售,软件和金融。
评论
发表评论
-
【翻译】深入浅出 EJB3.1(上)
2009-05-06 20:59 11181终于有空将EJB3.1的最新文章与大家分享,原文请看: ht ... -
【翻译】Java EE 6体系结构的变革
2009-02-09 10:01 4532又看到 Reza 同学为 -
【翻译】Java EE 6体系结构的变革(完)
2009-02-09 10:00 6479JSF 2.0 尽 ... -
垃圾收集器是一个“宝贝收藏家”?
2008-11-25 23:58 3084原文请看:http://java.dzone.com/ar ... -
深入理解JBoss Cache3.0——Naga
2008-11-12 09:12 9748原文请看: http://java.dzone.com/ ... -
【翻译】Rod Johnson——关于当选JCP执行委员会的之言片语
2008-11-03 10:42 3195SpringSource 在上月底被宣布被加入 JCP ... -
【翻译】EJB3.1真的来了吗?EJB3.1系列文章(五) 终章
2008-10-16 14:37 9255历时9 个多月的EJB3.1 系列文章终于要划上圆满的句 ... -
【翻译】Rod Johnson——平衡的质疑:Spring维护策略的再次调整(完)
2008-10-09 09:33 4085不管你承不承认,Spring实际上已经是实事上JAVA企业开 ... -
【云计算专家Joseph Ottinger系列】应用服务器本质论
2008-09-08 08:58 3483原文请看: http://www.t ... -
Spring破坏了JEE规范吗?
2008-09-02 13:33 4097[TTS 编辑注:这是 TTS 论坛上的原帖。我现在把它 ... -
【翻译】spring配置全书(下)——附PDF完整版下载
2008-07-14 12:30 10847JMS 命名空间简介 Schema URI ... -
【翻译】spring配置全书(上)
2008-07-07 23:11 8958作者简介: Craig Walls 是 Texa ... -
【翻译】EJB3.1真的来了吗?EJB3.1系列文章(四)
2008-06-18 23:10 38224前言 Raza 同学终于又出 EJB3.1 文章了 ... -
【翻译】Rod Johnson——Spring的宣言:开源,开放(完)
2008-06-10 16:51 5622前言 这是本文的第二部分,里面提到并回答许多Spring用 ... -
【翻译】Rod Johnson——Spring的宣言:开源,开放
2008-06-06 13:06 6124原文地址: http://blog.sp ... -
【翻译】EJB3.1真的来了吗?EJB3.1系列文章(三)
2008-05-01 13:53 8849文本继续和大家分享EJB3.1特性,今天谈到的EJB Lite ... -
【Danny hui】运用抽象工厂模式自己动手写一个IoC
2008-04-23 16:34 6364本文的作者Danny hui似乎是TTS上的新人,我从Goog ... -
【翻译】Wicket启示录——理论与实践(三)完
2008-04-11 01:09 6298接下来,我们再看看EditContact类,把新建联系人的话和 ... -
【翻译】Wicket启示录——理论与实践(二)
2008-04-09 23:47 5892第二部分 实践 Application(应用程序) 与 ... -
【翻译】Wicket启示录——理论与实践(一)
2008-04-09 23:15 6817序 Wicket,当多数人看到它时,也许又是带着惯性思考 “j ...
相关推荐
### EJB 3.1 深入浅出 #### 一、EJB 3.1 的背景与改进 **EJB(Enterprise Java Beans)**是Java Enterprise Edition(Java EE)平台上的服务端组件架构模型,它旨在快速并简化分布式、事务处理、安全性以及可移植...
总的来说,《EJB 3.1 Cookbook》这本书深入浅出地讲解了如何利用EJB 3.1版本来构建高效、可靠的企业级应用,是Java EE开发者的重要参考资料。通过阅读这本书,开发者可以掌握EJB的核心概念、设计模式以及最佳实践,...
《EJB 3.0从入门到精通》是一本针对企业级Java开发者的教程,它深入浅出地介绍了EJB(Enterprise JavaBeans)3.0规范。EJB是Java EE(Java Platform, Enterprise Edition)平台的核心组件之一,主要用于构建可扩展、...
2.13.2 BeanShell在jBPM中的用法........63 第 3 章 流程节点详解.....................................67 3.1 公共属性...................................................68 3.2 Node节点........................
### EJB3中文版知识点概览 #### 一、EJB3.0概念与环境配置 **1.1 ENTERPRISE JAVA BEANS (EJB)** Enterprise JavaBeans(EJB)是Java...通过实践和深入理解这些知识点,开发者可以构建出稳定、高效的企业级应用。
2.13.2 BeanShell在jBPM中的用法........63 第 3 章 流程节点详解.....................................67 3.1 公共属性...................................................68 3.2 Node节点........................
该书通过深入浅出的方式,引导读者掌握Java EE 6平台的核心概念和技术,同时利用GlassFish 3服务器进行实践。源代码提供了书中示例项目的实际实现,帮助读者更好地理解和应用所学知识。 1. **Java EE 6概述**:Java...
这本书深入浅出地讲解了Spring 3.x版本的各个方面,旨在帮助读者掌握如何利用Spring高效地构建Java EE应用程序。 首先,Spring框架的核心特性之一是依赖注入(Dependency Injection,DI),它使得组件之间的耦合度...
资源中提到的《Spring 3.0就这么简单》这本书,很可能是针对Spring 3.0这一版本深入浅出的教程,涵盖了Spring 3.0的主要特性和使用方法,适合初学者和有经验的开发者阅读,以更好地理解和利用Spring 3.0框架的能力。...
这本书深入浅出地介绍了如何利用Spring框架构建高质量的企业级应用。Spring框架是Java EE开发中的核心组件,它简化了依赖注入、事务管理、数据访问以及Web应用的开发工作。 在第三版中,作者Craig Walls详细阐述了...
《求精要诀——Java EE编程开发案例精讲》是一本深入浅出的教程,旨在帮助读者掌握Java EE(企业版)的编程技术。PPT形式的教程通常以清晰直观的方式呈现复杂的概念,便于学习和理解。这个压缩包包含了一系列章节的...
4. **EJB 3.1**:EJB(Enterprise JavaBeans)的最新版本,支持更高级的会话bean功能和消息驱动bean。 5. **JSF 2.0**:JavaServer Faces的更新版本,简化了UI组件的开发和使用。 6. **RESTful Web Services**:通过...
《求精要诀——JavaEE编程开发案例精讲》是一本深入浅出的JavaEE编程教程,由清华大学出版社出版。本书旨在通过丰富的实例讲解,帮助读者掌握JavaEE平台上的核心开发技术,提升实际项目开发能力。书中源代码的提供,...
这本书结合了jbpm3.1的中文文档,为读者提供了深入浅出的指导。 首先,我们要理解JBPM的核心概念。JBPM提供了一个基于模型驱动的方法来定义和管理业务流程,通过 BPMN(Business Process Model and Notation)2.0 ...