您好,欢迎访问三七文档
当前位置:首页 > 办公文档 > 其它办公文档 > 使用Java EE 实现松耦合的 SOA 应用程序
EJB倡导者:使用JavaEE实现松耦合的SOA应用程序级别:中级GeoffHambrick(ghambric@us.ibm.com),杰出工程师,IBM2006年2月13日本文探究了面向服务的体系结构中各种形式的松耦合,并重点介绍什么时候是使用消息驱动Bean所提供的异步处理能力的昀佳时机。摘自IBMWebSphere开发者技术期刊。在每个专栏中,EJB倡导者都采用独特的前后衔接的对话方式与实际客户和开发人员进行交流,并在期间针对某一大家关注的设计问题推荐解决方案。其中并没有介绍任何确定性的细节,也没有提出“新颖的”或专有的体系结构。要了解更多信息,请参见EJB倡导者简介。您对松耦合的定义是否太过狭窄呢?由于这是2005年的昀后一篇文章,而且这次交流的是Java™Platform、EnterpriseEdition(JavaEE)组件而非会话和实体Bean,所以可以通过这篇文章来很好地总结本专栏所进行的一年之久的讨论,并将所有的组件一起放到完整的面向服务的体系结构中。问题:太过于关注SOA中的会话和实体亲爱的EJB倡导者:到目前为止您的专栏全部都是关于服务的会话和实体EJB,它对于直接连接Java应用程序是很重要的,例如基于Web客户端的HttpServlets或富(我们不喜欢说“胖”)客户端的Swing应用程序。但我们曾听说面向服务的体系结构都是与松耦合有关的。这不就意味着要尽可能地使用SOAP来提供使客户端和服务器应用程序能够独立运行的语言中立性和异步协议?换句话说,为什么您对JMS和消息驱动Bean讨论得不多呢?署名:FeelingDisconnected对松耦合有许多方面要考虑亲爱的Disconnected:EJB倡导者关注的是应用程序的服务层,而对客户端介绍得很少,因为我对古谚语形式追随功能(formfollowsfunction)深信不疑。其原因在于,许多进行SOA的项目之所以失败,是因为它们没有首先建立定义服务的良好模型就开始着手实现细节。这种倾向相当正常,因为我在SOA项目中接触到的大多数人都是架构师和编程人员,他们知道棘手的始终是在细节上,想要尽快解决它们。所以,一旦我们认同好服务的特征是粗粒度、无状态、可通过中介传递和适应的(请参阅IsiteverbesttouseEJBcomponentswithoutfacadesinserviceorientedarchitectures?),很明显带有数据传输对象的会话Bean就会在实现中扮演重要角色。Page1of8EJB倡导者:使用JavaEE实现松耦合的SOA应用程序2009-9-15,从而使人们对会话Bean是否真的是必需的产生了疑问。图1显示了同时使用的两种方法。图1.用有待使用的会话和实体EJB实现的服务图1显示了当使用传递过去的会话Bean时,纯实体方法(自EJB2开始可用)如何才能有更少的组件和更短的路径长度。其中使用绿色框表示客户端,蓝色框表示各种接口和Facade类。橙色框是昀常访问的实体Bean。框和框之间使用双向箭头连接,箭头标有在组件之间通信所使用的协议;蓝色箭头表示相同JVM中的Java调用,红色箭头表示远程连接(在本例中使用RMI/IIOP)。为了表示端到端的流向,对流程箭头进行编号,其中A1-A10表示从Java客户端经过会话Bean到实体和返回的流程,B1-B4表示从客户端直接到实体Bean和返回的流程。客户端用于检索服务接口的编程模型也很简单,虽然在图中没有表示出来。检索会话Bean接口需要在JNDI上下文中查找会话Home并用它创建一个会话;实体Home仅仅需要一次查找,其方法可以直接调用而不需要创建对EJBObject的引用。以下两段代码示例显示了它们之间的区别。清单1.定位和调用远程会话EJB方法清单2.定位和调用等效远程实体EJBHome方法图1和相关的代码示例显示了JavaEE编程模型的真正好处,不管您是否选择使用实体Home方法。编程模型逐渐改进并提供向后兼容。简而言之,您的昀佳实践能够得以发展而不必强制更改现有的应用程序。另外,JNDI上下文提供了一个不容忽视的松耦合相关方面:实现独立性。会话或实体EJB组件的远程接口提供了位置独立性。使用远程接口使得在相同的JVM中部署客户端应用程序和服务组件成为可能,其中它对系统(例如使用HttpServlets的Web应用程序)的响应时间、吞吐量和可维护性目标有意义。图2显示的正是这样的配置,其中企业质量应用服务器(如IBM®WebSphere®ApplicationServer)在联合部署了客户端和服务组件时“短路”远ContextinitCtx=newInitialContext();Objectobj=initCtx.lookup(java:comp/env/ejb/OrderEntry);OrderEntryHomehome=(OrderEntryHome)PortableObjectRemote(obj,OrderEntryHome.class);OrderEntryref=home.create();//MethodmustbeinvokedonasessionreferenceCustomerDatadata=ref.getOpenOrderForCustomer(cID);ContextinitCtx=newInitialContext();Objectobj=initCtx.lookup(java:comp/env/Customer);CustomerHomeref=(CustomerHome)PortableObjectRemote(obj,CustomerHome.class);//NotehowthemethodisinvokeddirectlyCustomerDatadata=ref.getOpenOrder(cID);Page2of8EJB倡导者:使用JavaEE实现松耦合的SOA应用程序2009-9-15(不管服务实现为实体Home方法还是会话Bean)。流程A1-A6显示了与服务组件联合部署的HttpServlet的使用。流程B1-B4显示了它如何被远程富客户端JavaEE应用程序重用。图2.部署到本地Web应用程序和远程富客户端的服务但这听起来像是您已确定松耦合的昀重要方面是语言中立性和异步操作。并且您认为需要异步操作会使得必须在服务器端使用消息驱动Bean(MDB)和JMS。在实现MDB时,许多编程人员使用的方法是通过其远程接口调用表示服务的EJB组件,以使上述位置独立性昀大化。然后,不管服务实现是远程还是本地部署,MDB的目的都是作为简单的适配器,将MQ层连接到承载服务的EJB容器。JMS可能由异步客户端应用程序(如果它是Java)或MDB使用(通常用于应答队列)。图3显示了服务实现的另一个输入通道的这一配置。图3.用提供异步客户端通道的MDB部署的服务流程C1-C2与D1-D6分别显示,以阐释客户端和服务器流程的独立性。C2和D6只是对Writer是否写入消息进行“确认”,并不意味着等待。清单3显示了MDB的典型结构,该结构应该有助于阐明它必须做的处理:清单3.典型的消息驱动Bean实现publicclassOrderSubmitMsgHandlerimplementsMessageDrivenBean{privatetransientMessageDrivenContextcontext=null;//InterfacesupportedbyeitherthesessionBeanorentityHomeprivatetransientOrderEntryref;publicvoidejbCreate(){Page3of8EJB倡导者:使用JavaEE实现松耦合的SOA应用程序2009-9-15。看起来您已经将语言中立性的要求与异步处理的要求紧密联系起来了。没有理由不能将这些考虑分开;解析SOAP消息和用它调用会话Bean的能力应该与该消息的处理是异步(通过MQ或者传递JMS等效消息的另一个协议)还是同步(例如通过HTTP,甚至IIOP)无关。事实上,JavaEE应用程序上的一些早期“发明”的Web服务使用HttpServlet来解析通过HTTP传递的XML消息。这种方法昀终发展为SOAP/HTTP。图4显示可以在EJB组件所实现的服务之上提供的另一个路径。图4.将语言中立性和异步性的考虑分开WebServiceServlet和MessageDrivenBean可以共享对来自从消息串或HttpServletRequest提取的流的数据传输对象进行解析的代码。类似地,响应或应答可以共享从数据传输对象(它可以是Exception的一个实例)生成流的代码。希望这有助于您理解JavaEE组件的布置,所有这些都将提供某种对面向服务的体系结构很基本的松耦合形式。对话到此结束,//Cachethehomeaccordingtoeithersnippetoneortwo}publicvoidejbRemove(){}publicvoidsetMessageDrivenContext(MessageDrivenContextmdc){context=mdc;}//MessageacknowledgeanddatabaseupdateparticipatepublicvoidonMessage(MessageinMessage){//Parsethecustomerfromthemessagetry{ref.submit(customer);}catch(CustomerDoesNotExiste){//SendJMSmessagetoreplyqueuefromexception}catch(OrderNotOpene){//SendJMSmessagetoreplyqueuefromexception}catch(OrderHasNoItemsExceptione){//SendJMSmessagetoreplyqueuefromexception}}}Page4of8EJB倡导者:使用JavaEE实现松耦合的SOA应用程序2009-9-15:谢谢。我以前不认为像JNDI这样的服务和远程接口会提供松耦合。我还可以了解如何将SOAP和MQ的概念“紧耦合”(按照您提到的方法),以及应该如何尽可能将它们分开。所以将解析和生成SOAP消息看作由Web服务Servlet和MDB重用的服务本身是很有意义的。但谢谢,我不要这样。在这次讨论之前,SOA看似非常简单:每个服务都公开一个SOAP/MQ接口。现在看起来有好多选择要考虑,并且既然将SOAP消息的解析和生成看作服务,那么为什么不想建立一个独立的会话Bean来封装它们以便如图中所显示的那样进行重用呢?再次打扰您,我还是:StillDisconnected并非一切都是服务:要使用业务模型加以判定亲爱的Disconnected:这次讨论是当过快要着手实现
本文标题:使用Java EE 实现松耦合的 SOA 应用程序
链接地址:https://www.777doc.com/doc-15361 .html