Question

When intercepting several service interfaces with the help of ProxyFactoryBean and MethodInterceptor, the interceptor mixes up the service interfaces for some reason when the service interface method names are the same. My questions are:

1.) Are there rules to observe when intercepting multiple interfaces with a single ProxyFactoryBean?

2.) Where does the code go wrong? I tried switching the order of AnotherService and AService in the 'proxyInterfaces' list, but that doesn't work, either.

3.) I solved the problem by splitting the ProxyFactoryBean in two (see 'Workaround' at the bottom). Is that the only solution, or is there a way I can keep the ProxyFactoryBean as described in the 'Code' section?

Code:

I've got several services that I'm intercepting with a 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>

with the interceptor class MyInterceptor implementing the 'invoke' like this:

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

The Service interfaces are declared as follows:

public interface AService{
    public void delete();

    public void test();
}

public interface AnotherService{
    public void delete();
}

Now, when I autowire the AService into a class, I expect that I can use the delete- and test-function of AService:

public class Test{

  @Autowired
  private AService aService;

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

}

In my interceptor, the 'aService.test()' call arrives without a problem. However, the 'aService.delete()' call somehow triggers the interface AnotherService. The console output from the interceptor is as follows:

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

Workaround: I split the ProxyFactoryBean in two, with two separate interceptor beans (both referring to the same class as before though):

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

Now, this configuration produces the expected output:

com.test.AService: test
com.test.AService: delete
Was it helpful?

Solution

Proxy is just an implementation of your listed interfaces but in Java it's just not possible to implement same method from multiple interfaces without collisions.

Please see this thread for example.

So just stay with your workaround or change delete method names to be different (imho better option).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top