Search code examples
javaaopaspectjspring-aopinterceptor

AspectJ Interceptor not working


I have created an AspectJ interceptor like

@Aspect
public class RequestSpecificServiceAspect {
    @Pointcut("execution( * com.mycompany.c.d.doesTreatmentEqualsAndTrigger(..))")
    private void callInterceptor(){}

    @Before("callInterceptor()")
    public void getCallStack(){
    StackTraceElement[] callingStack = Thread.currentThread().getStackTrace();
    PopulateServiceDependentMap populateServiceDependentMap = new PopulateServiceDependentMap();
    populateServiceDependentMap.populateMap(callingStack, "ServiceName");
    }
}

This works just fine and since this was a trial code i now replaced it with the actual interceptor i wanted which is like this

@Pointcut("execution( * mycompany.f.g.findPluginForRequest(..)) && args(request)")
private void actualInterceptor(BSFBatchRequest request){}

@Before("actualInterceptor(request)")
public void getBSFCall(BSFBatchRequest request){ 
    StackTraceElement[] callingStack = Thread.currentThread().getStackTrace();
    PopulateServiceDependentMap populateServiceDependentMap = new PopulateServiceDependentMap();
    populateServiceDependentMap.populateMap(callingStack, request);
}

But now my interceptor is not intercepting the call to findPluginForRequest() function. Why is this happening and how can I fix it?

This is my spring config file(.xml) :

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd"
default-autowire="no">
<context:annotation-config/>

<aop:aspectj-autoproxy/>

<bean name="com.dpx.dependencyGraphFactory" class="com.mycompany.dpx.dependencytree.ModuleToModuleDependencyGraphFactory"></bean>
<bean name="com.dpx.serviceInterceptor" class="com.mycompany.dpx.dependencytree.RequestSpecificServiceAspect"/>

</beans>

The signature for findPluginForRequest() is private AllPurposeCache<BSFBatchRequest, BSFReply> findPluginForRequest(final BSFBatchRequest request). I have tried changing the pointcut to

@Pointcut("execution(private * mycompany.f.g.findPluginForRequest(..)) && args(request)")
private void actualInterceptor(BSFBatchRequest request){}

But it still doesn't work.


Solution

  • I can answer your question:

    private AllPurposeCache<BSFBatchRequest, BSFReply> findPluginForRequest(
      final BSFBatchRequest request
    )
    

    Spring AOP is not as powerful as AspectJ because it does not weave bytecode directly but is based on creating/using dynamic proxies via JDK or CGLIB. Dynamic proxies are just subclasses or classes implementing interfaces. As such they only override public methods. Your method is private, thus Spring AOP cannot intercept it. This is documented in the Spring AOP manual:

    Due to the proxy-based nature of Spring’s AOP framework, protected methods are by definition not intercepted, neither for JDK proxies (where this isn’t applicable) nor for CGLIB proxies (where this is technically possible but not recommendable for AOP purposes). As a consequence, any given pointcut will be matched against public methods only! If your interception needs include protected/private methods or even constructors, consider the use of Spring-driven native AspectJ weaving instead of Spring’s proxy-based AOP framework. This constitutes a different mode of AOP usage with different characteristics, so be sure to make yourself familiar with weaving first before making a decision.

    In order to get it working, either make the method public or switch to AspectJ.