| Spring 2.0.1与BEA WebLogic Server 9.2的集成 |
|
| Struts | |
| 作者是 Administrator | |
| 2007-11-29 06:21:26 | |
|
编辑注:Spring 2.0.2软件包于本文完成后已经发布了,现在可以从这里下载。 摘要一年多以前,我们讲述过 Spring 1.2.x与WebLogic Server 9.2的集成。其后,我们又验证了Spring和BEA WebLogic Server的更新的版本,一直到WebLogic Server 9.2和Spring 2.0的组合。这些版本表现出在功能性、可用性和性能上的重大飞跃,因此我们决定对文章进行更新以反映这一变化。 BEA WebLogic Server 9.2是Sun Microsystems的Java EE 1.4平台的领先实现。然而,WebLogic Server的核心价值主张则体现在Java EE规范没有覆盖的领域——增强的管理、易用性、高可用性、可伸缩性、可靠性和性能。实际上,WebLogic Server的价值不依赖于任何特定的编程模型,所以它与新也自然适用于新出现的非Java EE的Java编程模型。近年来出现的最令人激动的事物莫过于基于反向控制(IoC)的模型,Spring Framework就是它的事实上的实现。本文介绍了Spring 2.0 Framework、WebLogic Server以及这两者的集成的新特性。我们会看到,整体大于部分之和。 文章结构文章的前两节概述Spring、WebLogic Server和它们各自的特性。如果您熟悉Spring Framework,那么可以跳过第一节。如果您熟悉WebLogic Server,那么可以跳过第二节。本文主要目的是介绍这两种技术的集成,所以本文后续的部分都是讲述这一主题的。首先,我们分析MedRec—WebLogic Server上的一个示例程序——分别以它的原始的Java EE形式和使用Spring Framework重构后的形式。之后,是关于特定的集成点的一些细节。如果您打算在 WebLogic Server上开发Spring应用程序,那么,几乎可以肯定,这些细节会对您有所帮助。如果您只是想有个大致的概念,可以先阅读标题,内容留待以后再看。最后,我们展望了一些正在考虑中的未来开发工作。 Spring简介本节,我们来简要地概述Spring Framework的特性,包括2.0版以来的一些新特性。 Spring是基于Rod Johnson在 Expert One-on-One J2EE Design and Development(Wrox, 2002)公布的代码的一个分层的Java/Java EE应用程序框架。Spring的存在是因为我们相信Java EE应该更容易使用,并且有可能创造更简单的Java EE开发方法而不会牺牲平台性能。 Spring支持灵活的Java EE开发,允许使用Plain Old Java Objects(一般称为 POJO)开发Java EE应用程序。 改进的Spring开发体验Spring在其核心部分提供了一个易于配置、XML驱动的反向控制(IoC)容器。IoC基于所谓的“好莱坞原则”:“不要打电话过来,请等通知。”在这种模式中,通过容器而不是直接编程将Java对象间的关系注入应用程序中。有两种注入方式—构造函数注入和setter注入,具体取决于容器是通过其构造函数还是mutator方法将信息注入已创建的Java对象。 在Spring中,注入的属性——或到其他bean的引用——是通过一个XML文件进行配置的,这使得配置轻而易举。它耦合了另外一个AOP框架,允许非侵入性增加诸如事务处理和安全等属性,这意味着开发人员可以专注于创建业务解决方案,而不必忙于复杂的Java EE开发或配置。由于容器是非侵入性的,所以您不必担心业务代码会被特定于供应商(此处也包括Spring)的工件所污染。 Spring应用程序组件如上所述,Spring提供了一个轻量级的容器,用于提供集中式、自动化的配置并连接应用程序对象。它是非侵入性的,能够以一致的和透明的方式通过IoC把一组松耦合的组件(POJO)组装成复杂的系统。因为该容器允许首先独立地开发和测试各软件组件,然后在任意环境中(Java SE或Java EE)中进行扩展部署,所以它具有灵活性和高利用率,并提高了应用程序的可测试性和可伸缩性.此外,Spring提供了许多其他对开发人员友好的特性,下面我们一一列举:
所有的Spring功能都可以在任何Java EE服务器上使用,大部分功能可以在非托管环境中使用。Spring的一个重心是支持可重用业务和不依赖于特定的Java EE 服务的数据访问对象。这些对象可以不费事地跨J2EE环境(Web或EJB)、独立应用程序和测试环境进行重用。 Spring的分层架构提供了大量灵活性。它的功能都构建在较低的层次上。例如,您可以在不使用MVC框架或没有AOP支持的情况下使用JavaBean配置管理。但是,如果您要使用Web MVC框架或AOP支持,您会发现它们构建在配置框架之上,所以您可以马上用上有关它的知识。 BEA WebLogic Server 9.2简介本节,我们来简要概述BEA WebLogic Server的特性,重点强调其提供的底层基础架构,而不是编程模型。 WebLogic Server是可伸缩的企业级Java EE应用服务器。WebLogic Server基础架构支持各类分布式应用程序的部署,是构建各种应用程序的理想基础。 Sun Microsystem公司的 Java EE 1.4 规范 在WebLogic Server上的实现提供了标准的一组API,用以创建能够访问多种服务(如数据库、消息传递服务和外部企业系统连接)的分布式Java应用程序。终端用户客户程序使用Web浏览器客户端或Java客户端访问这些应用程序。由于Java EE是如此有名,这里我们就不进一步讨论了。参见关于 编程模型 的 WebLogic Server文档,可以获得更多信息。 除了实现Java EE之外,WebLogic Server还使企业能够在一个健壮的、安全的、高可用的、可伸缩的环境中部署任务关键型应用程序。这些特性允许企业配置WebLogic Server实例集群以分布负载,并在发生硬件或其他故障时提供额外的容量。新的诊断工具允许系统管理员监控和调优已部署的应用程序和 WebLogic Server环境本身的性能。可以对WebLogic Server进行配置来自动监控和调整应用程序吞吐量,无需人工干预。广泛的安全特性保护了服务的访问,保证了企业数据安全,并阻止了恶意攻击。 WebLogic Server的增强后的服务质量就像许多其他的BEA产品,WebLogic Server如同冰山,浮在水面上的只是很少的一部分而已。具体来说,WebLogic Server提供了许多特性和工具来支持高可用的和可伸缩的应用程序部署:
现在,让我们来看一看这两个系统之间的协作。 在Java EE和Spring环境中开发应用程序 为了比较和对照Java EE和Spring开发方法的不同,我们采用用Spring 2.0 Framework重新编写了MedRec示例程序,充分利用Spring 2.0的许多创新特性。下一节,我们将给出MedRec一般架构的简短概述,然后依次看一下它的Java EE形式和Spring形式。 Medical Records应用程序Avitek Medical Records(或MedRec)是一个WebLogic Server示例程序工具包,简明地示范了Java EE平台的各个方面。设计MedRec的目的是作为各层次水平Java EE开发人员的一个教学工具。它显示了每个Java EE组件的使用方法,阐明了适于组件交互和客户端开发的设计模式。MedRec也表明了在WebLogic Server上开发和部署应用程序的最佳实践。 MedRec背后的真实世界概念是一个框架,其中患者、医生、管理人员使用各种不同的客户端管理患者数据。对于患者,MedRec提供了基于Web的应用程序,供他们察看自己的医疗记录和维护档案文件。对于管理人员,MedRec提供了基于Web的应用程序,用于管理注册登记、医疗记录上传和所有应用程序监控。MedRec还提供与独立的医疗机构接合的资源。为了演示这个通信系统,MedRec包括一个医生应用程序,用于向MedRec系统请求和提交数据。 MedRec Java EE版本架构概述Java EE和WebLogic Server版的MedRec的设计和实现采用传统的三层架构模型,分为相互独立的客户端、服务器和数据存储三个部分:
我们为MedRec的患者和管理部门程序开发了Web应用程序(webapp),公开对于各自用户的服务。webapp符合模型-视图-控制器(Model-View-Controller)模式,Java Server Page呈现视图给用户,模型封装要呈现给用户和从用户处捕捉而来的数据,而控制器机制则管理除与服务层的交互之外的组件交互。MedRec采用Jakarta Struts来实现该模式。 服务层提供服务给发出请求的客户端,并管理与后端应用程序和资源的交互。MedRec的服务层采用Session Facade模式来封装业务逻辑和业务数据。Session Facade通过提供一个到分布式服务的接口,简化了应用程序的复杂性。在MedRec中,Session Facade的首要责任是提供数据吞吐量。在MedRec的J2EE和WebLogic Server版本中,Session Facade被开发为无状态的会话Enterprise JavaBean,而数据则是由实体Enterprise JavaBean来管理的。 为了与外部实体接合,MedRec通过Web服务公开应用程序功能,从而允许不同系统之间使用一系列开放标准动态交互。通过Web 服务公开服务使得MedRec能够为独立的各方提供数据,或接收来自各方的数据,这样就实现了集中式医疗记录管理的主要目标。 图1所示为Java EE和WebLogic版MedRec的高级架构示意图。
图1:Java EE和WebLogic版MedRec架构示意图 使用Spring重新表示MedRec为了使Spring能够利用WebLogic Server的企业级特性,我们重新设计了MedRec的架构,以相应的Spring组件替换核心Java EE组件。基于Spring的MedRec版本(MedRec-Spring)复制了与原版MedRec相同的功能。 反向控制 MedRec-Spring的最显著的变化是引入了Spring IoC。IoC方法功能强大,通过一个容器将依赖性注入到配置好的组件注入中而应用。IoC解耦了应用程序代码和它的配置。例如,对象与它们的依赖性无关,因此,可以专注于其职责。对于MedRec-Spring中,诸如DataSource、JMS 服务、MBean 连接和对等服务等企业资源在运行时被提供给 MedRec-Spring的对象。另外,通过迁移资源配置和在已编译代码外进行引用,应用程序从特定于开发的资源向中间的生产资源和环境的转移更加易于管理。 我们发现,要正确使用IoC,应用程序代码需要遵循更严格的Java编程规则——特别是在编写接口的代码时。接口比其他东西更能促进更好的协作,因为可以减轻依赖性,而且实现的变化被隔离开来。从IoC的角度看,接口支持依赖注入的可插入本性。为了利用IoC,我们对MedRec-Spring进行了重构,这样就可以基于接口对业务对象进行编码。 POJO 在MedRec-Spring中,Plain Old Java Objects(POJO)代替了无状态会话 EJB。无状态会话 EJB的强大在于它们的远程控制和事务管理功能。因为MedRec-Spring通过Spring的HTTP Invoker架构公开了服务bean,所以它能够满足远程控制的要求。事务管理是由Spring的事务抽象层提供的。MedRec-Spring的事务管理精确地映射了MedRec的事务管理,因为Spring事务管理器被配置为把责任委托给WebLogic Server的JTA事务管理器。 消息收发 MedRec-Spring包含了原始MedRec的大多数消息收发功能。采用Spring的 JMS包简化了一些一般性任务,如连接工厂和目的站查找。Spring提供了一个代表消息收发目的站的对象,而不是通过程序获取队列句柄。和所有的Spring beans一样,这些对象表示(JNDI名称、连接工厂关联等)是在已编译代码的外部配置的。。我们还在三个方面使用了Spring 2.0的 Message-Driven POJO(MDP)作为JMS消息的目标:
AOP MedRec-Spring使用Spring AOP主要有两个目的:
JPA 现在MedRec-Spring使用JPA访问和写入患者纪录。更多细节请见 结合SPRING 2.0使用JAVA PERSISTENCE API。 应用程序管理 MedRec-Spring包含应用程序管理特性。这些特性与WebLogic Server的域配置以及运行时域交互。MedRec-Spring必须按照WebLogic Server的 MBean Server形式,Spring提供了连接管理,简化了MBean Server的可访问性。 Web Services 最后,MedRec-Spring使用Web services输出它的服务。Spring提供一个JAX-RPC 工厂生成Web服务的代理。类似于其他Spring bean,工厂bean也是在已编译的代码外部配置的,使得应用程序更加灵活。 图2所示为基于Spring的MedRec版本的高级架构示意图。
图2. 基于Spring的MedRec版本的高级架构图 WebLogic Server上的Spring最佳实践 比较了Java EE与Spring环境上的MedRec架构之后,现在我们来介绍在实现MedRec-Spring应用程序过程中发现的一些宝贵经验:
Spring on WebLogic Server工具包为了帮助用户从部署在WebLogic Server上的Spring应用程序得到最大的收获,我们已经发布了一个经过认证的BEA发行版,包括Spring 2.0、MedRec on Spring应用程序和其他的一些不错的工具。您可以从BEA 的 发行版Web站点 上免费下载这个工具包。 企业Spring Spring Framework的非侵入性IoC开发模型不但依赖于Java EE应用服务器可用的特性集,而在旨在补充该特性集。事实上,在要求很高的生产环境中,底层应用服务器基础架构提供的服务质量对Spring应用程序的可靠性、可用性和性能非常重要。WebLogic Server 9.2提供了企业级的特性,能够从各方面增强用户的Spring应用程序。这一节,我们来详述这些特性以及如何在Spring应用程序中利用它们。 集群管理和部署一个WebLogic Server集群包括多个WebLogic Server服务器实例,这些服务器实例同时运行并一起工作,从而提高了可伸缩性和可靠性。对客户端来说,集群就像单个的WebLogic Server实例一样。构成集群的服务器实例既可以运行在同一台机器上,也可以位于不同的机器上。可以通过在现有的机器上向集群添加另外的服务器实例,或者向集群添加机器以驻留增加的服务器实例,来提高集群的容量。WebLogic Server集群为Spring应用程序提供了一个企业级部署平台,WebLogic Server提供的丰富性和易用性是其他支持相似特性的技术所不具有的。关于WebLogic Server集群的配置和管理的完整讨论请见Understanding Cluster Configuration。 通常,Spring应用程序被打包成 webapp形式,在这种情况下,无需为了应用WebLogic Server集群技术而更改自己的应用程序。只需将应用程序部署到集群中的服务器就可体验增强的可伸缩性和可用性带来的好处。 Spring会话复制Spring Web应用程序通常将信息存入HTTP会话,如订单ID和用户信息。为了支持一个集群内的servlet和JSP的自动复制和故障恢复,WebLogic Server支持用于保持HTTP会话状态的 几种机制。简单地通过将用户应用程序提供给一个适当的weblogic.xml部署描述符,它们就能够被Spring Web applications非侵入性地使用。有关WebLogic Server 9.0的更多可用信息,请参见 配置不同的会话持久性。 集群化的Spring远程控制Spring提供强大的远程控制支持,允许用户仍然利用一致的基于POJO的编程模型轻松地导出和使用远程服务。通过一个接合到适当的Spring bean的RMI接口,Vanilla Spring支持代理POJO调用。然而,这种支持仅限于JRMP(Sun的RMI实现),或者通过JndiRmiProxyFactoryBean使用特定的远程接口。借助于Spring 1.2.5 on WebLogic Server 9.0认证,我们已经扩展了JndiRmiProxyFactoryBean和相关的服务导出程序——这样它就能支持任何J2EE RMI实现的POJO代理,包括RMI-IIOP和T3。这方面的支持还包括一个WebLogic RMI部署描述符,它支持代理RMI接口上的集群化,所以POJO调用可以跨一个WebLogic Server集群进行负载均衡。客户端上这种支持的配置与此相似(applicationContext.xml)。
<bean id="proProxy"
class="org.springframework.remoting.rmi.JndiRmiProxyFactoryBean">
<property name="jndiName" value="t3://${serverName}:${rmiPort}/order"/>
</property>
<property name="jndiEnvironment">
<props>
<prop key="java.naming.factory.url.pkgs">
weblogic.jndi.factories
</prop>
</props>
</property>
<property name="serviceInterface"
value="org.springframework.samples.jpetstore.domain.logic.OrderService"/>
</bean>
服务导出程序如下(同样来自applicationContext.xml):
<bean id="order-pro" class="org.springframework.remoting.rmi.JndiRmiServiceExporter">
<property name="service" ref="petStore"/>
<property name="serviceInterface"
value="org.springframework.samples.jpetstore.domain.logic.OrderService"/>
<property name="jndiName" value="order"/>
</bean>
集群化的描述符是自动包含在内的,仅仅要求适当的集群配置和Spring应用程序在所有集群成员上部署。参见 故障恢复支持,可以获得更多信息。 对Spring组件的控制台支持Spring on WebLogic Server工具包中包含一个WebLogic Server控制台扩展,它显示了应用程序中定义的Spring bean、属性和操作。它构建在WebLogic控制台扩展门户框架之上,这一框架能够变换WebLogic Administration控制台的外观、功能和布局,而无需修改服务器或控制台代码。将控制台扩展复制到yourdomain/console-ext目录下,则重新启动服务器时就部署了控制台扩展。关于部署控制台扩展的更多细节,请参考Spring on WebLogic Server工具包。 控制台扩展为不是MBean的Spring bean自动创建(JMX)管理接口(对于多数Spring beans,通常就是这样),通过在applicationContext.xml中配置一个MBeanExporter并指定经汇编器公开的bean来完成。这一特性是Spring和WebLogic Server无缝地、非侵入性协作的一个极好的例证。为了使Spring应用程序支持JMX,只需要更改以应用程序上下文部署描述符。为了使控制台支持Spring,只需要将两个jar部署到已有域即可。 为了在WebLogic Server Administration控制台启动Spring Console扩展,需要两个jar文件;它们作为Spring WebLogic包的一部分提供。具体来说,这两个jar文件称为spring-ext-server.jar和spring-ext-client.jar。spring-ext-server.jar需要复制到yourdomain/console-ext目录。相关的spring-ext-client.jar文件需要和 Web应用程序一道部署。(如果是.WAR文件,则将spring-ext-client.jar放入Web应用程序的 WEB-INF/lib目录。) 有了这两个文件后,剩下的工作就是在Spring XML配置文件中定义几个 bean。第一个Spring bean是绝对要定义的,它是com.interface21.wl9.jmx.mediator.Mediator。这个bean(顾名思义)介于用户应用程序、WebLogic Server的 MBeanServer和Administrative控制台三者之间。它的定义如下所示,非常简单: <!-- WLS console adapter bean --> <bean id="consoleAdapter" class="com.interface21.wl9.jmx.mediator.Mediator"/> 这个bean必须被“插入”(或说依赖性注入)第二个bean,即MBeanExporter,它也是绝对必须进行配置的。MBeanExporter 类交付的成果就是将Spring应用程序上下文中已定义的任何数量的异构bean简单地导出到BEA WebLogic MBeanServer(或者任何配置好的MBeanServer)。注意,MBeanServer导出的那些bean无需为JMX而进行编码。Spring JMX基础架构代码负责生成ModelMBean来描述通过JMX的用于管理而导出的bean。下面是一个典型的上下文配置文件的MBeanExporter bean定义:
<bean id="exporter" class="org.springframework.jmx.export.MBeanExporter">
<property name="assembler" ref="assembler"/>
<property name="server" ref="server"/>
<property name="beans">
<map>
<!-- these are the beans that are to be exported... -->
<entry key="my_app_name:type=MaintenanceControl"
value-ref="maintenanceInterceptor"/>
<entry key="my_app_name:type=ExceptionMonitor"
value-ref="exceptionHandler"/>
<entry key="my_app_name:type=RequestStatistics"
value-ref="requestStatisticsFilter"/>
</map>
</property>
<property name="registrationBehaviorName"
value="REGISTRATION_REPLACE_EXISTING"/>
<property name="autodetect" value="true"/>
<property name="listeners">
<list>
<!-- notice how we 'plug-in' the Mediator bean
that was defined previously... -->
<ref bean="consoleAdapter"/>
</list>
</property>
</bean>
注意上面的bean定义,另一个bean('assembler')被注入MBeanExporter的 'assembler'属性。下面是它的定义:
<bean id="assembler" class="org.springframework.jmx.export.assembler.InterfaceBasedMBeanInfoAssembler">
<property name="interfaceMappings">
<props>
<prop key="my_app_name:type=MaintenanceControl">fully.qualified.management.interface.name</prop>
<prop key="my_app_name:type=ExceptionMonitor">fully.qualified.management.interface.name</prop>
<prop key="my_app_name:type=RequestStatistics">fully.qualified.management.interface.name</prop>
</props>
</property>
</bean>
描述Spring JMX提供的所有内容超出了本文的范围。这样说就够了:上面定义的InterfaceBasedMBeanInfoAssembler bean是一个可能的策略,用以控制用户bean的哪些方法和属性实际地公开出来供管理之用,就像JMX操作和属性那样。InterfaceBasedMBeanInfoAssembler使用(任意地)接口决定公开哪些方法和属性。更多信息请查本文最后的参考资料一节。 记录在MBeanExporter的bean定义上的第二个属性是server属性。这是向MBeanExporter注入一个WebLogic Server的 MBeanServer实例的地方。MBeanExporter将输出所有已配置的bean到这一指定的服务器。下面是这个bean的定义: <!-- WebLogic 9 MBeanServer --> <jndi:jndi-lookup id="server" jndi-name="java:comp/env/jmx/runtime"/> 在server bean的这个定义中,实际上MBeanServer实例源自JNDI(使用为jndiName属性指定的值在上下文中查找)。对于MBeanExporter,MBeanServer源自JNDI的事实没有意义;这个将依赖性注入需要依赖性的对象透明源引是依赖性注入方法的一大附加值(上面所见的易于使用和配置的JndiObjectFactoryBean证明Spring的注入支持是非常高级的)。 最后,最有趣的是,MBeanExporter配置的一部分是beans属性。它是一个(JMX) ObjectNames到bean的一个简单映射,这些bean将导出到先前注入的MBeanServer实例以便管理。选择ObjectName的策略(在这种策略下,您的bean实际上会导出到MBeanServer)是完全可配置的。本例中,所用的缺省策略是简单地使用beans 映射的键作为ObjectName。(见JavaDoc,它是随Spring一起提供的,作为各种ObjectName策略的一个全面纲要。) Web services支持Spring 远程控制功能的另一个方面是它对RPC风格的 Web services的支持。WebLogic Server提供了基于Ant的工具,来根据Web服务的描述生成JAX-RPC存根。Web服务客户端利用这些生成的存根获取一个表示服务器端操作的远程接口。Spring提供一个JaxRpcPortProxyFactoryBean简化了这个过程。 我们发现,在WebLogic Server环境中正确地配置JaxRpcPortProxyFactoryBean有些棘手,所以为了节约您的时间,我们给出下面这个代码片断,演示如何为一个包含复杂类型的Document Literal包装的Web服务配置代理生成。 多数属性是自解释的。有几个比较有名:
在JaxRpcPortProxyFactoryBean上设置lookupServiceOnStartup为false,即可在启动时关闭JAX-RPC服务查找。当首次访问时,将会进行查找。这对于与可靠的WebLogic Server请求/响应Web services通信是必须的,而此处的客户端也必须是一个Web服务。在这些情况下,始发客户端通常是与Web服务客户端一起部署的。因为应用程序部署完成前不会激活Web服务,所以对于Spring上下文加载,客户端Web服务是不可用的。如下代码摘录自一个applicationContext-ws.xml上下文配置文件:
<!-- reliable asynchronous Web service for sending new medical records to medrec -->
<bean id="reliableClientWebServicesPortType"
class="org.springframework.remoting.jaxrpc.JaxRpcPortProxyFactoryBean"
lazy-init="true">
<property name="wsdlDocumentUrl"
value="http://${WS_HOST}:${WS_PORT}/ws_phys/PhysicianWebServices?WSDL"/>
<property name="portName" value="PhysicianWebServicesPort"/>
<property name="jaxRpcService">
<ref bean="generatedReliableService"/>
</property>
<property name="serviceInterface"
value="com.bea.physician.webservices.client.PhysicianWebServicesPortType"/>
<property name="username" value="medrec_webservice_user"/>
<property name="password" value="weblogic"/>
<property name="customProperties">
<props>
<prop key="weblogic.wsee.complex">true</prop>
</props>
</property>
</bean>
<!-- allows the jaxRpcService class to execute its constructor which loads in type mappings -->
<bean id="generatedReliableService"
class="com.bea.physician.webservices.client.PhysicianWebServices_Impl">
</bean>
参见WebLogic Server的 Overview Web Services Invocation 和 Remoting and Web Services Using Spring,可以获得更多相关信息。 安全性WebLogic Server安全系统支持并扩展了Java EE的安全性,提供了一组丰富的安全提供程序,可以对其进行定制,来处理不同的安全性数据库或安全性策略。除了使用标准的Java EE安全性之外,应用程序编程人员还能够使用很多专有扩展,这些扩展使应用程序可以与安全系统紧密集成。WebLogic Server带有几个安全提供程序,例如,可以选择包含大部分流行LDAP服务器的身份验证数据库、Active Directory、本地Windows和一个内置的身份验证解决方案。可以使用定制的提供程序对内置的提供程序进行扩充,从而几乎可以与任意身份验证数据库、授权机制和凭证映射服务相集成。因为部署为webapp的Spring应用程序使用的是Java EE安全性,所以无需修改应用程序就可以获得WebLogic Server的安全性优点。 经验丰富的Spring用户还会熟悉Acegi——Spring自身的安全框架。目前,可以在应用程序中使用Acegi、WebLogic Server安全性,或同时使用二者,因为它们是相互独立的。稍后我们将讲述与此相关的更多信息。 分布式事务Spring提供事务管理的基础架构。除了对各家数据库供应商的支持之外,Spring还通过一家 Java EE 供应商的JTA实现支持分布式事务。通过WebLogicJtaTransactionManager,可以把Spring的JTA管理器配置为与WebLogic Server的JTA实现一起工作。 WebLogicJtaTransactionManager直接向WebLogic Server Java Transaction API委托责任。通过JNDI,客户端和bean提供者可以使用WebLogic Server JTA TransactionManager接口,这一交互由Spring管理。事务管理器也支持事务的作用域;事务能够作用于集群和域的内部或二者之间。 WebLogicJtaTransactionManager最强大的特性是管理分布式事务的能力和用于企业应用程序的两阶段委托协议。使用WebLogicJtaTransactionManager,应用程序能够利用WebLogic Administration Console来进行事务监控。WebLogicJtaTransactionManager还支持按数据库隔离级别,允许复杂的事务处理配置。下面的代码节选自applicationContext-service.xml:
<bean id="serviceFacade" class="com.bea.medrec.web.service.ServiceFacadeImpl">
<!-- .... -->
</bean>
<!-- spring's transaction manager delegates to WebLogic Server's transaction manager -->
<bean id="transactionManager" class="org.springframework.transaction.jta.WebLogicJtaTransactionManager"> <property name="transactionManagerName" value="javax.transaction.TransactionManager"/>
</bean>
<aop:config>
<aop:advisor advice-ref="txAdvice"
pointcut="execution(* com.bea.medrec.web.service.ServiceFacade.*(..))"/>
</aop:config>
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="activate*" propagation="REQUIRED"/>
<tx:method name="deny*" propagation="REQUIRED"/>
<tx:method name="update*" propagation="REQUIRED"/>
<tx:method name="process*" propagation="REQUIRED"/>
<tx:method name="get*" propagation="REQUIRED" read-only="true"/>
<tx:method name="search*" propagation="REQUIRED" read-only="true"/>
<tx:method name="saveRecord" propagation="REQUIRED"/>
<!-- ... -->
</tx:attributes>
</tx:advice>
如需了解更多信息,请参见Overview of Transactions in WebLogic Server Applications 和 在Spring中实现事务挂起。 消息驱动POJO消息驱动POJO(MDP)替代了Java EE的消息驱动Bean(MDB)。与POJO类似,它们的优势也是不要求任何特定于平台的API扩展或scaffolding。仅仅需要标准的JMS API实现:
public class RegistrationMessageListener implements MessageListener {
public void onMessage(Message message) {
// Fetch Registration information from ObjectMessage.
// Process new reg by invoking service (DI)
// ... }
}
与 Spring的大多数成员一样,MDP容器的配置当然也很简单。下面的代码节选自applicationContext-jms.xml:
<!-- JMS ConnectionFactory and Queue -->
<jndi:jndi-lookup id="jmsConnectionFactory" jndi-name="com.bea.medrec.messaging.MedRecQueueConnectionFactory"/>
<jndi:jndi-lookup id="registrationQueue" jndi-name="com.bea.medrec.messaging.RegistrationQueue"/>
<!-- MDP -->
<bean id="registrationMessageListener" class="com.bea.medrec.service.messaging.RegistrationMessageListener">
<!-- ... properties... -->
</bean>
<!-- MDP container -->
<bean id="registrationMessageListenerContainer"
class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory" ref="jmsConnectionFactory"/>
<property name="concurrentConsumers" value="5"/>
<property name="destination" ref="registrationQueue"/>
<property name="messageListener" ref="registrationMessageListener"/>
<property name="transactionManager" ref="transactionManager"/>
</bean>
关于在WebLogic Server上实现MDP的更多详细讨论请见 这里。 JPA和AOP的配置我们已经定义了一个Web服务层,它允许我们在RMI、Spring HTTP invoker、Hessian/Burlap和JAXPRC之间轻松切换Web服务实现。当调用远程服务时,如果想要使用一种可序列化机制传递对象,那么这些对象本身必须可序列化。遗憾的是,OpenJPA的 Find结果是一个私有的List实现,不支持Serializable,所以我们需要将这些List与一些更合适的List绑定,如Java SE集合库的ArrayList或LinkedList。我们可以使用spring aop,不必修改应用程序源代码:
@Aspect
public class ReturningValuePostProcessorAspect {
@Pointcut("execution(java.util.List com.bea.medrec.dao.PatientDao.*(..))")
public void postProcessPatientDao() {
}
@Pointcut("execution(java.util.List com.bea.medrec.dao.RecordDao.*(..))")
public void postProcessRecordDao() {
}
@Pointcut("execution(java.util.List com.bea.medrec.dao.UserDao.*(..))")
public void postProcessUserDao() {
}
}
下面是相关联的ReturningValuePostProcessor类。
@Aspect
public class ReturningValuePostProcessor {
public ReturningValuePostProcessor() {
}
@Around("com.bea.medrec.dao.jpa.ReturningValuePostProcessorAspect.postProcessPatientDao()")
public Object postProcessPatientDao(ProceedingJoinPoint pjp) throws Throwable {
return doPostProcess(pjp);
}
@Around("com.bea.medrec.dao.jpa.ReturningValuePostProcessorAspect.postProcessRecordDao()")
public Object postProcessRecordDao(ProceedingJoinPoint pjp) throws Throwable {
return doPostProcess(pjp);
}
@Around("com.bea.medrec.dao.jpa.ReturningValuePostProcessorAspect.postProcessUserDao()")
public Object postProcessUserDao(ProceedingJoinPoint pjp) throws Throwable {
return doPostProcess(pjp);
}
private Object doPostProcess(ProceedingJoinPoint pjp) throws Throwable {
Object retVal = pjp.proceed();
if (retVal == null) {
return null;
}
if (!(retVal instanceof List)) {
return retVal;
} else {
//noinspection unchecked
return new ArrayList((List) retVal);
}
}
}
下面的代码节选自applicationContext-jpa.xml: <bean id="patientDao" class="com.bea.medrec.dao.jpa.PatientDaoImpl"/>: <bean id="recordDao" class="com.bea.medrec.dao.jpa.RecordDaoImpl"/>: <!-- ... -->: <bean id="returningValuePostProcessor" class="com.bea.medrec.dao.jpa.ReturningValuePostProcessor"/>: <aop:aspectj-autoproxy/>: Java Management ExtensionJava Management Extension(Java管理扩展,JMX)是Java应用程序监控和管理规范。它允许一般的管理系统监控应用程序,挡应用程序需要注意时发出通知,并修改应用程序状态以补救问题。Spring提供广泛的JMX支持,包括通过Spring MBeanServerConnectionFactoryBean公开WebLogic Server的 MBeanServer的能力。MBeanServerConnectionFactoryBean是一个方便的工厂,附带一个MBeanServerConnection。在应用程序部署期间,连接建立并被缓存,以后由引用bean进行操作。 可以配置MBeanServerConnectionFactoryBean返回WebLogic Server的 Runtime MBean Server,公开特定的WebLogic Server实例的监视、运行时控制和活动配置。这包括访问WebLogic Server Diagnostics Framework。此外,Runtime MBean为当前服务器提供runtime MBean和活动配置MBean的访问。还可以配置MBeanServerConnectionFactoryBean,获得到WebLogic Server的Domain Runtime MBean Server的连接。Domain Runtime MBean Server提供域范围内服务的访问,如应用程序部署、JMS服务器和JDBC数据源。它还是访问域中所有服务器的所有runtime MBean和活动配置MBean的层次结构的单点。这个MBean Server也是访问被管理服务器上的MBean的单点。 此外,可以配置MBeanServerConnectionFactoryBean获取与WebLogic Server的 Edit MBean Server的连接。Edit MBean Server提供管理当前WebLogic Server域配置的入口点。 注意,在部署期间,WebLogic Server的 Domain Runtime MBean Server不是活动的。所以,bean需要使用Spring的延迟初始化(lazy initialization)进行配置,它会在调用bean时获取该bean。 下面是使用WebLogic MBean Server配置Spring MBeanServerConnectionFactoryBean连接的一个例子:
<!-- expose WebLogic Server's runtime mbeanserver connection -->
<bean id="runtimeMbeanServerConnection"
class="org.springframework.jmx.support.MBeanServerConnectionFactoryBean">
<property name="serviceUrl" value="service:jmx:t3://${WS_HOST}:${WS_PORT}/jndi/weblogic.management.mbeanservers.runtime"/>
<property name="environment">
<props>
<prop key="java.naming.security.principal">
${WS_USERNAME}</prop>
<prop key="java.naming.security.credentials">
${WS_PASSWORD}</prop>
<prop key="jmx.remote.protocol.provider.pkgs">
weblogic.management.remote</prop>
</props>
</property>
</bean>
如需获得更多信息,请参见 Understanding WebLogic Server MBeans 和Spring JMX Support。 支持从 WebLogic Server 9.0和Spring 1.2.5开始,BEA就为Spring Framework on WebLogic Server提供了支持和认证。这种支持不仅是测试WebLogic Server上的Spring库的健全性,还致力于BEA和Interface 21——Spring Framework的创建者和维护者之间的积极努力和协作。我们不但测试了上面所讲的Spring 2.0的所有特性和配置,一些新特性还是直接作为BEA和Interface 21的协作成果引入Spring 2.0的。 下载Spring Open Source Framework Support 2.0 download 包括Spring 2.0(已在WebLogic Server 9.2上经过验证)和Spring-JMX控制台扩展以及利用Spring 2.0 Framework重新编写的WebLogic Medical Records示例程序。 未来的工作今后,我们计划提供WebLogic Server和Spring Framework的更深层次的集成。我们有了一些想法,其中最令人感兴趣的是:
结束语我们用了一些时间讨论了Spring、WebLogic Server和这两种技术的集成。如我们所展示的那样,WebLogic Server增强了应用程序的服务质量,Spring则提高了开发人员的生产力。这两种技术都是高度非侵入性的,允许您专注于应用程序的业务功能的开发,而不是纠缠于特定于技术的API的错综复杂性。 参考资料
|
|
| 最近更新 ( 2007-11-29 06:21:26 ) | |



