EJBクライアントプロキシ

例えばStatelessSessionBeanのプロキシ設定はstandardjboss.xmlにこんな風に書いてある。


  stateless-rmi-invoker
  jboss:service=invoker,type=jrmp
  org.jboss.proxy.ejb.ProxyFactory
  
    
      
        org.jboss.proxy.ejb.HomeInterceptor
        org.jboss.proxy.SecurityInterceptor
        org.jboss.proxy.TransactionInterceptor
        org.jboss.invocation.InvokerInterceptor
        org.jboss.invocation.MarshallingInvokerInterceptor
      
      
        org.jboss.proxy.ejb.StatelessSessionInterceptor
        org.jboss.proxy.SecurityInterceptor
        org.jboss.proxy.TransactionInterceptor
        org.jboss.invocation.InvokerInterceptor
        org.jboss.invocation.MarshallingInvokerInterceptor
      
    
  

クライアントがRMIで(ローカルでもいいけど)EJBHomeをlookupすると、EJBHomeを実装した動的プロキシがもらえる。beanをcreateすると同じくリモートインターフェースを実装した動的プロキシがもらえる。

StatelessSessionBeanにアクセスするクライアントの動作を見てみる。

JRMPInvokerProxy.invoke(Invocation) line: 105
InvokerInterceptor.invokeInvoker(Invocation) line: 227
InvokerInterceptor.invoke(Invocation) line: 167
TransactionInterceptor.invoke(Invocation) line: 46
SecurityInterceptor.invoke(Invocation) line: 55
StatelessSessionInterceptor.invoke(Invocation) line: 97
ClientContainer.invoke(Object, Method, Object) line: 86
$Proxy1.hello(String) line: not available [local variables unavailable]
TestClient.testBean() line: 49
TestClient.main(String) line: 62

プロキシ-ClientContainer-インタセプタ-JRMPInvokerProxyという流れで処理される。

インタセプタを作ってみる

public class FirstInterceptor extends Interceptor {
  public Object invoke(Invocation invocation) throws Throwable {
    System.out.println(invocation.getMethod());
    return getNext().invoke(invocation);
  }
}

毎度System.out.printlnで萎えるが、ソース読むのが主眼なので…

こんな風に差し込んでやる


  org.jboss.proxy.ejb.StatelessSessionInterceptor
  test.interceptor.FirstInterceptor
  org.jboss.proxy.SecurityInterceptor
  org.jboss.proxy.TransactionInterceptor
  org.jboss.invocation.InvokerInterceptor
  org.jboss.invocation.MarshallingInvokerInterceptor


クラスをクライアント側、サーバ側両方に置かなきゃならんのが面倒。

出力はこんな感じ。

public abstract java.lang.String test.ejb.SimpleEJB.hello(java.lang.String) throws java.rmi.RemoteException
hello !! tokobayashi

1行目がFirstInterceptorによる出力。invocationのメソッド情報。
2行目が本来のEJB呼び出しの返り値を出力したもの。

TODO:サーバサイドでどう管理しているかも調べる