- 浏览: 639735 次
- 性别:
- 来自: 北京
最新评论
-
2047699523:
java hibernate demo使用实例教程源代码下载: ...
hibernate延迟加载的原理与实现 -
在世界的中心呼喚愛:
hantsy 写道这种lazy的解释只对了一半,按java p ...
hibernate延迟加载的原理与实现 -
moguicy:
看了下时间,不是楼主是否还在开发
【翻译】Wicket启示录——理论与实践(一) -
xfan0828:
"最后但并不是最不重要的一点就是" BZ, ...
【翻译】深入浅出 EJB3.1(上) -
doudou87323:
十分感谢,正在学习中,受益匪浅
【翻译】深入浅出 EJB3.1(上)
我对本文的一些看法:
Reza Rahman又出EJB3.1新文章了.本文作为该系列的第二部分,重点探讨了EJB3.1中的Timer Service和EJB打包机制.通过本文,你会了解到EJB3.1其实也在改变――越来越轻量级,越来越讲究最佳实践.比如说Timer Service就是在当前流行的开源scheduler(调度程序),比如说Quartz的基础上再接再厉.EJB打包机制也越来越看重轻量级的容器(比如说Tomcat),毕竟市场占有率说明了一切!!!最后稍带提到了Web Bean作为EJB的DI(依赖注入)补充,填补了EJB一直以来的诟病.但不管怎么样,EJB3.1究竟在JavaEE扮演什么样的角色,我们拭目以待.
正文
讨论
该系列文章预先给大家介绍了专家组们正在继续研究JavaEE下一版本的规范——EJB3.1所带来的改变。理想情况下,文章提到的这些变化,希望可以尽早的从你那里得到反馈从而使得专家组可以做出最好的选择。EJB3.0已经将笨重的JavaEE编程模型转变得简洁明了。EJB3.1的目标就是在此基础上通过添加一系列必须的特性,使得EJB走的更远。在应系列的每一篇文章中,我将告诉你专家组的进展情况。
在先前的第一篇文章中,我谈到了最早两个关于EJB3.1特性的讨论——可选的session bean接口和singleton bean。当然其它的特性也捎带谈了谈。在这第二篇文章里,我将详细讲述另外两个特性——增强的EJB Timer Service和更简化的packing(打包).请记住,尽管规范的草案很快会发布,但这里所说的一切至今仍然没有确定下来。我只是让你了解JCP内部在干什么,并且如果你有反馈意见,可以随时提出。
致谢
在第一篇文章里,我鼓励你直接给JCP邮箱jsr-318-comments@jcp.org或我的邮箱rrahman@tripodtech.net反馈。在介绍EJB3.1之前,我想致谢所有反馈意见的人们。我希望在我的每篇文章中,都能继续得到你们的思路与意见。我也为该系列文章广而好评而感激大家。
是时候改变Timer Service特性了
Scheduling(计划任务)是许多应用程序的重要组成部分,比如说报表生成,数据库维护,生成OLAP摘要以及数据同步等任务都涉及到Scheduling。如果你用过当前版本EJB Timer Service,我会发现它很有用,但也很受限制!最大的限制在于当前版本的EJB Timer Service并不十分灵活而且计划的作业只能硬编码实现,无法使用可声明式的处理办法。Timer Service的一些缺点早在EJB2.x时期,Richard Monson-Haefel就已经作了论述,下面就是Richard在TheServerSide上关于EJB的一些观点:http://www.theserverside.com/tt/articles/article.tss?l=MonsonHaefel-Column4.
好吧,现在我们来快速看看EJB3.0所支持的Timer Service。下面是一个EJB3的例子:
@Stateless
public class PlaceBidBean implements PlaceBid {
@Resource TimerService timerService;
public void addBid(Bid bid) {
... Code to add the bid goes here...
timerService.createTimer(15*60*1000, 15*60*1000, bid);
}
@Timeout
public void monitorBid(Timer timer) {
Bid bid = (Bid) timer.getInfo();
... Code to monitor the bid goes here...
}
}
上面的那个Stateless Session bean建立了一个每15分钟触发的timer,这样当一个bid(竞标)对象建立后,每过15分钟,addBid方法会被调用一次。当timer每次触发时,被标注为@Timeout annotation 的monitorBid方法被调用,查看bidder(竞标人)是否已经高于先前的价格了。
这个功能在PlaceBidBean中运作良好,现在我们稍微改变一下需求:需要为所有的ActionBazaar客户每月月初提供时事邮件。那么如果按照现在这样基于毫秒来控制TimerService的硬编程方式简直就是冒险!当然,不否认,在应用程序启动时,你可以写出一些相当笨重的代码来创建这样的timer。但何必呢,现在的JavaEE中,已经有几个现成的timer机制来实现相对灵活的声明式配置。你可以使用流行的开源scheduler(调度程序),比如说Quartz,也可以使用商业化的Flux,甚至还可以使用你应用程序服务器(比如说WebLogic或EAServer.)所特有的scheduler。现在的问题是,如果你需要一个类似于UNIX cron这么强大的声明式scheduler的话,那么以上解决方案就显得相当麻烦——所的以上方案都与各自的供应商绑定。还有更完美的解决方案吗?请随我一同走进EJB3.1中加强的Timer Service。
在Timer Service所增强的特性中,最重要的特性之一是也可以采用声明式方法来创建一个类似于cron的schedule来trigger(触发)EJB方法(当然还有更多特性,不过要等到最新规范的草案出来后,你们才能看到)。现在我们来解决先前提出的那个问题,这里你可以使用@Schedule annotation来标注EJB方法,实现为所有的ActionBazaar客户每月月初提供时事邮件:
@Stateless
public class NewsLetterGeneratorBean implements NewsLetterGenerator {
@Schedule(second="0", minute="0", hour="0",
dayOfMonth="1", month="*", year="*")
public void generateMonthlyNewsLetter() {
... Code to generate the monthly news letter goes here...
}
}
下面的表格显示了@Schedule annotation的一些默认值:
Attribute | Allowable Values | Default |
Second | [0,59] | 0 |
Minute | [0,59] | 0 |
Hour | [0,23] | 0 |
dayOfMonth | [1,31] | * |
Month | [1,12] or {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep","Oct", "Nov", Dec"} | * |
dayOfWeek | [0,7] or {"Sun", "Mon", "Tue","Wed", "Thu", "Fri", "Sat"} | * |
Year | A four-digit calendar year | * |
注意,所有的属性都支持cron风格的“*”号通配符,逗号分隔的列表(比如:用"Jan, Feb, Mar"来设置month的属性)还有“-”号分隔来描述时间跨度(比如说"Mon-Fri"表示week属性从星期一到星期五)。那么@Schedule表达式语法是否支持“/”操作呢?又是否支持缩写,比如用“Jan”代替“January”呢?同样,是否可以将@Schedule表达式再压缩的更简单些?上面的那个例子可以表示成:
@Schedule(expression="0 0 0 1 * * *")
有一些站起来嚷嚷说“纯cron风格的表达式”太晦涩了,又有一些人指出许多数开发人员已经习惯了这种风格,EJB应该支持它。现在的TimerService接口添加了新方法,用来支持编程版本的cron风格。编程版本中,支持为一个给定的schedule定义激活和取消日期。比如说,我们刚才提到的那些“每月初提供时事”将来可以在预定时间激活,而不是像以前那样当timer创建好了就处于激活状态。那么应该让@Schedule annotation也支持类似的功能吗?支持定义一个有限次数的cron trigger怎么样?你还能想到其它特性吗?
简化 EJB 打包机制
EJB3.0可选的XML布署描述符已经大大简化了JavaEE应用程序的打包和布署。尽管如此,JavaEE打包仍然死板的要求一个模块一个模块的。也就是说你必须分开为web和EJB模块打包成jar文件。在一个典型的JavaEE布署场合下,一个EAR文件包括一个war归档文件和一个EJB jar。图1描述了当前JavaEE打包的方案。概括的说,理想中的EJB的jar代表的是“模块化”的busines service,供 “客户端”的web模块使用.模块化思想是很重要,但问题是如果business service用不着客户端在多个JavaEE模块之间进行共享的话,这样反而会让简单的web应用程序过度浪费时间.
图 1: 当前JavaEE的打包情况.
为简化web应用程序的EJB打包机制针对的就是解决这个问题.在新的方案中,没有必要再分开建立EJB模块.EJB(尤其是采用标注annotation形式的Pojo)可以直接放在WEB-INF/classes文件夹下,作为WAR布署的一部分.类似的,如果你要使用ejb-jar.xml布署描述符,你也可以直接将其同web.xml文件一起放在WEB-INF文件夹下.将来也有可能可以把EJB jar包直接放在WEB-INF/lib文件夹下(你觉得这重要吗?).新的打包方案请看图2:
图 2: 为简化web应用程序的EJB打包方案
对我个人而言,一个有趣的含意是:简化后的打包方案与先前所要求严格定义的JavaEE EAR文件相比,EJB变成更加模糊了.(毕竟EJB也可以直接布署在WEB-INF文件夹及其子文件夹WEB-INF\classes下了)这对使用XML配置文件和JNDI look-ups而非100%采用Annotation和DI(依赖注入)的我们来说,确实是一个不小的麻烦.现在所有的EJB引用,资源的引用以及任何环境下定义的实体现在都可以在WAR中进行共享.因为整个WAR文件只有一个local componet environment(本地组件环境,将JDNI绑定在java:comp/env命名空间上).也就是说,你可以在web.xml这么定义一个数据源的引用:
<resource-ref> <description>My data source</description> <res-ref-name>jdbc/mydb</res-ref-name> <res-type>javax.sql.DataSource</res-type> <res-auth>Container</res-auth> </resource-ref>
现在你不仅可以在web容器组件(比如说servlet)使用下列代码来查找数据源,也可以在WAR里的EJB中直接使用.
// Looking up my data source. DataSource ds = (DataSource) envCtx.lookup("java:comp/env/jdbc/mydb");
你是怎么看待这个的?真正使我喜欢简化后的打包机制的一个原因是——它与EJB Lite(注:EJB Lite是EJB的一个子集,但最后是否会推出,还需要等JSR的最后决定)配合的很好.EJB Lite是EJB的一个最小子集,专门用于简化后的应用程序.在以后的文章中,我会谈到更多关于EJB Lite的内容.一种有趣的假设就是,很有可能许多供应商会先从实现EJB Lite开始,将EJB直接布署到WAR文件里,这样就完全绕过了JavaEE的EAR文件,可以运行于各种Servlet容器(比如说Tomcat或Jetty).我感觉JBoss AS Express,GlassFish Express以Tomcat+OpenEJB很可能不会忽略EJB Lite的,尤其假定在JavaEE 6基础上.而你是怎么看待这些可能发生的事情呢?
更多主题
不管你相信与否,这些讨论的特性在这两篇文章中仍然只是冰山一角.下面一些有趣的话题我将在后续的系列文章中再给大家探讨:
1. EJB以EJB Lite形式支持最低要求的容器.这也许与现在开源的Embedded Jboss,OpenEJB和EasyBeans作为Tomcat的一个插件形式类似.
2. 支持异步Session Bean的调用
3. 通过Stateful Session Bean的web service终端,支持stateful web service.
4. 标准化的JNDI映射来代替目前各个供应商四分五裂的局面已经有了初步的讨论.
除了EJB3.1外,我还想谈谈从EJB到Web Beans的使用.也许你已经知道,Web Beans是一个非常强大的综合应用程序框架,它所得EJB可以拥有一些非常有意义的DI(依赖注入)特性,而此前JavaEE一直备受批评.Web Beans规范由Gaving King领导着,并且其中的思想来自于JBoss Seam和Google Guice(外号“疯狂的Bob” Bob Lee因Guice而名声大振,目前也致力于WebBeans开发).最后,祝希望专家组好运吧,并且希望他们及时将反馈的信息进行处理.
相关连接
1. JSR 318: Enterprise JavaBeans 3.1, http://jcp.org/en/jsr/detail?id=318.
2. JSR 299: Web Beans, http://jcp.org/en/jsr/detail?id=299.
按照Linux约定:0或7都可以代表星期天
(第二部分结束)
评论
关于 EJB 3.1 的最新动态,请看 Ken Saks (EJB 3.1 spec lead)的 blog:
http://blogs.sun.com/kensaks/
信息: The Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: C:\sun\jre1.6.0_03\bin;.;C:\WINDOWS\Sun\Java\bin;C:\WINDOWS\system32;C:\WINDOWS;C:\Program Files\Java\jre1.6.0_05\bin\client;C:\Program Files\Java\jre1.6.0_05\bin;F:\oracle\app\oracle\product\10.2.0\server\bin;C:\WINDOWS\system32;C:\WINDOWS\system32\WBEM;D:\Sun\AppServer\jdk;D:\Sun\AppServer\jdk\bin;d:\Program Files\Sybase\Shared\PowerBuilder;C:\Program Files\Microsoft SQL Server\80\Tools\BINN;d:\Program Files\Sybase\Shared\DataDirect;C:\Program Files\Common Files\Adobe\AGL;C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727;C:\Program Files\Common Files\Autodesk Shared\;C:\Program Files\backburner 2\;e:\Program Files\Subversion\bin;E:\dot.net\bin;d:\Sun\AppServer\bin;;E:\program\Tools\WinNT;E:\program\MSDev98\Bin;E:\program\Tools;E:\VC98\bin;E:\apache-ant-1.7.0\BIN
2008-3-21 21:19:23 org.apache.coyote.http11.Http11BaseProtocol init
信息: Initializing Coyote HTTP/1.1 on http-8090
2008-3-21 21:19:23 org.apache.catalina.startup.Catalina load
信息: Initialization processed in 1907 ms
2008-3-21 21:19:23 org.apache.catalina.core.StandardService start
信息: Starting service Catalina
2008-3-21 21:19:23 org.apache.catalina.core.StandardEngine start
信息: Starting Servlet Engine: Apache Tomcat/5.5.20
2008-3-21 21:19:23 org.apache.catalina.core.StandardHost start
信息: XML validation disabled
2008-3-21 21:19:24 org.apache.catalina.core.StandardContext filterStart
严重: Exception starting filter encodingFilter
java.lang.ClassNotFoundException: filter.SetCharacterEncodingFilter
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1355)
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1201)
at org.apache.catalina.core.ApplicationFilterConfig.getFilter(ApplicationFilterConfig.java:209)
at org.apache.catalina.core.ApplicationFilterConfig.setFilterDef(ApplicationFilterConfig.java:304)
at org.apache.catalina.core.ApplicationFilterConfig.<init>(ApplicationFilterConfig.java:77)
at org.apache.catalina.core.StandardContext.filterStart(StandardContext.java:3634)
at org.apache.catalina.core.StandardContext.start(StandardContext.java:4217)
at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1013)
at org.apache.catalina.core.StandardHost.start(StandardHost.java:718)
at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1013)
at org.apache.catalina.core.StandardEngine.start(StandardEngine.java:442)
at org.apache.catalina.core.StandardService.start(StandardService.java:450)
at org.apache.catalina.core.StandardServer.start(StandardServer.java:709)
at org.apache.catalina.startup.Catalina.start(Catalina.java:551)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:294)
at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:432)
2008-3-21 21:19:24 org.apache.catalina.core.StandardContext start
严重: Error filterStart
2008-3-21 21:19:24 org.apache.catalina.core.StandardContext start
严重: Context [/zhaobandevelop] startup failed due to previous errors
2008-3-21 21:19:24 org.apache.coyote.http11.Http11BaseProtocol start
信息: Starting Coyote HTTP/1.1 on http-8090
2008-3-21 21:19:25 org.apache.jk.common.ChannelSocket init
信息: JK: ajp13 listening on /0.0.0.0:8009
2008-3-21 21:19:25 org.apache.jk.server.JkMain start
信息: Jk running ID=0 time=0/250 config=null
2008-3-21 21:19:25 org.apache.catalina.storeconfig.StoreLoader load
信息: Find registry server-registry.xml at classpath resource
2008-3-21 21:19:25 org.apache.catalina.startup.Catalina start
信息: Server startup in 2031 ms
第一排第7个按钮(Img按钮)
--------------------------------------------------------------------
期待EJB越来越方便!
发表评论
-
【翻译】深入浅出 EJB3.1(下)
2009-05-07 23:37 8913Global JNDI names( 统一的 全局 ... -
【翻译】深入浅出 EJB3.1(上)
2009-05-06 20:59 11162终于有空将EJB3.1的最新文章与大家分享,原文请看: ht ... -
【翻译】Java EE 6体系结构的变革
2009-02-09 10:01 4526又看到 Reza 同学为 -
【翻译】Java EE 6体系结构的变革(完)
2009-02-09 10:00 6473JSF 2.0 尽 ... -
垃圾收集器是一个“宝贝收藏家”?
2008-11-25 23:58 3080原文请看:http://java.dzone.com/ar ... -
深入理解JBoss Cache3.0——Naga
2008-11-12 09:12 9743原文请看: http://java.dzone.com/ ... -
【翻译】Rod Johnson——关于当选JCP执行委员会的之言片语
2008-11-03 10:42 3192SpringSource 在上月底被宣布被加入 JCP ... -
【翻译】EJB3.1真的来了吗?EJB3.1系列文章(五) 终章
2008-10-16 14:37 9224历时9 个多月的EJB3.1 系列文章终于要划上圆满的句 ... -
【翻译】Rod Johnson——平衡的质疑:Spring维护策略的再次调整(完)
2008-10-09 09:33 4072不管你承不承认,Spring实际上已经是实事上JAVA企业开 ... -
【云计算专家Joseph Ottinger系列】应用服务器本质论
2008-09-08 08:58 3483原文请看: http://www.t ... -
Spring破坏了JEE规范吗?
2008-09-02 13:33 4095[TTS 编辑注:这是 TTS 论坛上的原帖。我现在把它 ... -
【翻译】spring配置全书(下)——附PDF完整版下载
2008-07-14 12:30 10844JMS 命名空间简介 Schema URI ... -
【翻译】spring配置全书(上)
2008-07-07 23:11 8951作者简介: Craig Walls 是 Texa ... -
【翻译】EJB3.1真的来了吗?EJB3.1系列文章(四)
2008-06-18 23:10 38219前言 Raza 同学终于又出 EJB3.1 文章了 ... -
【翻译】Rod Johnson——Spring的宣言:开源,开放(完)
2008-06-10 16:51 5616前言 这是本文的第二部分,里面提到并回答许多Spring用 ... -
【翻译】Rod Johnson——Spring的宣言:开源,开放
2008-06-06 13:06 6117原文地址: http://blog.sp ... -
【翻译】EJB3.1真的来了吗?EJB3.1系列文章(三)
2008-05-01 13:53 8840文本继续和大家分享EJB3.1特性,今天谈到的EJB Lite ... -
【Danny hui】运用抽象工厂模式自己动手写一个IoC
2008-04-23 16:34 6360本文的作者Danny hui似乎是TTS上的新人,我从Goog ... -
【翻译】Wicket启示录——理论与实践(三)完
2008-04-11 01:09 6287接下来,我们再看看EditContact类,把新建联系人的话和 ... -
【翻译】Wicket启示录——理论与实践(二)
2008-04-09 23:47 5889第二部分 实践 Application(应用程序) 与 ...
相关推荐
#### 二、EJB 3.1 的主要特点 ##### 1. **No-Interface View (非接口视图)** EJB 3.1 引入了一种新的概念——No-Interface View,即将一个Bean的所有公共方法通过Local View暴露出来。这意味着Session Beans不再...
EJB 3.1是其一个重要的版本,相较于3.0,它引入了许多改进和新特性,使得EJB更加易用且更接近轻量级框架的开发体验。这个压缩包中的源代码是《EJB 3.1 Cookbook》一书的配套实例,可以帮助读者深入理解和应用书中...
### EJB3.1技术培训知识点详述 #### 一、EJB3.1概述 **EJB(Enterprise JavaBeans)3.1** 是Java EE平台中的一个重要组成部分,主要用于构建可伸缩、健壮的企业级应用程序。EJB3.1在前代版本的基础上做了大量的...
- **标题**:“EJB3.1_JSR 318-EJB3.1” - **描述**:此文档是EJB 3.1规范(JSR 318),与EJB 3.0相比,新增的功能包括: - 取消接口要求。 - 引入单例会话Bean(Singleton session bean)。 - 支持异步调用。 -...
### EJB3.1讲解 #### EJB概要 ##### EJB基本概念 EJB(Enterprise JavaBeans)是由Sun Microsystems提出的、面向企业级应用的一种组件模型。它旨在为开发复杂的企业级应用程序提供一种标准化的方式。在EJB的概念...
《EJB 3.1 Cookbook》是一本针对企业级Java应用开发的专业书籍,主要涵盖了EJB(Enterprise JavaBeans)3.1版本的相关技术。EJB是Java EE(Java Platform, Enterprise Edition)的一部分,用于构建可扩展、安全且...
EJB 3.1 Core Contracts主要包括了EJB容器与EJB组件之间的交互协议以及EJB组件必须遵循的一系列规则。这些合同定义了EJB组件的生命周期管理、远程调用接口、事务处理等核心功能,并且强调了EJB组件与容器之间约定的...
【EJB3.1简介】 EJB(Enterprise Java Beans)是Java平台上的一个核心标准,主要用于构建企业级分布式应用程序。EJB3.1是EJB规范的一个版本,它简化了之前版本的复杂性,提高了开发效率。EJB3.1引入了更多的注解驱动...
标题《EJB3.1与JBoss7.1.1在eclipse的实现》意味着本文档将介绍如何使用EJB3.1标准在JBoss应用服务器7.1.1版本上进行企业级Java Bean(EJB)的开发,并通过Eclipse集成开发环境进行部署和测试。EJB3.1是一种用于简化...
#### 二、EJB 3.1 特性 ##### 1. **轻量级 EJB** - **简化注解**:EJB 3.1 引入了更多的注解来简化配置,例如 `@Stateless`、`@Stateful` 和 `@Singleton`。 - **无 XML 配置**:在大多数情况下,开发者可以通过...
`javax.ejb`包是Java EJB规范的一部分,包含了一系列接口和类,这些是用来实现和管理EJBs的关键元素。 标题中的"javax.ejb-3.1.2.2.jar"是一个特定版本的EJB API的实现,它对应于EJB 3.1规范的2.2次小更新。这个jar...
**J2EE EJB 3.1:企业级Java组件的增强与演进** Java 2 Platform, Enterprise Edition (J2EE) 是一个用于构建分布式、多层的企业级应用程序的平台,而Enterprise JavaBeans (EJB) 是J2EE的核心组成部分,它提供了一...
### EJB 3.1五大模式改进令Java EE 6更好用 在深入解析EJB 3.1的五大改进模式之前,我们首先简要回顾一下EJB(Enterprise Java Beans)的基本概念及其在Java EE平台中的重要性。EJB是Java EE的核心组件之一,旨在...
本篇文章将指导你如何使用JBoss7.1和EJB3.1在Eclipse3.7环境中创建你的第一个EJB项目。EJB(Enterprise JavaBeans)是一种Java平台上的组件模型,用于构建可扩展的、可靠的、安全的企业级应用。JBoss是Red Hat公司...
"javax.ejb-3.1.2.2_with-source.zip"是一个包含了javax.ejb-3.1.2.2版本的EJB组件,这个版本支持Java EE 6规范,且提供了源代码供开发者深入学习和调试。 EJB 3.1是EJB规范的一个重要里程碑,它极大地简化了EJB的...
EJB 3.1 Cookbook – Free Pdf Book
标题《EJB3.1 Cookbook》表明这是一本关于企业Java Bean (EJB) 技术的实用指南,其第三版专注于提供一系列解决实际问题的简单而非常有效的方法。EJB是Java EE(现在称为Jakarta EE)的一部分,用于简化基于Java的...
EJB 3.1是该规范的一个重要版本,引入了许多改进以提高开发者的生产力和简化API。在这个ejb-3_1-pr-api.zip文件中,我们主要关注的是EJB 3.1的编程模型和API。 EJB 3.1的重要特性包括: 1. **注解驱动的开发**:与...