Skip to content
Advertisement

Spring AOP and AspectJ on same method

I have a question about using aspectJ and spring aop method intercepting. I created 2 annotations: @AJTest and @SAOPTest.

package com.test.company;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;

@Aspect
public class AJTestAspect {

    @Pointcut("@annotation(AJTest)")
    public void aJTest() {
    }

    @Around("aJTest()")
    public Object profile(ProceedingJoinPoint joinPoint) throws Throwable {
        final long start = System.currentTimeMillis();
        try {
            return joinPoint.proceed();
        } finally {
            long finish = System.currentTimeMillis() - start;
            System.out.println("Method execution time: " + (start - finish));
        }
    }
}

registered it

package com.test.company;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class AJConfiguration {

    @Bean
    public AJTestAspect ajTestAspect() {
        return new AJTestAspect();
    }
}

and other

package com.test.company;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;

public class SAOPInterceptor implements MethodInterceptor {

    @Override
    public Object invoke(MethodInvocation methodInvocation) throws Throwable {
        System.out.println("Number of parameters " + methodInvocation.getArguments().length);
        return methodInvocation.getMethod().invoke(methodInvocation.getThis(), methodInvocation.getArguments());
    }
}

and register it

package com.test.company;

import org.springframework.aop.Advisor;
import org.springframework.aop.aspectj.AspectJExpressionPointcut;
import org.springframework.aop.support.DefaultPointcutAdvisor;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
@EnableConfigurationProperties
public class SpringSAOPTestConfiguration {

    @Bean
    public Advisor springAopTestAdvisor() {
        AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
        pointcut.setExpression("@annotation(com.test.company.SAOPTest)");
        return new DefaultPointcutAdvisor(pointcut, new SAOPInterceptor());
    }
}

and added it to my method in controller

package com.test.company;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

    @RestController
    public class TestController {
    
        @SAOPTest
        @AJTest
        @GetMapping("/test")
        public String doSomething(@RequestParam("firstParam") String firstParam, @RequestParam("secondParam") Integer secondParam) throws InterruptedException {
            Thread.sleep(2_500);
            return firstParam + " " + secondParam;
        }
    }

Application class

package com.test.company;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.EnableAspectJAutoProxy;

@EnableAspectJAutoProxy
@SpringBootApplication
public class AopTestApplication {
    public static void main(String[] args) {
        SpringApplication.run(AopTestApplication.class, args);
    }
}

but when i call it by http://localhost:8080/test?firstParam=test&secondParam=2 i can’t see message with time of execution of the method, but can see how many parameters were passed to the method. If I’ll remove @SAOPTest – method time of execution is worked as expected, but it is not working with both annotations. Is it the problem with proxy object created by spring, or I missed something?

Advertisement

Answer

Your interceptor does not proceed correctly. Please read the MethodInterceptor javadoc. The interceptor should look like this:

public class SAOPInterceptor implements MethodInterceptor {
  @Override
  public Object invoke(MethodInvocation methodInvocation) throws Throwable {
    System.out.println("Number of parameters " + methodInvocation.getArguments().length);
    return methodInvocation.proceed();
  }
}

Besides, your aspect calculates time wrong, too. First, you say finish = System.currentTimeMillis() - start and later you print start - finish. Either you should subtract finish - start or calculate the time spent in the variable, but not both and not start - finish. Why not simply System.out.println("Method execution time: " + (System.currentTimeMillis() - start));?

User contributions licensed under: CC BY-SA
8 People found this is helpful
Advertisement