I am using this custom annotation for logging execution time, annotation could be present on method or class in which all public methods have it. Everything works fine, except in case of method level "LogExecutionTime logExecutionTime" comes null. This throws an NPE.
@Around("@annotation(logExecutionTime) || @within(logExecutionTime)")
public Object logExecutionTime(ProceedingJoinPoint joinPoint, LogExecutionTime logExecutionTime) throws Throwable {
final Logger logger = LoggerFactory.getLogger(joinPoint.getTarget().getClass());
final String name = joinPoint.toShortString();
final StopWatch stopWatch = new StopWatch(name);
stopWatch.start(name);
try {
return joinPoint.proceed();
} finally {
stopWatch.stop();
if (logExecutionTime.value()) {
logger.info(joinPoint.getSignature().getName() + ".time=", stopWatch.getTotalTimeSeconds());
}
}
}
if I reverse the order-
@Around("@within(logExecutionTime) || @annotation(logExecutionTime)")
the behavior reverses and I get a valid object at method level and null at class level annotated methods.
I have worked around this by having 2 explicit methods and separating the two-
@Around("@within(logExecutionTime)")
public Object logExecutionTimeClassLevel(ProceedingJoinPoint joinPoint, LogExecutionTime logExecutionTime) throws Throwable {
return logExecutionTimeMethodLevel(joinPoint, logExecutionTime);
}
@Around("@annotation(logExecutionTime)")
public Object logExecutionTimeMethodLevel(ProceedingJoinPoint joinPoint, LogExecutionTime logExecutionTime) throws Throwable {
final Logger logger = LoggerFactory.getLogger(joinPoint.getTarget().getClass());
final String name = joinPoint.toShortString();
final StopWatch stopWatch = new StopWatch(name);
stopWatch.start(name);
try {
return joinPoint.proceed();
} finally {
stopWatch.stop();
if (logExecutionTime.value()) {
logger.info(joinPoint.getSignature().getName() + ".time=", stopWatch.getTotalTimeMillis());
}
}
Was hoping to understand this behavior, when we use OR '||' with two pointcuts.
class level
@LogExecutionTime
@Component
public class CleanUpService implements ICleanUpService { ... }
method level
@Scheduled(fixedDelay = 100)
@LogExecutionTime(false)
public void processMessageQueue() { ... }