Seasar DI Container with AOP

概要

S2RMIはS2RemotingのRMIによる実装です。 S2RMIを使うと、異なるJavaVM上のS2Containerに定義されているコンポーネント(POJO)を簡単に呼び出すことができます。

セットアップ

前提条件

S2RMI S2 S2Remoting
1.0.0 2.1.11〜 0.0.7〜

実行環境

S2RMIを実行するには、以下のものが必要です。

  • JDK (J2SE SDK) 1.4以降が必要です。S2RMI-V1.0.0の開発とテストはJDK 1.4.2_08で行っています。 ダウンロードはこちら
  • S2の2.1.11以降が必要です(J2SE5.0ではS2.2以降が必要です)。S2RMI-V1.0.0の開発とテストはS2.2.7で行っています。 ダウンロードはこちら
  • S2Remotingの0.0.7以降が必要です。S2RMI-V1.0.0の開発とテストはS2Remoting1.0.0で行っています。 ダウンロードはこちら

開発環境

S2RMIのディストリビューションは、他のS2関連プロダクトの多くと同様、Eclipse Javaプロジェクトをアーカイブしたものとなっています。

  • Eclipse3.0以降が必要です。ダウンロードはこちら
  • S2の2.1.11以降が必要です。ダウンロードはこちら
  • S2Remotingの0.0.7以降が必要です。ダウンロードはこちら

ダウンロード

S2RMIはこちらからダウンロードすることができます。

インストール

事前にS2およびS2RemotingがEclipseワークスペースにインポートされている必要があります。

  • ダウンロードしたS2RMI-Vx.y.z.zipファイルを適当なディレクトリに解凍してください。
  • Eclipseを起動し、「ファイル」−「インポート」メニューを選択してください。
  • 「インポート」ウィザードで「既存プロジェクトをワークスペースへ」を選択し、「次へ」をクリックしてください。
  • 「参照」ボタンをクリックし、解凍したディレクトリにできているs2-rmiディレクトリを選択し、「OK」ボタンをクリックします。
  • 「終了」ボタンをクリックします。

基本的な使い方

ここではS2RMIに含まれるsrc/example以下の例を使って、S2RMIの使い方を説明します。 S2RMIはS2Containerに登録されているコンポーネントを簡単にリモートオブジェクト化します。 service.Helloインタフェースは普通のインタフェースです。 また、service.impl.HelloImplクラスはHelloインタフェースの実装クラス(POJO)です。 このHelloインタフェースとその実装クラスをS2RMIを使って、リモートオブジェクトとして公開します。

サービス

service.Hello.java

public interface Hello {
    public String say();
}

service.impl.HelloImpl.java

public class HelloImpl implements Hello {
    public String say() {
        return "Hello";
    }
}

サーバ側の設定

サーバ側の設定方法について説明します。サーバ側のdiconファイルに定義すべきコンポーネントは次の3つです。

  • org.seasar.remoting.rmi.adaptor.RMIAdaptorImpl
  • org.seasar.remoting.rmi.deployer.RMIAdaptorDeployer
  • service.impl.HelloImpl(リモートオブジェクトとして公開するインタフェースの実装クラス)
 RMIAdaptorImplクラスはComponentInvokerImplクラスを利用して、S2Containerに登録されているコンポーネントを呼び出すアダプタです。 RMIAdaptorDeployerはRMIAdaptorImplクラスをRMIレジストリに登録します。

server.dicon

<components>
  <component name="rmiAdapptor" class="org.seasar.remoting.rmi.adaptor.RMIAdaptorImpl">
    <property name="invoker">
      <component class="org.seasar.extension.component.impl.ComponentInvokerImpl"/>
    </property>
  </component>

  <component class="org.seasar.remoting.rmi.deployer.RMIAdaptorDeployer">
    <property name="adaptor">rmiAdapptor</property>
    <property name="registryPort">1108</property>
    <property name="servicePort">1109</property>
    <initMethod name="deploy"/>
  </component>

  <component name="hello" class="service.impl.HelloImpl"/>
</components>

RMIAdaptorDeployerのプロパティ

<property name="registryPort">
rmiregistry のポート番号。設定を省略するとデフォルトポート(1099)を使用します。
<property name="servicePort">
RMIAdaptorImplが使用するポート番号。設定を省略するとデフォルトポート(0)になり、匿名ポートが使用されます。

RMIAdaptorDeployerの起動

diconファイルに<initMethod name="deploy"/>を定義することにより、S2Containerを初期化することで、S2Container上のコンポーネントをリモート呼び出しできるようにします。 以下のServerMainクラスはその例です。

server.ServerMain.java

package server;

import org.seasar.framework.container.S2Container;
import org.seasar.framework.container.factory.S2ContainerFactory;
import org.seasar.remoting.common.deployer.Deployer;

public class ServerMain {
    public static void main(String[] args) {
        S2ContainerFactory.create("server/server.dicon").init();
    }
}

ServerMainを実行するには、パッケージ・エクスプローラーからServerMain.javaを選択し、右クリックから「実行」−「Javaアプリケーション」を行ってください。

クライアント側の設定

クライアント側の設定方法について説明します。クライアント側のdiconファイルに定義すべきコンポーネントは次の3つです。

  • org.seasar.remoting.rmi.connector.RMIConnector
  • org.seasar.remoting.common.interceptor.RemotingInterceptor
  • service.Hello(リモートオブジェクトとして呼び出すインタフェース)
 RMIConnectorクラスはRMIレジストリからRMIAdaptorImplクラスのスタブを取得し、サーバ側のコンポーネントを呼び出します。 RemotingInterceptorクラスはRMIConnectorを利用してリモートオブジェクトとして呼び出すインタフェース(Hello)にAOPとして設定します。 リモートオブジェクトを呼ぶ側と呼ばれる側のコンポーネント名称(hello)の定義は同じにする必要があります。

S2RMIはS2Remotingのひとつの実装であるため、RemotingInterceptorに設定するコネクタをS2RMIのRMIConnectorからS2Axisの org.seasar.remoting.axis.connector.AxisConnectorに変更することで、S2Axisによって公開されているリモートオブジェクトを呼び出すことができます。 S2Axisによるサーバ側の定義方法についてはこちらを参照して下さい。

clinet.dicon

<components>
  <component name="rmiConnector" class="org.seasar.remoting.rmi.connector.RMIConnector">
    <property name="baseURL">new java.net.URL("rmi://localhost:1108/")</property>
    <initMethod name="lookup"/>
  </component>

  <component name="remoting" class="org.seasar.remoting.common.interceptor.RemotingInterceptor">
    <property name="connector">rmiConnector</property>
  </component>

  <component name="hello" class="service.Hello">
    <aspect>remoting</aspect>
  </component>
</components>

リモートオブジェクトのメソッド呼び出し

クライアント側ではRemotingInterceptorをAOPとして定義したインタフェース(Hello)のメソッドを呼び出すと

Hello.say() -> RMIConnector -> RMIAdaptor -> ComponentInvoker -> HelloImpl.say()
という流れでリモート呼び出しを行います。以下のClientMainクラスはその例です。

client.ClientMain.java

package client;

import org.seasar.framework.container.S2Container;
import org.seasar.framework.container.factory.S2ContainerFactory;
import service.Hello;

public class ClientMain {
    public static void main(String[] args) {
        S2Container container = S2ContainerFactory
                .create("client/client.dicon");
        container.init();
        Hello hello = (Hello) container
                .getComponent(service.Hello.class);

        System.out.println(hello.say());
    }
}

ClientMainを実行するには、パッケージ・エクスプローラーからClientMain.javaを選択し、右クリックから「実行」−「Javaアプリケーション」を行ってください。

カスタム RMI ソケットファクトリの設定

RMIAdaptorDeployerにはRMIClientSocketFactory、RMIServerSocketFactoryの実装クラスを設定することができます。

RMIAdaptorDeployerの詳細定義

  <component class="org.seasar.remoting.rmi.deployer.RMIAdaptorDeployer">
    <property name="adaptor">rmiAdapptor</property>
    <property name="registryPort">1108</property>
    <property name="servicePort">1109</property>
    <initMethod name="deploy"/>
    <initMethod name="addCustomSocketFactory">
      <arg>
        <component class="server.rmisocfac.XorClientSocketFactory">
          <arg>0xAC</arg>
        </component>
      </arg>
      <arg>
        <component class="server.rmisocfac.XorServerSocketFactory">
          <arg>0xAC</arg>
        </component>
      </arg>
    </initMethod>
  </component>