1

ProxyFactoryBean と MethodInterceptor を使用して複数のサービス インターフェイスをインターセプトする場合、サービス インターフェイスのメソッド名が同じ場合、インターセプターは何らかの理由でサービス インターフェイスを混同します。私の質問は次のとおりです。

1.)単一の ProxyFactoryBean で複数のインターフェースをインターセプトするときに守るべき規則はありますか?

2.)コードのどこが間違っていますか? 「proxyInterfaces」リストで、AnotherService と AService の順序を入れ替えてみましたが、それもうまくいきません。

3.) ProxyFactoryBean を 2 つに分割して問題を解決しました (下部の「回避策」を参照)。それが唯一の解決策ですか、それとも「コード」セクションで説明されているように ProxyFactoryBean を保持できる方法はありますか?

コード:

ProxyFactoryBeanでインターセプトしているサービスがいくつかあります。

<bean name="MyInterceptor" class="com.test.MyInterceptor">

<bean class="org.springframework.aop.framework.ProxyFactoryBean">
  <property name="interceptorNames">
    <list>  
      <value>MyInterceptor</value>
    </list>
  </property>
  <property name="proxyInterfaces">
    <list>
     <value>com.test.AService</value>
     <value>com.test.AnotherService</value>
    </list>
  </property>
</bean>

次のように「呼び出し」を実装するインターセプタークラス MyInterceptor を使用します。

public Object invoke(MethodInvocation invocation) throws Throwable {
  Method method = invocation.getMethod();
  String interfaceName = method.getDeclaringClass().getName();
  System.out.println(interfaceName + ": " + method.getName());
}

サービスインターフェイスは次のように宣言されます。

public interface AService{
    public void delete();

    public void test();
}

public interface AnotherService{
    public void delete();
}

ここで、AService をクラスにオートワイヤーすると、AService の削除機能とテスト機能を使用できると思います。

public class Test{

  @Autowired
  private AService aService;

  public void testAservice(){
    aService.test();
    aService.delete();
  }

}

私のインターセプターでは、「aService.test()」呼び出しは問題なく到着します。ただし、'aService.delete()' 呼び出しは、どういうわけかインターフェイス AnotherService をトリガーします。インターセプターからのコンソール出力は次のとおりです。

com.test.AService: test
com.test.AnotherService: delete 

回避策: ProxyFactoryBeanを 2 つ に分割し、2 つの個別のインターセプター Bean を使用します (どちらも以前と同じクラスを参照しています)。

<bean name="MyInterceptor1" class="com.test.MyInterceptor"/>
<bean class="org.springframework.aop.framework.ProxyFactoryBean">
  <property name="interceptorNames">
    <list>  
      <value>MyInterceptor1</value>
    </list>
  </property>
  <property name="proxyInterfaces">
    <list>
     <value>com.test.AService</value>
    </list>
  </property>
</bean>

<bean name="MyInterceptor2" class="com.test.MyInterceptor"/>
<bean class="org.springframework.aop.framework.ProxyFactoryBean">
  <property name="interceptorNames">
    <list>  
      <value>MyInterceptor2</value>
    </list>
  </property>
  <property name="proxyInterfaces">
    <list>
     <value>com.test.AnotherService</value>
    </list>
  </property>
</bean>

さて、この構成は期待される出力を生成します:

com.test.AService: test
com.test.AService: delete
4

1 に答える 1

1

プロキシは、リストされたインターフェースの単なる実装ですが、Java では、衝突なしで複数のインターフェースから同じメソッドを実装することは不可能です。

たとえば、このスレッドを参照してください。

したがって、回避策をそのまま使用するか、削除メソッド名を別のものに変更してください(私見のほうが良いオプションです)。

于 2014-01-04T11:17:54.750 に答える