S2Remoting
むらたさんの日記から一連の「S2Remoting サンプル実装」を読ませて頂きました.なるほど〜,随分前からいろいろな構想があったのですね.さすがひがさん...
そんなわけで (どんなわけで?),さっそく採用させて頂こうかと思います.
S2Remoting では共通の Interceptor
を提供し,Connector
によって様々なプロトコルをサポートするということにしましょう.
そんなわけで (どんなわけで?),Interceptor
はこんな感じでどうでしょうか?
package org.seasar.remoting.client; import org.aopalliance.intercept.MethodInvocation; import org.seasar.framework.aop.interceptors.AbstractInterceptor; import org.seasar.framework.container.ComponentDef; import org.seasar.framework.util.ClassUtil; public class RemotingInterceptor extends AbstractInterceptor { protected Connector connector; protected String name; public void setConnector(final Connector connector) { this.connector = connector; } public void setName(final String name) { this.name = name; } public Object invoke(final MethodInvocation invocation) throws Throwable { return connector.invoke(getTargetName(invocation), invocation.getMethod(), invocation.getArguments()); } protected String getTargetName(final MethodInvocation invocation) { if (name != null) { return name; } final ComponentDef componentDef = getComponentDef(invocation); final String componentName = componentDef.getComponentName(); if (componentName != null) { return componentName; } final Class componentClass = componentDef.getComponentClass(); if (componentClass != null) { return ClassUtil.getShortClassName(componentClass); } return ClassUtil.getShortClassName(invocation.getThis().getClass()); } }
ちょっと工夫したのはターゲットの名前を取ってくるところ.この意図は後で.
そして Connector
.
package org.seasar.remoting.client; import java.lang.reflect.Method; public interface Connector { Object invoke(String name, Method method, Object[] args) throws Throwable; }
まぁ,どうということもなく.
そして URL を使う Connector
のための抽象クラス.
package org.seasar.remoting.client; import java.lang.reflect.Method; import java.net.MalformedURLException; import java.net.URL; import java.util.LinkedHashMap; import java.util.Map; public abstract class URLBasedConnector implements Connector { protected URL baseURL; public void setBaseURL(final URL baseURL) { this.baseURL = baseURL; } public Object invoke(final String name, final Method method, final Object[] args) throws Throwable { return invoke(getTargetURL(name), method, args); } protected URL getTargetURL(final String name) throws MalformedURLException { return new URL(baseURL, name); } protected abstract Object invoke(URL targetURL, Method method, Object[] args) throws Throwable; }
ターゲット URL はキャッシュした方がいいかもしれませんが,それはまた後で.ひがさんの構想にあるような複数 URL をサポートする場合は ClusterableURLBasedConnector
とか別途作るって事でそれはまた後で.それから,結局 setBaseUrl(URL)
ではなく setBaseURL(URL)
にしようかと思ってます.URL が複数になった時に Urls
より URLs
の方がカッコいいかなーって思ったので.
ともあれ (JW),このように URLBasedConnector
はベースとなる URL を持ち,RemotingInterceptor
から渡されるサービス (リモートオブジェクト) 名を付加してターゲットとなる URL を求めています.このため,複数のサービスを使う場合でも URL の指定を一カ所にまとめられたりします.そして RemotingInterceptor
はコンポーネント定義からターゲットの名前を取ってくるため,一つのインスタンスを複数のターゲットに適用できます.で,こんな感じ.
<component name="remoting" class="RemotingInterceptor"/> <component class="AxisConnector"> <property name="baseURL">new URL("http://localhost:8080/s2-axis-examples/services/")</property> </component> <component name="foo" class="Foo"> <aspect>remoting</aspect> </component> <component name="bar" class="Bar"> <aspect>remoting</aspect> </component>
いい感じじゃない? (^^;
これ,S2Axis と S2Hessian は楽に対応できますが,S2XmlRpc はちょっと悩ましいかもしれませんね.ターゲット URL に対応する XmlRpcClient
のキャッシュを持つとかしないといけない感じ.
とりあえず,ご意見あればお願いします.
リモーティング関連プロダクトのパッケージ名なんですが,次のように揃えた方がいいかなぁと考えています.
org.seasar.remoting.client
リモーティング共通 (クライアント)org.seasar.remoting.server
リモーティング共通 (サーバ)org.seasar.remoting.axis
Axis (SOAP)org.seasar.remoting.caucho
Hessian / Burlaporg.seasar.remoting.rmi
RMIorg.seasar.remoting.xmlrpc
XmlRpc
なにげに S2XmlRpc はすでに上記のパッケージになっているので,S2Axis と S2Hessian が対応すればいいだけなんですが.
こちらもご意見あればお願いします.
そろそろ Sandbox 申請しようかな...