1

借助ProxyFactoryBean和MethodInterceptor拦截多个服务接口时,当服务接口方法名相同时,拦截器由于某种原因混淆了服务接口。我的问题是:

1.)使用单个 ProxyFactoryBean 拦截多个接口时是否需要遵守规则?

2.)代码哪里出错了?我尝试在“proxyInterfaces”列表中切换 AnotherService 和 AService 的顺序,但这也不起作用。

3.)我通过将 ProxyFactoryBean 一分为二解决了这个问题(参见底部的“解决方法”)。这是唯一的解决方案,还是有一种方法可以按照“代码”部分中的说明保留 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一分为二,使用两个单独的拦截器 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 回答