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));
?