Spring 2.0.1とBEA WebLogic Server 9.2の統合
Pages: 1, 2, 3, 4

セキュリティ

WebLogic Serverのセキュリティシステムでは、Java EEのセキュリティ機能をサポートし拡張する一方、さまざまなセキュリティデータベースやセキュリティポリシーに合わせてカスタマイズできる豊富なセキュリティプロバイダを提供します。アプリケーションプログラマは、Java EEの標準セキュリティ機能のほか、アプリケーションをセキュリティシステムと密接に統合できる独自開発の多様な拡張機能も利用できます。WebLogic Serverにはセキュリティプロバイダがいくつか付属しています。例えば、普及しているLDAPサーバの大半を含む認証データベース、Active Directory、ネイティブWindows、組み込み認証ソリューションといった選択肢があります。組み込みプロバイダはカスタムプロバイダで補強して、ほぼすべての認証データベース、認可メカニズム、および資格マッピングサービスと統合できるようになります。WebアプリケーションとしてデプロイされたSpringアプリケーションではJava EEのセキュリティ機能を利用するため、アプリケーションを一切変更せずにWebLogic Serverセキュリティ機能のメリットが得られます。

経験豊かなSpringユーザなら、Spring Securityについてもご存知でしょう。Spring SecurityとWebLogic Serverセキュリティはそれぞれ互いに独立しているため、アプリケーションでは現在、そのいずれか一方、あるいはその両方を利用できます。これについては後で詳しく述べます。

分散トランザクション

Springには、トランザクション管理のインフラストラクチャが用意されています。Springでは、さまざまなデータベースベンダをサポートするほか、Java EEベンダのJTA実装を通じて分散トランザクションもサポートします。SpringのJTAマネージャは、WebLogicJtaTransactionManagerを通じて、WebLogic ServerのJTA実装と連携して動作するように構成することができます。

WebLogicJtaTransactionManagerは、担当するタスクをWebLogic ServerのJava Transaction APIに直接委託します。WebLogic ServerのJTA TransactionManagerインタフェースはJNDIを通じてクライアントやBeanプロバイダで利用でき、そのやり取りはSpringで管理されます。トランザクションマネージャはまた、トランザクションのスコープ(有効範囲)も可能にします。つまり、トランザクションは、クラスタやドメインの内部で動作することも、クラスタやドメインにまたがって動作することもできます。

WebLogicJtaTransactionManagerの最も強力な機能は、エンタープライズアプリケーションの分散トランザクションと2フェーズコミットプロトコルを管理できることです。アプリケーションでは、WebLogicJtaTransactionManagerを利用することで、WebLogic管理コンソールを通じてトランザクション監視を活用できます。また、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>

詳細については、「WebLogic Serverアプリケーションのトランザクションの概要」と「Springにトランザクションの"サスペンション(一時停止)"を装備する」を参照してください。

メッセージ駆動型POJO

メッセージ駆動型POJO(MDP)は、Java EEのメッセージ駆動型Bean(MDB)に代わるものです。MDPには、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のコンフィグレーション

私たちは、RMI、Spring HTTP Invoker、Hessian/Burlap、およびJAXPRCの間で簡単にWebサービスの実装を切り替えることができるWebサービス層を定義しました。リモートサービスを呼び出すときに、直列化可能なメカニズムを使用してオブジェクトを転送したい場合、オブジェクト自体が直列化可能である必要があります。残念ながら、OpenJPAのFind結果はプライベートなList実装であり、Serializableをサポートしないため、Java SEコレクションライブラリのArrayListやLinkedListなど、より適したものでこれらのListをラップする必要があります。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 Extension

JMX(Java Management Extension)は、Javaアプリケーションの監視と管理のための仕様です。それにより、汎用の管理システムでアプリケーションの監視、アプリケーションに注意が必要な場合の通知、およびアプリケーションの状態変更による問題の是正が可能になります。SpringではJMXを幅広くサポートしており、その一環として、SpringのMBeanServerConnectionFactoryBeanを通じてWebLogic ServerのMBeanサーバを公開することができます。MBeanServerConnectionFactoryBeanは、MBeanServerConnectionを副産物として生成するコンビニエンスファクトリです。接続は、アプリケーションのデプロイ時に確立され、参照側のBeanで後で利用できるようにキャッシュされます。

MBeanServerConnectionFactoryBeanは、WebLogic Serverの実行時MBeanサーバを返すように構成することができ、このサーバで特定のWebLogic Serverインスタンスの監視、実行時制御、およびアクティブコンフィグレーションがわかるようになります。これには、WebLogic ServerのDiagnostics Frameworkへのアクセスも含まれます。さらに、実行時MBeanは、実行時MBeanとアクティブコンフィグレーションMBeanへのアクセスを現在のサーバに提供します。

MBeanServerConnectionFactoryBeanはまた、WebLogic Serverのドメイン実行時MBeanサーバへの接続を取得するように構成することもできます。ドメイン実行時MBeanサーバは、アプリケーションのデプロイメント、JMSサーバ、JDBCデータソースなど、ドメイン全体に及ぶサービスの利用許可を提供します。また、ドメイン内の全サーバのすべての実行時MBeanとすべてのアクティブコンフィグレーションMBeanの階層に対する単一のアクセスポイントにもなります。このMBeanサーバはまた、管理対象サーバ上に存在するMBeanへの単一のアクセスポイントの役目も果たします。

さらに、MBeanServerConnectionFactoryBeanは、WebLogic Serverの編集MBeanサーバへの接続を取得するように構成することもできます。編集MBeanサーバは、現在のWebLogic Serverドメインのコンフィグレーションを管理するためのエントリポイントとなります。

WebLogic Serverのドメイン実行時MBeanサーバはデプロイ時にはアクティブでないことに注意してください。このため、BeanはSpringの遅延初期化を用いて構成する必要があり、その場合、Beanは呼び出されたときにフェッチされます。

WebLogic ServerのMBeanサーバで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>

詳細については、「WebLogic Server MBeanについて」とSpringの「 JMX Support」(英語)を参照してください。

サポート

BEAでは、WebLogic Server 9.0とSpring 1.2.5を出発点として、WebLogic Server版Spring Frameworkのサポートと動作認定を利用できるようにしています。このサポートは、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 MedRecサンプルアプリケーションが含まれています。

今後の取り組み

今後、私たちはWebLogic ServerとSpring Frameworkとの統合をさらに深めていく予定です。アイデアはいくつかありますが、その中で最も興味深いものをいくつか以下に挙げておきます。

  • Spring デプロイメントユニット:Springアプリケーションは通常Webアプリケーションとしてデプロイされますが、Springアプリケーション専用のデプロイメントユニットを用意することも可能でしょう。
  • Spring Security WebLogic Server セキュリティ機能の統合:Spring SecurityはSpringのセキュリティフレームワークですが、これをWebLogic Serverのエンタープライズクラスセキュリティフレームワークと統合する予定です。

まとめ

この記事では、少し時間を割いて、Spring、WebLogic Server、およびこれら2つのテクノロジの統合について見てきました。その中で示したように、Springは開発者の生産性向上を可能にする一方、WebLogic Serverはアプリケーションのサービス品質の向上を可能にします。両テクノロジはきわめて非侵襲的であるため、テクノロジ固有のAPIに関する複雑な事がらに忙殺されるのではなく、アプリケーションのビジネス機能の開発に専念することができます。

参考資料