Spring ProxyFactoryBean服务拦截不是唯一的

时间:2014-01-03 17:03:11

标签: java spring spring-aop autowired method-interception

当在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

1 个答案:

答案 0 :(得分:1)

代理只是列出的接口的一个实现,但在Java中,根本不可能从多个接口实现相同的方法而不会发生冲突。

请参阅this帖子,例如。

因此,请继续使用您的解决方法或将删除方法名称更改为不同(imho更好的选项)。