Spring 2.0.1 与 BEA WebLogic Server 9.2 的集成
页面: 1, 2, 3, 4

安全性

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 扩展或结构。它们只需要标准的 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 调用程序、Hessian/Burlap 和 JAXPRC 之间轻松切换 Web 服务实现。调用远程服务时,如果想要使用一种可序列化的机制传递对象,那么这些对象本身必须可序列化。遗憾的是,OpenJPA 的 Find 结果是一个私有的列表实现,不支持 Serializable,所以我们需要将这些列表与一些更合适的列表绑定,如 Java SE 集合库的 ArrayListLinkedList。我们可以使用 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 管理扩展

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 的延迟初始化进行配置,它会在调用 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 下载包括 Spring 2.0(已在 WebLogic Server 9.2 上经过认证)和 Spring-JMX 控制台扩展以及利用 Spring 2.0 Framework 重新编写的 WebLogic Medical Records 示例程序。

未来的工作

今后,我们计划提供 WebLogic Server 和 Spring Framework 之间更深层次的集成。尽管我们有了一些想法,但其中最令人感兴趣的是:

  • Spring 部署单元: Spring 应用程序通常被部署为 webapp,但今后为 Spring 应用程序提供专用部署单元是可能的。

  • Spring 安全性和 WebLogic Server 安全性集成: Spring 安全性是 Spring 的安全框架,我们计划将它与 WebLogic Server 的企业级安全框架集成。

总结

我们用了一些时间讨论了 Spring、WebLogic Server 以及这两种技术的集成。如我们所展示的那样,WebLogic Server 提高了应用程序的服务质量,Spring 则提高了开发人员的生产力。这两种技术都是高度非侵入性的,允许您专注于应用程序的业务功能的开发,而不是纠缠于特定于技术的 API 的错综复杂性。

参考资料

Andy Piper 是 WebLogic Server 高级开发组的资深工程师。过去 6 年间,Andy 一直致力于 WebLogic Server,并负责许多特性开发和技术创新。