S2Remotingサンプル実装改造
前回までで、一先ず動作するものができましたが、これから少しずつ手を加えて行く。
また、S2が2.1.1にバージョンアップしたので、環境を更新しました。
気になっている点は以下の2点。
- Adaptorインタフェースとその実装
- 例外処理
1. Adaptorインタフェースとその実装の変更
Adaptorインタフェースとして、Remoteを継承したRmiAdaptorを作成したが、AdaptorインタフェースがRMIの実装に縛られるのはよろしくない気がする。
そこで、純粋にリモートメソッドの呼び出しだけを行うインタフェースを作る。
2. RemoteMethodInvokerインタフェース
package sample.seasar.remoting; import java.rmi.Remote; /** * @author murata */ public interface RemoteMethodInvoker extends Remote { public Object invoke(String targetName, String methodName, Object[] args) throws Exception; }
Connectorインタフェースの実装クラスはこのRemoteMethodInvokerのリモートオブジェクトを取得して、処理を実行するように変更する。
また、Adaptorインタフェースの実装クラスはこのRemoteMethodInvokerのリモートオブジェクトをrmiregistryに登録し、自身のinvokeメソッドを呼ばれるように変更する。
こんなイメージですね。
Interseptor > Connector > RemoteMethodInvoker > Adaptor
Interseptor < Connector < RemoteMethodInvoker < Adaptor
3. Connector
package sample.seasar.remoting; /** * @author murata */ public interface Connector { public Object invoke(String tagetName, String methodName, Object[] args) throws Exception; }
4. ConnectorImpl
package sample.seasar.remoting.impl; import java.rmi.Naming; import java.rmi.RMISecurityManager; import sample.seasar.remoting.Connector; import sample.seasar.remoting.RemoteMethodInvoker; /** * @author murata */ public class RmiConnectorImpl implements Connector { private RemoteMethodInvoker remoteInvoker; public void addURL(String url) throws Exception { if (null == System.getSecurityManager()) { System.setSecurityManager(new RMISecurityManager()); } this.remoteInvoker = (RemoteMethodInvoker) Naming.lookup(url + "/RemoteMethodInvoker"); } /* * (non-Javadoc) * * @see org.seasar.remoting.Connector#invoke(java.lang.String, * java.lang.String, java.lang.Object[]) */ public Object invoke(String targetName, String methodName, Object[] args) throws Exception { return this.remoteInvoker.invoke(targetName, methodName, args); } }
5. Adaptor
AdaptorはRemoteMethodInvokerの導入により、RMIに依存しないインタフェースになります。最初に戻りましたね。
package sample.seasar.remoting; /** * @author murata */ public interface Adaptor { public void setup() throws Exception; public Object invoke(String tagetName, String methodName, Object[] args) throws Exception; }
6. AdaptorImpl
Adaptorインタフェースの実装クラスでは、RemoteMethodInvokerの実装クラスを生成し、invokeメソッドを呼ばれるように自身の参照を渡すように変更する。
あとは、ポート番号を設定できるようにしてみる。
package sample.seasar.remoting.impl; import java.rmi.Naming; import java.rmi.RMISecurityManager; import org.seasar.framework.beans.BeanDesc; import org.seasar.framework.beans.factory.BeanDescFactory; import org.seasar.framework.container.S2Container; import sample.seasar.remoting.Adaptor; import sample.seasar.remoting.RemoteMethodInvoker; /** * @author murata */ public class RmiAdaptorImpl implements Adaptor { private int port = 1099; private S2Container container; /** * @param port The port to set. */ public void setPort(int port) { this.port = port; } /** * @param container * The container to set. */ public void setContainer(S2Container container) { this.container = container; } /* * (non-Javadoc) * * @see sample.seasar.remoting.Adaptor#setup() */ public void setup() throws Exception { if (null == System.getSecurityManager()) { System.setSecurityManager(new RMISecurityManager()); } RemoteMethodInvoker remoteInvoker = new RemoteMethodInvokerImpl(this); Naming.rebind("//localhost:" + this.port + "/RemoteMethodInvoker", remoteInvoker); } /* * (non-Javadoc) * * @see org.seasar.remoting.Adaptor#invoke(java.lang.String, java.lang.String, * java.lang.Object[]) */ public Object invoke(String targetName, String methodName, Object[] args) throws Exception { Object targetObj = this.container.getComponent(targetName); BeanDesc beanDesc = BeanDescFactory.getBeanDesc(targetObj.getClass()); return beanDesc.invoke(targetObj, methodName, args); } }
7. RemoteMethodInvokerImpl
RemoteMethodInvokerインタフェースの実装クラスは、Adaptorの参照を持つようにし、Connectorから呼ばれたら、Adaptorのinvokeメソッドを呼ぶようにします。
package sample.seasar.remoting.impl; import java.rmi.RemoteException; import java.rmi.server.UnicastRemoteObject; import sample.seasar.remoting.Adaptor; import sample.seasar.remoting.RemoteMethodInvoker; /** * @author murata */ public class RemoteMethodInvokerImpl extends UnicastRemoteObject implements RemoteMethodInvoker { private Adaptor adaptor; /** * @throws RemoteException */ public RemoteMethodInvokerImpl(Adaptor adaptor) throws RemoteException { super(); this.adaptor = adaptor; } /* * (non-Javadoc) * * @see sample.seasar.remoting.RemoteMethodInvoker#invoke(java.lang.String, * java.lang.String, java.lang.Object[]) */ public Object invoke(String targetName, String methodName, Object[] args) throws Exception { return this.adaptor.invoke(targetName, methodName, args); } }