﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-【永恒的瞬间】  -文章分类-EJB3.0</title><link>http://www.blogjava.net/19851985lili/category/26726.html</link><description>☜GivE mE HapPy ☞




</description><language>zh-cn</language><lastBuildDate>Thu, 25 Oct 2007 18:30:09 GMT</lastBuildDate><pubDate>Thu, 25 Oct 2007 18:30:09 GMT</pubDate><ttl>60</ttl><item><title>Session Bean与Entity Bean</title><link>http://www.blogjava.net/19851985lili/articles/154978.html</link><dc:creator>☜♥☞MengChuChen</dc:creator><author>☜♥☞MengChuChen</author><pubDate>Mon, 22 Oct 2007 05:44:00 GMT</pubDate><guid>http://www.blogjava.net/19851985lili/articles/154978.html</guid><wfw:comment>http://www.blogjava.net/19851985lili/comments/154978.html</wfw:comment><comments>http://www.blogjava.net/19851985lili/articles/154978.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/19851985lili/comments/commentRss/154978.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/19851985lili/services/trackbacks/154978.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp;Entity Bean与Session Bean的不同表现在如下几个方面：&nbsp;持久性在应用或应用服务器的运行时间外，Entity Bean状态数据仍存在于持久数据存储之中。Entity Bean有两种持久类型：Bean管理持久类型（Bean-managed Persistence，BMP）和容器管理的持久类型（Container-managed Persiste...&nbsp;&nbsp;<a href='http://www.blogjava.net/19851985lili/articles/154978.html'>阅读全文</a><img src ="http://www.blogjava.net/19851985lili/aggbug/154978.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/19851985lili/" target="_blank">☜♥☞MengChuChen</a> 2007-10-22 13:44 <a href="http://www.blogjava.net/19851985lili/articles/154978.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Message-driven Bean</title><link>http://www.blogjava.net/19851985lili/articles/154946.html</link><dc:creator>☜♥☞MengChuChen</dc:creator><author>☜♥☞MengChuChen</author><pubDate>Mon, 22 Oct 2007 04:27:00 GMT</pubDate><guid>http://www.blogjava.net/19851985lili/articles/154946.html</guid><wfw:comment>http://www.blogjava.net/19851985lili/comments/154946.html</wfw:comment><comments>http://www.blogjava.net/19851985lili/articles/154946.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/19851985lili/comments/commentRss/154946.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/19851985lili/services/trackbacks/154946.html</trackback:ping><description><![CDATA[&nbsp;
<p><strong>Message-driven Bean</strong></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">Message-driven Bean</span><span style="font-family: 宋体">是EJB2.0 规范中提出的的Enterprise Bean<strong>。</strong></span></p>
<p><strong><span style="font-family: 宋体">Message-driven Bean </span></strong><strong><span style="font-family: 宋体">的产生原因</span></strong></p>
<p><strong><span style="font-family: 宋体">效率原因</span></strong></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">在JavaEE&#8482;平台中，客户端对Session Bean 和Entity Bean 的方法调用通过RMI或RMI-IIOP协议进行，这是传统的通过网络进行远程调用的方法，当调用请求通过网络传播到容器，容器则将客户端请求变成一序列的方法调用依次进行。客户端只有在容器处理完请求并返回结果后方可继续进行。</span></p>
<p><strong><span style="font-family: 宋体">可靠性的原因</span></strong></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">当客户端对Session Bean或Entity Bean进行调用时，必须保证服务器容器处于运行状态，如容器或网络出现错误，客户端调用将无法进行。</span></p>
<p><strong><span style="font-family: 宋体">事件的广播</span></strong></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">传统的RMI 或RMI-IIOP机制中，客户端在某一时刻只能与某一具体的服务器通讯， 没有任何内置的机制来将事件广播到多个服务器。</span></p>
<p><span style="font-family: 宋体">Message-driven Bean</span><span style="font-family: 宋体">作为远程方法调用的一种替代方法，在客户端和服务器的直接方法调用之间放置了一个中间层，接收一个或多个客户端的消息，并将消息转发给一个或多个消息的使用者(Message Consumer)。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">通过消息机制而非直接的方法调用，客户端可以继续执行而不必等待服务器的运行结果，服务器可以选择在方法调用完成后通知客户，而消息机制本身保证了信息传输的可靠性，同时使用消息域(Message Domain)中的消息类型模型以达到事件广播的机制。</span></p>
<p><span style="font-family: 宋体">但是，对Message-Driven Bean 的使用也有一定的限制，如不适用于依赖于方法调用、要求具有明确的返回值才能继续的客户端程序。另外，如果在一个应用中过多的使用了Message-Driven Bean， 对应用的执行效率将会产生影响，所以不适用于对时间因素敏感的客户端程序(如在下午两点定购下午四点的机票，而在四点后才得到订购是否成功的结果，这时结果已毫无用处)。</span></p>
<p><strong><span style="font-family: 宋体">Message-driven Bean </span></strong><strong><span style="font-family: 宋体">作为一般的JMS 使用者(consumer)</span></strong></p>
<p style="text-indent: 31.5pt"><span style="font-family: 宋体">作为一种具有JMS使用者(consumer)功能的Enterprise Bean组件模型，Message-Driven Bean由EJB容器进行管理，具有一般的JMS使用者(consumer)所不具有的优点，如对于一个Message-driven Bean，容器可创建多个实例来处理大量的并发消息，而一般的JMS使用者 (consumer)开发时则必须对此进行处理才能获得类似的功能。同时Message-Driven Bean可取得EJB所能获得的标准服务，如容器管理事务等服务。</span></p>
<p><span style="font-family: 宋体">由于与Message-driven Bean相关的主题(Topic)或队列(Queue)可以在部署时配置，因此，Message-driven Bean具有更多的灵活性。</span></p>
<p><span style="font-family: 宋体">但注意，一个Message-driven Bean在部署时只可与一个具体的主题(Topic)或队列(Queue) 建立关联。如有多个主题(Topic)或队列（Queue）需要与一个Message-driven Bean关联，则 可以在部署时部署多个Message-driven Bean类,或使用一般的JMS使用者(consumer) 。</span></p>
<p><span style="font-family: 宋体">Message-driven Bean </span><span style="font-family: 宋体">与其他Enterprise Bean</span></p>
<p><span style="font-family: 宋体">作为Enterprise Bean组件模型之一，Message-driven Bean，具有一些与Session Bean 和Entity Bean相同的方法，但由于Message-driven Bean本身不处理客户端调用，也无会话状态，客户只能通过向与Message Driven Bean关联的队列或主题发送消息从而与Message-driven Bean 进行交互，因此，Message-driven Bean 与Session Bean 和Entity Bean之间最大的不同之处在于Message-Driven Bean不具有组件接口及Home接口。</span></p>
<p><span style="font-family: 宋体">另外，</span>Message-driven Bean<span style="font-family: 宋体">异步地处理队列（</span>Queue<span style="font-family: 宋体">）或主题</span>(Topic)<span style="font-family: 宋体">中的消息，而非方法调用。</span></p>
<p><strong>Message-driven Bean</strong></p>
<p style="text-justify: inter-ideograph; text-align: justify">Message-driven Bean<span style="font-family: 宋体">是</span>JMS<span style="font-family: 宋体">消息驱动的</span>JavaEE&#8482;<span style="font-family: 宋体">平台服务器端组件，具备无状态、支持事务的特点。当从</span>JMS<span style="font-family: 宋体">队列（</span>Queue<span style="font-family: 宋体">）或主题（</span>Topic<span style="font-family: 宋体">）中接收到</span>JMS<span style="font-family: 宋体">消息后，由容器对组件进行调用。一般，可理解为消息的监听器（</span>Listener<span style="font-family: 宋体">）及接收者（</span>Consumer<span style="font-family: 宋体">）。</span></p>
<p style="text-justify: inter-ideograph; text-align: justify">Message-driven Bean<span style="font-family: 宋体">组件对于客户端是不可见的。客户端如希望调用封装在组件中的业务逻辑，只能通过向组件监听的</span>JMS<span style="font-family: 宋体">队列（</span>Queue<span style="font-family: 宋体">）或主题（</span>Topic<span style="font-family: 宋体">）发送消息，然后容器以事件的形式向组件实例发送消息，组件实例根据消息的内容调用相应的业务逻辑或其他组件。</span></p>
<p style="text-justify: inter-ideograph; text-align: justify"><span style="font-family: 宋体">因此，任何向组件监听的特定</span>JMS<span style="font-family: 宋体">队列（</span>Queue<span style="font-family: 宋体">）或主题（</span>Topic<span style="font-family: 宋体">）发送</span>JMS<span style="font-family: 宋体">消息的客户端，即可视为</span>Message-driven Bean<span style="font-family: 宋体">的客户端。</span></p>
<p style="text-justify: inter-ideograph; text-align: justify">Message-driven Bean<span style="font-family: 宋体">组件模型不具备会话状态，也就是说，当组件实例在没有对客户端的</span>JMS<span style="font-family: 宋体">消息提供处理的时候，所有的实例间没有差别。</span></p>
<p style="text-justify: inter-ideograph; text-align: justify">Message-driven Bean<span style="font-family: 宋体">的运行和客户端的运行是异步的。同时，对于客户端不可见。其实例由容器创建，其生存周期由容器控制。</span></p>
<p><strong><span style="font-size: 12pt; color: navy; font-family: Verdana">Message-driven Bean</span></strong><strong><span style="font-size: 12pt; color: navy; font-family: 宋体">与</span></strong><strong><span style="font-size: 12pt; color: navy; font-family: Verdana">EJB</span></strong><strong><span style="font-size: 12pt; color: navy; font-family: 宋体">容器、客户端、消息系统</span></strong></p>
<p style="margin: 4.5pt 0cm; text-indent: 24pt"><span style="font-size: 11pt; color: black; font-family: 宋体">下图是</span><span style="font-size: 11pt; color: black; font-family: Verdana">EJB</span><span style="font-size: 11pt; color: black; font-family: 宋体">容器、客户端、消息系统与</span><span style="font-size: 11pt; color: black; font-family: Verdana">EJB</span><span style="font-size: 11pt; color: black; font-family: 宋体">之间的关系：</span></p>
<p style="margin: 4.5pt 0cm; text-indent: 24pt"><em><span style="font-size: 11pt; color: black; font-family: Verdana">EJB</span></em><em><span style="font-size: 11pt; color: black; font-family: 宋体">容器、客户端、消息系统与</span></em><em><span style="font-size: 11pt; color: black; font-family: Verdana">EJB</span></em><em><span style="font-size: 11pt; color: black; font-family: 宋体">之间的关系</span></em></p>
<div align="center">
<table style="margin-left: 37.5pt; width: 90%; border-collapse: collapse" cellspacing="0" cellpadding="0" width="90%" border="0">
    <tbody>
    </tbody>
</table>
</div>
<p style="margin: 4.5pt 0cm; text-indent: 24pt"><span style="font-family: 宋体">客户端发送消息到</span>JMS<span style="font-family: 宋体">消息系统中的队列或主题。</span>Message-driven Bean<span style="font-family: 宋体">在部署到容器中时，指定的队列或主题，容器对其进行监听；当容器从队列或主题中接收到消息之后，将消息作为事件的一部分通知容器中相应的</span>Message-driven Bean<span style="font-family: 宋体">实例。</span></p>
<p style="margin: 4.5pt 0cm; text-indent: 24pt"><strong><span style="font-family: 宋体">组件模型单元</span></strong></p>
<p style="text-justify: inter-ideograph; text-align: justify">Message-driven Bean<span style="font-family: 宋体">由容器控制其生存周期，容器提供安全、并发、事务等等服务，对于客户端来说，</span>Message-driven Bean<span style="font-family: 宋体">是不可见的。因此，</span>Message-driven Bean<span style="font-family: 宋体">不同于</span>Session Bean<span style="font-family: 宋体">和</span>Entity Bean<span style="font-family: 宋体">，不具有组件接口和</span>Home<span style="font-family: 宋体">接口。</span></p>
<p style="text-justify: inter-ideograph; text-align: justify">Message-driven Bean<span style="font-family: 宋体">组件模型包含两个单元，即组件类和部署描述。下面分别对开发这些单元时，涉及的普遍过程、规则及注意事项进行描述。</span></p>
<h3 style="text-justify: inter-ideograph; text-align: justify"><span style="font-family: 宋体">组件类</span></h3>
<h3 style="text-justify: inter-ideograph; text-align: justify">&nbsp;javax.ejb.MessageDrivenBean<span style="font-family: 宋体">接口</span></h3>
<p style="text-justify: inter-ideograph; text-align: justify">EJB2.1<span style="font-family: 宋体">规范中的</span>Message-driven Bean<span style="font-family: 宋体">组件中的组件类必须实现</span>MessageDrivenBean<span style="font-family: 宋体">接口。</span>EJB3.0<span style="font-family: 宋体">规范不强制</span>Message-driven Bean<span style="font-family: 宋体">实现该接口，而通过</span>@MessageDriven<span style="font-family: 宋体">注解进行标记并通过依赖注入与注解实现类似功能。</span></p>
<p style="text-justify: inter-ideograph; text-align: justify">MessageDrivenBean<span style="font-family: 宋体">接口中定义了两个容器管理回调的方法：</span></p>
<p style="text-justify: inter-ideograph; margin-left: 36pt; text-align: justify; tab-stops: list 36.0pt"><span style="font-size: 10pt; font-family: Symbol">&#183;<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span>setMessageDrivenContext<span style="font-family: 宋体">方法，容器创建</span>Bean<span style="font-family: 宋体">实例后，容器将调用该方法将由容器维护的</span>Bean<span style="font-family: 宋体">实例的上下文（</span>context<span style="font-family: 宋体">）与</span>Bean<span style="font-family: 宋体">实例进行关联。</span><span style="font-family: 宋体">在</span>EJB3.0<span style="font-family: 宋体">规范中，可使用</span>@Resource<span style="font-family: 宋体">注解通知容器注入</span>MessageDrivenContext<span style="font-family: 宋体">实例。</span></p>
<p style="text-justify: inter-ideograph; margin-left: 36pt; text-align: justify; tab-stops: list 36.0pt"><span style="font-size: 10pt; font-family: Symbol">&#183;<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span>ejbRemove<span style="font-family: 宋体">方法，在实例被容器清除时，容器将调用此方法。一般，实例会在此方法中对实例占用的资源进行释放。在</span>EJB3.0<span style="font-family: 宋体">规范中，可使用</span>@PreDestroy<span style="font-family: 宋体">注解标记此方法。</span></p>
<p style="text-justify: inter-ideograph; margin-left: 36pt; text-indent: 0cm; text-align: justify">&nbsp;<strong>javax.jms.MessageListener</strong><strong><span style="font-family: 宋体">接口</span></strong></p>
<p style="text-justify: inter-ideograph; text-align: justify">Message-driven Bean<span style="font-family: 宋体">组件中的组件类必须实现</span>MessageListener<span style="font-family: 宋体">接口。</span></p>
<p style="text-justify: inter-ideograph; text-align: justify"><span style="font-family: 宋体">在消息到达</span>Message-driven Bean<span style="font-family: 宋体">指定的监听队列或主题时，容器将调用</span>javax.jms.MessageListener<span style="font-family: 宋体">接口中定义的</span>onMessage<span style="font-family: 宋体">方法。开发者在此方法中提供对消息进行处理的业务逻辑。</span></p>
<p style="text-justify: inter-ideograph; text-align: justify">Session Bean<span style="font-family: 宋体">和</span>Entity Bean<span style="font-family: 宋体">不可实现</span>javax.jms.MessageListener<span style="font-family: 宋体">接口。</span></p>
<p style="text-justify: inter-ideograph; text-align: justify"><strong>&nbsp;javax.ejb.MessageDrivenContext</strong><strong><span style="font-family: 宋体">接口</span></strong></p>
<p style="text-justify: inter-ideograph; text-align: justify"><span style="font-family: 宋体">容器将提供一个</span>MessageDrivenContext<span style="font-family: 宋体">对象，使实例可以访问由容器维护的实例的上下文环境。在此接口中，定义了如下方法：</span></p>
<p style="text-justify: inter-ideograph; margin-left: 36pt; text-align: justify; tab-stops: list 36.0pt"><span style="font-size: 10pt; font-family: Symbol">&#183;<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span>getEJBHome<span style="font-family: 宋体">、</span>getEJBLocalHome<span style="font-family: 宋体">方法，从</span>EJBContext<span style="font-family: 宋体">接口继承的方法，</span>Message-driven Bean<span style="font-family: 宋体">实例不可调用此方法；</span></p>
<p style="text-justify: inter-ideograph; margin-left: 36pt; text-align: justify; tab-stops: list 36.0pt"><span style="font-size: 10pt; font-family: Symbol">&#183;<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span>getCallerPrincipal<span style="font-family: 宋体">方法，从</span>EJBContext<span style="font-family: 宋体">接口继承的方法，</span>Message-driven Bean<span style="font-family: 宋体">实例不可调用此方法；</span></p>
<p style="text-justify: inter-ideograph; margin-left: 36pt; text-align: justify; tab-stops: list 36.0pt"><span style="font-size: 10pt; font-family: Symbol">&#183;<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span>isCallerInRole<span style="font-family: 宋体">方法，从</span>EJBContext<span style="font-family: 宋体">接口继承的方法，</span>Message-driven Bean<span style="font-family: 宋体">实例不可调用此方法；</span></p>
<p style="text-justify: inter-ideograph; margin-left: 36pt; text-align: justify; tab-stops: list 36.0pt"><span style="font-size: 10pt; font-family: Symbol">&#183;<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span>setRollbackOnly<span style="font-family: 宋体">方法，当前事务将被永久标记为回滚，不会被提交。只有容器管理事务的</span>Message-driven Bean<span style="font-family: 宋体">可被允许使用此方法；</span></p>
<p style="text-justify: inter-ideograph; margin-left: 36pt; text-align: justify; tab-stops: list 36.0pt"><span style="font-size: 10pt; font-family: Symbol">&#183;<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span>getRollbackOnly<span style="font-family: 宋体">方法，检查当前事务是否已被标记为回滚。例如，</span>EJB<span style="font-family: 宋体">实例可以通过此方法，决定是否继续在当前事务边界内继续进行计算。只有容器管理事务的</span>Message-driven Bean<span style="font-family: 宋体">可被允许使用此方法；</span></p>
<p style="text-justify: inter-ideograph; margin-left: 36pt; text-align: justify; tab-stops: list 36.0pt"><span style="font-size: 10pt; font-family: Symbol">&#183;<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span>getUserTransaction<span style="font-family: 宋体">方法，返回</span>javax.transaction.UserTransaction<span style="font-family: 宋体">接口。</span>EJB<span style="font-family: 宋体">实例可通过此接口对事务边界进行划分，并取得事务的状态。只有容器管理事务的</span>Message-driven Bean<span style="font-family: 宋体">可被允许使用此方法；</span></p>
<p style="text-justify: inter-ideograph; margin-left: 36pt; text-indent: 0cm; text-align: justify"><strong>&nbsp;</strong><strong><span style="font-family: 宋体">串行化的调用</span></strong></p>
<p style="text-justify: inter-ideograph; text-align: justify">Apusic<span style="font-family: 宋体">应用服务器中的</span>EJB<span style="font-family: 宋体">容器支持</span>Message-driven Bean<span style="font-family: 宋体">的多个实例的并发运行，但是每个实例只</span>&#8220;<span style="font-family: 宋体">看到</span>&#8221;<span style="font-family: 宋体">一个串行的方法调用过程，因此开发</span>Message-driven Bean<span style="font-family: 宋体">时，不需要将其以可重入（</span>reentrant<span style="font-family: 宋体">）的方式进行编写。</span></p>
<p style="text-justify: inter-ideograph; text-align: justify"><strong>&nbsp;</strong><strong><span style="font-family: 宋体">消息处理的并发</span></strong></p>
<p style="text-justify: inter-ideograph; text-align: justify">Apusic<span style="font-family: 宋体">应用服务器允许</span>Message-driven Bean<span style="font-family: 宋体">的多个实例并发执行，提供对流（</span>Stream<span style="font-family: 宋体">）消息并发处理。</span></p>
<p style="text-justify: inter-ideograph; text-align: justify"><strong>&nbsp;Message-driven Bean</strong><strong><span style="font-family: 宋体">方法的事务上下文</span></strong></p>
<p style="text-justify: inter-ideograph; text-align: justify">onMessage<span style="font-family: 宋体">方法在何种事务范围内被调用，取决于部署描述中指定的事物属性，如</span>Bean<span style="font-family: 宋体">被指定使用容器管理的事务的方式，则必须将事务属性设置为</span>&#8220;Required&#8221;<span style="font-family: 宋体">或</span>&#8220;NotSupported&#8221;<span style="font-family: 宋体">。</span></p>
<p style="text-justify: inter-ideograph; text-align: justify"><span style="font-family: 宋体">当</span>Bean<span style="font-family: 宋体">采用</span>Bean<span style="font-family: 宋体">管理的事务的方式，即使用</span>javax.transaction.UserTransaction<span style="font-family: 宋体">接口进行事务划分时，导致</span>Bean<span style="font-family: 宋体">实例被调用的消息接收操作并非是事务中的一部分。如果希望消息接收操作是事务中的一部分，则</span>Bean<span style="font-family: 宋体">必须使用容器管理事务的方式，并且设置事务属性为</span>&#8220;Required&#8221;<span style="font-family: 宋体">。</span></p>
<p style="text-justify: inter-ideograph; text-align: justify">&nbsp;<strong><span style="font-family: 宋体">消息接收确认（</span></strong><strong>Message Acknowledgement</strong><strong><span style="font-family: 宋体">）</span></strong></p>
<p style="text-justify: inter-ideograph; text-align: justify">Message-driven Bean<span style="font-family: 宋体">不能使用</span>JMS API<span style="font-family: 宋体">中提供的消息接收确认操作。消息接收确认操作由容器自动完成。如</span>Bean<span style="font-family: 宋体">采用了容器管理事务的方式，则消息接收确认操作作为事务提交的一部分自动进行。如使用了</span>Bean<span style="font-family: 宋体">管理事务的方式，消息接收确认操作不能作为事务提交的一部分，开发者可通过在部署描述中的</span>acknowledge-mode<span style="font-family: 宋体">元素指定消息接收确认操作的方式为</span>AUTO_ACKNOWLEDGE<span style="font-family: 宋体">或</span>DUPS_OK_ACKNOWLEDGE<span style="font-family: 宋体">，如未指定</span>acknowledge-mode<span style="font-family: 宋体">元素，容器将使用</span>AUTO_ACKNOWLEDGE<span style="font-family: 宋体">方式进行消息接收确认操作。</span></p>
<p style="text-justify: inter-ideograph; text-align: justify"><strong><span style="font-family: 宋体">指定队列（</span></strong><strong>Queue</strong><strong><span style="font-family: 宋体">）或主题（</span></strong><strong>Topic</strong><strong><span style="font-family: 宋体">）</span></strong></p>
<p style="text-justify: inter-ideograph; text-align: justify"><span style="font-family: 宋体">当</span>Message-driven Bean<span style="font-family: 宋体">被部署到容器时，必须关联到某个消息队列（</span>Queue<span style="font-family: 宋体">）或主题（</span>Topic<span style="font-family: 宋体">），以便容器对此队列或主题进行监听。</span></p>
<p style="text-justify: inter-ideograph; text-align: justify"><span style="font-family: 宋体">开发者可通过</span>@MessageDriven<span style="font-family: 宋体">注解的</span>mappedName<span style="font-family: 宋体">属性或部署描述文件中的</span>message-driven-destination<span style="font-family: 宋体">元素指定关联的队列或主题。</span></p>
<p style="text-justify: inter-ideograph; text-align: justify"><span style="font-family: 宋体">如</span>Bean<span style="font-family: 宋体">关联的是一个消息主题，则通过部署描述中的</span>subscription-durability<span style="font-family: 宋体">元素指定对队列进行的是持久还是非持久订阅，如此元素未指定，则使用非持久订阅的方式。</span></p>
<p style="text-justify: inter-ideograph; text-align: justify">&nbsp;<strong><span style="font-family: 宋体">异常处理</span></strong></p>
<p style="text-justify: inter-ideograph; text-align: justify">Message-driven Bean<span style="font-family: 宋体">中的</span>onMessage<span style="font-family: 宋体">方法不能声明抛出</span>java.rmi.RemoteException<span style="font-family: 宋体">异常。</span></p>
<p style="text-justify: inter-ideograph; text-align: justify"><span style="font-family: 宋体">一般来说，</span>Message-driven Bean<span style="font-family: 宋体">在运行期间不应向容器抛出</span>RuntimeException<span style="font-family: 宋体">异常。</span>RuntimeException<span style="font-family: 宋体">异常是指会导致</span>Message-driven Bean<span style="font-family: 宋体">进入</span>&#8220;<span style="font-family: 宋体">不存在</span>&#8221;<span style="font-family: 宋体">状态的非应用级异常。如果</span>Bean<span style="font-family: 宋体">使用了</span>Bean-managed<span style="font-family: 宋体">事务并抛出了</span>RuntimeException<span style="font-family: 宋体">异常，容器不应确认收到了这条消息。</span></p>
<p style="text-justify: inter-ideograph; text-align: justify"><span style="font-family: 宋体">从发信端看来，收信端一直存在，若发信端继续对该目的地发送消息，容器会自动把消息转向到其他</span>Message-driven Bean<span style="font-family: 宋体">实例。</span></p>
<p style="text-justify: inter-ideograph; text-align: justify"><span style="font-family: 宋体">遗漏的</span>PreDestroy<span style="font-family: 宋体">调用</span></p>
<p style="text-justify: inter-ideograph; text-align: justify"><span style="font-family: 宋体">在系统发生异常的情况下，不能保证容器总会调用</span>Bean<span style="font-family: 宋体">的</span>PreDestroy<span style="font-family: 宋体">方法，因此，如果</span>Bean<span style="font-family: 宋体">在</span>PostConstruct<span style="font-family: 宋体">方法中打开了一些资源，并在</span>PreDestroy<span style="font-family: 宋体">方法中释放这些资源，在这种情况下，则这些资源不能被释放。</span></p>
<p style="text-justify: inter-ideograph; text-align: justify"><span style="font-family: 宋体">鉴于以上原因，使用</span>Message-driven Bean<span style="font-family: 宋体">的应用需要提供一种机制，以便周期性的清除这些未释放的资源占用。</span></p>
<p style="text-justify: inter-ideograph; text-align: justify">&nbsp;<strong><span style="font-family: 宋体">必须遵守的规则</span></strong></p>
<p style="text-justify: inter-ideograph; text-align: justify"><span style="font-family: 宋体">在开发</span>Message-driven Bean<span style="font-family: 宋体">时，开发者必须遵守如下规则：</span></p>
<p style="text-justify: inter-ideograph; text-align: justify"><strong>&nbsp;</strong><strong><span style="font-family: 宋体">组件类</span></strong></p>
<p style="text-justify: inter-ideograph; margin-left: 36pt; text-align: justify; tab-stops: list 36.0pt"><span style="font-size: 10pt; font-family: Symbol">&#183;<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: 宋体">使用</span>EJB2.1<span style="font-family: 宋体">规范时，必须间接或直接实现</span>javax.ejb.MessageDrivenBean<span style="font-family: 宋体">接口；</span><span style="font-family: 宋体">使用</span>EJB3.0<span style="font-family: 宋体">规范时，可改为使用</span>@MessageDriven<span style="font-family: 宋体">注解对组件类进行标记。</span></p>
<p style="text-justify: inter-ideograph; margin-left: 36pt; text-align: justify; tab-stops: list 36.0pt"><span style="font-size: 10pt; font-family: Symbol">&#183;<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: 宋体">必须间接或直接实现</span>javax.jms.MessageListener<span style="font-family: 宋体">接口；</span></p>
<p style="text-justify: inter-ideograph; margin-left: 36pt; text-align: justify; tab-stops: list 36.0pt"><span style="font-size: 10pt; font-family: Symbol">&#183;<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: 宋体">类必须声明为</span>public<span style="font-family: 宋体">，不可被声明为</span>final<span style="font-family: 宋体">或</span>abstract<span style="font-family: 宋体">类；</span></p>
<p style="text-justify: inter-ideograph; margin-left: 36pt; text-align: justify; tab-stops: list 36.0pt"><span style="font-size: 10pt; font-family: Symbol">&#183;<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: 宋体">必须拥有一个无参数的</span>public<span style="font-family: 宋体">构造函数（</span>constructor<span style="font-family: 宋体">）；</span></p>
<p style="text-justify: inter-ideograph; margin-left: 36pt; text-align: justify; tab-stops: list 36.0pt"><span style="font-size: 10pt; font-family: Symbol">&#183;<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: 宋体">类不能定义</span>finalize()<span style="font-family: 宋体">方法；</span></p>
<p style="text-justify: inter-ideograph; margin-left: 36pt; text-align: justify; tab-stops: list 36.0pt"><span style="font-size: 10pt; font-family: Symbol">&#183;<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: 宋体">在原</span>EJB2.1<span style="font-family: 宋体">规范中，类必须实现</span>ejbCreate()<span style="font-family: 宋体">方法用来创建组件实例，在</span>EJB3.0<span style="font-family: 宋体">中，这一要求已被移除了。</span>EJB3.0<span style="font-family: 宋体">的兼容规则规定，如果</span>Message-driven Bean<span style="font-family: 宋体">类实现了</span>ejbCreate()<span style="font-family: 宋体">方法，将看作被</span>@PostConstruct<span style="font-family: 宋体">注解标记的方法处理。此时若同时使用</span>@PostConstruct<span style="font-family: 宋体">注解，则只能标记</span>ejbCreate()<span style="font-family: 宋体">方法。</span></p>
<p style="text-justify: inter-ideograph; margin-left: 36pt; text-indent: 0cm; text-align: justify">&nbsp;<strong>onMessage</strong><strong><span style="font-family: 宋体">方法</span></strong></p>
<p style="text-justify: inter-ideograph; margin-left: 36pt; text-align: justify; tab-stops: list 36.0pt"><span style="font-size: 10pt; font-family: Symbol">&#183;<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: 宋体">方法必须被声明为</span>public<span style="font-family: 宋体">；</span></p>
<p style="text-justify: inter-ideograph; margin-left: 36pt; text-align: justify; tab-stops: list 36.0pt"><span style="font-size: 10pt; font-family: Symbol">&#183;<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: 宋体">方法不能被声明为</span>final<span style="font-family: 宋体">或</span>static<span style="font-family: 宋体">；</span></p>
<p style="text-justify: inter-ideograph; margin-left: 36pt; text-align: justify; tab-stops: list 36.0pt"><span style="font-size: 10pt; font-family: Symbol">&#183;<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: 宋体">返回值必须为</span>void<span style="font-family: 宋体">；</span></p>
<p style="text-justify: inter-ideograph; margin-left: 36pt; text-align: justify; tab-stops: list 36.0pt"><span style="font-size: 10pt; font-family: Symbol">&#183;<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: 宋体">方法只能有一个</span>javax.jms.Message<span style="font-family: 宋体">类型的参数；</span></p>
<p style="text-justify: inter-ideograph; margin-left: 36pt; text-align: justify; tab-stops: list 36.0pt"><span style="font-size: 10pt; font-family: Symbol">&#183;<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: 宋体">不能抛出</span>java.rmi.RemoteException<span style="font-family: 宋体">异常</span></p>
<p style="text-justify: inter-ideograph; margin-left: 36pt; text-align: justify; tab-stops: list 36.0pt"><span style="font-size: 10pt; font-family: Symbol">&#183;<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: 宋体">运行期间一般来说不应抛出</span>RuntimeException<span style="font-family: 宋体">。请参考：</span></p>
<p style="text-justify: inter-ideograph; margin-left: 36pt; text-indent: 0cm; text-align: justify"><strong>&nbsp;ejbRemove</strong><strong><span style="font-family: 宋体">方法</span></strong></p>
<p style="text-justify: inter-ideograph; margin-left: 36pt; text-align: justify; tab-stops: list 36.0pt"><span style="font-size: 10pt; font-family: Symbol">&#183;<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: 宋体">方法名必须是</span>ejbRemove;</p>
<p style="text-justify: inter-ideograph; margin-left: 36pt; text-align: justify; tab-stops: list 36.0pt"><span style="font-size: 10pt; font-family: Symbol">&#183;<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: 宋体">方法必须被声明为</span>public<span style="font-family: 宋体">；</span></p>
<p style="text-justify: inter-ideograph; margin-left: 36pt; text-align: justify; tab-stops: list 36.0pt"><span style="font-size: 10pt; font-family: Symbol">&#183;<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: 宋体">方法不能被声明为</span>final<span style="font-family: 宋体">或</span>static<span style="font-family: 宋体">；</span></p>
<p style="text-justify: inter-ideograph; margin-left: 36pt; text-align: justify; tab-stops: list 36.0pt"><span style="font-size: 10pt; font-family: Symbol">&#183;<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: 宋体">返回值必须为</span>void<span style="font-family: 宋体">；</span></p>
<p style="text-justify: inter-ideograph; margin-left: 36pt; text-align: justify; tab-stops: list 36.0pt"><span style="font-size: 10pt; font-family: Symbol">&#183;<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: 宋体">方法不能有参数；</span></p>
<p style="text-justify: inter-ideograph; margin-left: 36pt; text-align: justify; tab-stops: list 36.0pt"><span style="font-size: 10pt; font-family: Symbol">&#183;<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: 宋体">不能抛出</span>java.rmi.RemoteException<span style="font-family: 宋体">异常。</span></p>
<p style="text-justify: inter-ideograph; margin-left: 36pt; text-align: justify; tab-stops: list 36.0pt"><span style="font-size: 10pt; font-family: Symbol">&#183;<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: 宋体">在</span>EJB3.0<span style="font-family: 宋体">规范中，可使用</span>@PreDestroy<span style="font-family: 宋体">注解实现同样效果。若实现</span>javax.ejb.MessageDrivenBean<span style="font-family: 宋体">接口同时使用注解，则只能把</span>ejbRemove()<span style="font-family: 宋体">方法注解为</span>@PreDestroy</p>
<p style="text-justify: inter-ideograph; text-align: justify"><strong><span style="font-family: 宋体">生存周期</span></strong></p>
<p style="text-justify: inter-ideograph; text-align: justify"><span style="font-family: 宋体">下图表示</span>Message-driven Bean<span style="font-family: 宋体">的生存周期。</span></p>
<p style="text-justify: inter-ideograph; text-align: justify"><em><span style="font-family: Verdana">Message-driven Bean</span></em><em><span style="font-family: 宋体">的生存周期</span></em></p>
<div align="center">
<table style="margin-left: 37.5pt; width: 90%; border-collapse: collapse" cellspacing="0" cellpadding="0" width="90%" summary="manufactured viewport for HTML img" border="0">
    <tbody>
    </tbody>
</table>
</div>
<img src ="http://www.blogjava.net/19851985lili/aggbug/154946.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/19851985lili/" target="_blank">☜♥☞MengChuChen</a> 2007-10-22 12:27 <a href="http://www.blogjava.net/19851985lili/articles/154946.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Session Bean</title><link>http://www.blogjava.net/19851985lili/articles/154926.html</link><dc:creator>☜♥☞MengChuChen</dc:creator><author>☜♥☞MengChuChen</author><pubDate>Mon, 22 Oct 2007 03:45:00 GMT</pubDate><guid>http://www.blogjava.net/19851985lili/articles/154926.html</guid><wfw:comment>http://www.blogjava.net/19851985lili/comments/154926.html</wfw:comment><comments>http://www.blogjava.net/19851985lili/articles/154926.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/19851985lili/comments/commentRss/154926.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/19851985lili/services/trackbacks/154926.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp;会话Bean（Session Bean）什么是Session BeanSession Bean可被视为客户端程序在服务器上的部分逻辑延伸，每个Session Bean对象对应于特定的客户端，不能在多个客户端间共享。换句话说，Session Bean用于表示运行于服务器端的部分业务过程，作为客户端的代理，管理业务过程或任务，如客户对账户的借贷操作、汇率的计算，等等这些涉及逻辑...&nbsp;&nbsp;<a href='http://www.blogjava.net/19851985lili/articles/154926.html'>阅读全文</a><img src ="http://www.blogjava.net/19851985lili/aggbug/154926.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/19851985lili/" target="_blank">☜♥☞MengChuChen</a> 2007-10-22 11:45 <a href="http://www.blogjava.net/19851985lili/articles/154926.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>EJB 简介</title><link>http://www.blogjava.net/19851985lili/articles/154836.html</link><dc:creator>☜♥☞MengChuChen</dc:creator><author>☜♥☞MengChuChen</author><pubDate>Mon, 22 Oct 2007 01:25:00 GMT</pubDate><guid>http://www.blogjava.net/19851985lili/articles/154836.html</guid><wfw:comment>http://www.blogjava.net/19851985lili/comments/154836.html</wfw:comment><comments>http://www.blogjava.net/19851985lili/articles/154836.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/19851985lili/comments/commentRss/154836.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/19851985lili/services/trackbacks/154836.html</trackback:ping><description><![CDATA[EJB是sun的服务器端组件模型，最大的用处是<font color="#0000ff">部署分布式应用程序</font>，类似微软的.com技术。凭借java跨平台的优势，用EJB技术部署的分布式系统可以不限于特定的平台。<br />
<br />
<br />
EJB (Enterprise JavaBean)是J2EE的一部分，定义了一个用于开发基于组件的企业多重应用程序的标准。其特点包括网络服务支持和核心开发工具(SDK)。 <br />
<br />
在J2EE里，Enterprise Java Beans(EJB)称为Java 企业Bean，是Java的核心代码，分别是<font color="#0000ff">会话Bean</font>（Session Bean），<font color="#0000ff">实体Bean</font>（Entity Bean）和<font color="#0000ff">消息驱动Bean</font>（MessageDriven Bean）。&nbsp;&nbsp;<br />
<br />
1.Session Bean用于<font color="#0000ff">实现业务逻辑</font>，它可以是有状态的，也可以是无状态的。每当客户端请求时，容器就会选择一个Session Bean来为客户端服务。Session Bean可以直接访问数据库，但更多时候，它会通过Entity Bean实现数据访问。 <br />
<br />
2.Entity Bean是域模型对象，用于<font color="#0000ff">实现O/R映射</font>，负责将数据库中的表记录映射为内存中的Entity对象，事实上，创建一个Entity Bean对象相当于新建一条记录，删除一个Entity Bean会同时从数据库中删除对应记录，修改一个Entity Bean时，容器会自动将Entity Bean的状态和数据库同步。 <br />
<br />
3.MessageDriven Bean是EJB2.0中引入的新的企业Bean，它基于JMS消息，只能<font color="#0000ff">接收客户端发送的JMS消息</font>然后处理。MDB实际上是一个异步的无状态 Session Bean，客户端调用MDB后无需等待，立刻返回，MDB将异步处理客户请求。这适合于需要异步处理请求的场合，比如订单处理，这样就能避免客户端长时间 的等待一个方法调用直到返回结果。 <br />
<br />
EJB实际上是SUN的J2EE中的一套规范,并且规定了一系列的API用来实现把EJB概念转换成EJB产品.EJB是BEANS,BEANS是什么概 念,那就是得有一个容纳她,让她可劲造腾的地方,就是得有容器.EJB必须生存在EJB容器中.这个容器可是功能强大之极!她首先要包装你BEAN, EJB的客户程序实际上从来就不和你编写的EJB直接打交道,他们之间是通过HOME/REMOTE接口来发生关系的.它负责你的BEAN的所有的吃喝拉 萨睡,比如BEAN的持续化,安全性,事务管理。。。<br />
<br />
一.什么是 EJB?<br />
<br />
一个技术规范：EJB 从技术上而言不是一种"产品"<br />
EJB 是一种标准描述了构建应用组件要解决的:<br />
可扩展 (Scalable)<br />
分布式 (Distributed)<br />
事务处理 (Transactional)<br />
数据存储 (Persistent)<br />
安全性 (Secure)<br />
<br />
二.Sun 对 EJB 的期望<br />
<br />
提供一个标准的分布的、基于 OO 的组件架构<br />
屏蔽复杂的系统级功能需求<br />
Write once, run anywhere<br />
与非 Java 应用之间的互操作能力<br />
兼容 CORBA 标准<br />
<br />
三.特征
<div class="itemizedlist">
<ul type="disc">
    <li>
    <p>包含处理企业数据的业务逻辑；</p>
    <li>
    <p>EJB实例由容器在运行时创建及管理；</p>
    <li>
    <p>可在部署时通过编辑环境项（environment entry）定制EJB的行为；</p>
    <li>
    <p>EJB的各种服务设置信息，如事务及安全属性，从EJB的类文件中分离出来。在部署和运行时，可通过工具对EJB的服务设置信息进行管理；</p>
    <li>
    <p>EJB部署到EJB容器后，客户端才可通过EJB容器对EJB进行间接访问；</p>
    <li>
    <p>EJB可使用任何EJB规范中指定可以使用的服务；</p>
    <li>
    <p>EJB可以不经改动代码或重新编译，即可直接装配到一个新的应用中；</p>
    <li>
    <p>当EJB被部署到不同的容器或服务器时，EJB开发者定义的客户视图(Client View)不会发生改变。</p>
    </li>
</ul>
</div>
<br />
四：为什么选择 EJB?<br />
<br />
EJB 服务器完成"繁杂"的工作：<br />
　　应用开发人员关注于业务逻辑的实现而不是底层的实现机制(类似于 4GL 语言设计的目标)<br />
<p>事务处理：<br />
　　服务器提供对EJB组件的事务控制服务，多个业务操作同时成功，或全部失败，可以通过代码外的　部署描述来设置组件事务处理级别 ； </p>
<br />
可扩展性：<br />
　　　EJB 可以根据您应用的增长而扩展，EJB 服务器往往还提供了负载均衡和<br />
安全性：<br />
　　　由 EJB 服务器提供资源的访问权限控制<br />
<br />
四.EJB 架构<br />
<br />
<p>EJB的客户端有以下几种类型：</p>
<div class="itemizedlist">
<ul type="disc">
    <li>
    <p>运行于相同容器或其他容器中的EJB； </p>
    <li>
    <p>一般的Java类，如Java应用程序、applet、servlet； </p>
    <li>
    <p>非Java的客户环境，如非Java语言编写的CORBA客户。</p>
    </li>
</ul>
</div>
EJB组件模型的组成部分
<p>一般，EJB组件由以下几个部分组成，即组件服务器 (Server)，容器 (Container)，类 (Class) ，实例 (Instance)<br />
接口、Home接口，Remote 接口、Enterprise Bean类和部署描述文件(Message-driven Bean不具有组件接口和Home接口）。下面分别描述这些组成部分<br />
<br />
EJB的组件接口<br />
　　客户端通过EJB的组件接口访问EJB对象，组件接口中定义了可被客户端访问的业务方法(Message-driven Bean不具有组件接口）。组件接口分为远程接口和本地接口。</p>
<p>EJB对象通过远程或本地接口，提供远程客户访问或本地客户访问的支持。</p>
<p>　　　提供远程接口的EJB拥有可被远程客户访问或本地客户访问的能力。对于提供了远程接口的对象，客户可通过标准的Java RMI（Remote Method Invocation）进行远程对象调用。</p>
<p>　　提供本地接口的EJB只可被本地组件通过本地接口进行调用。所谓本地组件，即是运行于相同Java虚拟机中的本地EJB对象。本地调用通过一般的标准Java编程语言接口进行。</p>
<p>EJB可以同时提供本地接口和远程接口，但一般只提供二者之一。</p>
<p>HOME接口<br />
　　　EJB2.0规定了通过Home接口来提供客户端创建、清除和在同种类型的EJB中查找特定EJB对象的方法(Message-driven Bean不包含Home接口）。对于提供远程接口的EJB，需要提供远程Home接口；提供本地接口的EJB，需要提供本地Home接口。</p>
<p>　　　Home接口由EJB开发人员编写，远程Home接口必须扩展（extend）javax.ejb.EJBHome接口；本地Home接口必须扩展（extend）javax.ejb.EJBLocalHome接口。</p>
<p>EJB客户端通过标准的JNDI（Java Naming and Directory Interface&#8482;）API定位Home接口。</p>
<p>　EJB3.0中，Home接口的功能由依赖注入以及可选的生命周期回调方法实现。EJB组件不再需要提供Home接口</p>
<p>Enterprise Bean类<br />
Enterprise Bean类包含了组件的实现细节。</p>
<p>　　Enterprise Bean类由EJB开发人员编写，EJB2.0规范中的Enterprise Bean组件，必须分别声明实现如下接口，javax.ejb.SessionBean、javax.ejb.EntityBean和javax.ejb.MessageDrivenBean。符合EJB3.0规范的Enterprise Bean组件则不须实现以上接口，而使用@Stateful、@Stateless、@MessageDriven注解标记EJB类。</p>
<p>部署描述文件<br />
　　　部署描述文件是用于包含Enterprise Bean的运行时属性(安全性，事务性等等)信息的文件，与以上部分一起形成完整的EJB组件，通常部署描述文件使用图形化的部署工具进行处理。在EJB3.0规范中，EJB部署描述文件并不是必须的，可以在代码中使用注解来为EJB类附加部署信息。但部署描述文件可以令管理人员在部署时更为灵活。EJB3.0规范规定，当部署描述文件的信息与程序代码中的注解信息出现冲突时，以部署描述文件为准。这样管理人员就可以通过修改部署描述文件来改变部署信息，而不须重新编译应用程序。</p>
<p><br />
五. 简化的编程模型<br />
<br />
关注于业务逻辑实现：EJB 负责生命周期 (lifecycle), 数据存储 (persistence), 事务处理语义 (transactional semantic), 安全(security), ...<br />
通用的编程模型：各种服务的高层 API<br />
Java 是其编程语言<br />
<br />
<br />
EJB( 业务逻辑代码 ) 表示了与特定商业领域（例如银行、零售等行业）相适应的逻辑。它由<br />
运行在业务逻辑层的 enterprise bean 处理。<font color="#0000ff">一个 enterprise bean 可以从客户端接受数据，对<br />
它进行处理，并将其发送到企业信息系统层以作存储；同时它也可以从存储器获取数据，<br />
处理后将其发送到客户端应用程序</font>。<br />
有三种类型的 enterprise beans：session beans、entity beans 和 message-driven beans。<br />
Session bean 描述了与客户端的一个短暂的会话。当客户端的执行完成后，session bean 和<br />
它的数据都将消失；与之相对应的是一个 entity bean 描述了存储在数据库表中的一行持久<br />
稳固的数据，如果客户端终止或者服务结束，底层的服务会负责 entity bean 数据的存储。<br />
Message-driven bean 结合了 session bean 和 Java 信息服务（JMS）信息监听者的功能，它允<br />
许一个商业组件异步地接受 JMS 消息。 <br />
<br />
</p>
<p>六:EJB组件模型的灵活性</p>
<p>EJB组件模型的灵活性表现在:<br />
EJB可作为表示无状态服务的对象； <br />
EJB可作为表示无状态服务的对象，可通过向指定的消息队列或主题发送JMS消息，以实现对此对象的异步调用； <br />
EJB可作为表示与特定客户的会话对象。此类对象在客户进行跨越方法的调用时，自动维持会话状态； <br />
EJB可作为表示业务对象的实体对象，在多个客户间共享； <br />
EJB可作为一个细粒度的持久对象，包含在一个粗粒度业务对象的持久状态中。 <br />
通常，被远程访问的组件往往是粗粒度的业务对象，如订单、雇员纪录；细粒度的业务对象往往不会采用可远程访问的EJB组件模型，如订单中的采购项、雇员纪录中的地址，而是采用可本地访问的EJB组件模型或是作为EJB的附属类出现。</p>
<p>七:何时使用EJB组件:</p>
<p>下面是在使用EJB组件模型构建企业应用时，一些判断EJB组件模型是否适用的标准。<br />
EJB组件是构建分布式企业应用的组件模型技术； <br />
EJB组件规范是针对分布式企业应用制定的，是基于分布式对象技术的Java组件；EJB组件不涉及表示层的内容，因此，必须与其他表示层技术一起使用；应用服务器提供了可以解决安全性、资源共享、持续运行、并行处理、事务完整性等复杂问题的服务，从而简化了商业应用系统。<br />
应用客户端类型的考虑； <br />
一般，企业应用开发都会有多种类型的客户端的需求，访问相同的数据或业务逻辑。如使用Web客户提供对应用的基于Internet的访问，使用应用客户端提应用基于Intranet的访问。EJB组件模型将业务逻辑与数据封装到EJB组件中，提供对多种客户端的支持。</p>
<p>应用数据与业务逻辑的并发访问控制的考虑； <br />
企业应用通常需要提供数据或业务逻辑的并发访问能力，以此保证数据的完整性，由于EJB 组件控制对后台数据的访问，并管理当前事务和数据库的内部锁定。节省了编写数据库控制逻辑的工作量，同时也保证了数据的一致性与正确性，从而降低了总编程量。<br />
全局事务控制的考虑； <br />
企业应用通常需要对不同的资源进行事务性的操作，如某个操作需要对数据库进行访问，同时可能需要通过JMS消息服务发送消息，或者，需要访问两个位于不同物理位置的异种数据库，这些操作必须在相同的事务环境中完成。<br />
基于访问控制的考虑； <br />
企业应用中往往需要对某些资源进行访问控制，如需要针对不同用户对组件方法调用设置访问控制策略，对访问特定Web资源的用户设置访问控制策略等.</p>
 <img src ="http://www.blogjava.net/19851985lili/aggbug/154836.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/19851985lili/" target="_blank">☜♥☞MengChuChen</a> 2007-10-22 09:25 <a href="http://www.blogjava.net/19851985lili/articles/154836.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>