Issue
I tried making a custom annotation for logging method execution time and it is working fine untill I am using the annotation on method which are not in the controller class. When used in the controller class, autowiring of other class (service class) fails and gives a Null Pointer exception.
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface LogExecutionTime {
}
--
@Aspect
@Component
public class ExampleAspect {
@Around("@annotation(LogExecutionTime)")
public Object logExecutionTime(ProceedingJoinPoint joinPoint) throws Throwable {
long start = System.currentTimeMillis();
Object proceed = joinPoint.proceed();
long executionTime = System.currentTimeMillis() - start;
System.out.println(joinPoint.getSignature() + " executed in " + executionTime + "ms");
return proceed;
}
}
When I am using this Annotation on any class other than my Controller, it is working fine.
@RestController
public class ProjectController {
@Autowired
ProjectService projectService;
@GetMapping("/testTimeTaken")
@LogExecutionTime
private String testTimeTaken() {
return projectService.dummyMethod();
}
}
Solution
You cannot use aspects to "catch" private method.
From Spring reference:
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.
So the best thing you can do is to change your method public--> public String testTimeTaken()
Answered By - Jose Luis