Search code examples
javaspringspring-aop

Is it possible to have multiple pointcuts with different arguments in Spring AOP?


I have single advice method with multiple pointcuts. Is it possible to have different arguments?

   @Around("execution(* com.admin.web.controller.*.*.*(javax.servlet.http.HttpServletRequest,com.admin.model.PortalRequestTransaction)) && args(request,portalRequestTransaction)"
        + " || execution(* com.admin.web.controller.BaselineImporterController.*(javax.servlet.http.HttpServletRequest,..)) && args(request)")
public Object auditAround(ProceedingJoinPoint joinPoint, HttpServletRequest request,
                          PortalRequestTransaction portalRequestTransaction) throws Throwable { // some code here }

For example, Is it possible to the first pointcut to have 2 arguments and for the second one to have only one argument and second one passed as null? If this is not possible, what is the best solution?


Solution

  • One way to achieve this is using JoinPoint.getArgs() to get the method arguments as an object array. This involves reflection.

    A sample code to achieve this would be as follows

    import org.aspectj.lang.ProceedingJoinPoint;
    import org.aspectj.lang.annotation.Around;
    import org.aspectj.lang.annotation.Aspect;
    import org.aspectj.lang.annotation.Pointcut;
    import org.springframework.stereotype.Component;
    
    @Component
    @Aspect
    public class TestAspect {
        
        @Pointcut("execution(* com.admin.web.controller.*.*.*(javax.servlet.http.HttpServletRequest,com.admin.model.PortalRequestTransaction))")
        public void requestNTransaction() {}
        
        @Pointcut("execution(* com.admin.web.controller.BaselineImporterController.*(javax.servlet.http.HttpServletRequest,..))")
        public void requestAsFirstArg() {}
    
        @Around("requestNTransaction() || requestAsFirstArg()")
        public Object auditAround(ProceedingJoinPoint pjp) throws Throwable {
            // get the signature of the method to be adviced
            System.out.println(pjp.getSignature());
            Object[] args = pjp.getArgs();
            for(Object arg:args) {
                // use reflection to identify and process the arguments
                System.out.println(arg.getClass());
            }
            return pjp.proceed();
        }
    
    }
    

    Note:

    1. Individual methods serving as Pointcut signature . Spring documentation
    2. ProceedingJoinPoint for @Around advice type