javaspringspring-aopspring-aspects

Spring AOP. How to make pointcut for all public methods in annotated class


I need to handle all the exceptions that are thrown from public methods of class annotated with some annotation. I trying to use Spring AOP. This is my logger:

@Aspect
public class Logger {
    private final Logger log = LoggerFactory.getLogger(this.getClass());

    @Pointcut("@annotation(loggable)")
    public void isLoggable(Loggable loggable) {
    }

    @AfterThrowing(pointcut = "isLoggable(loggable)", throwing = "e")
    public void afterThrowing(Loggable loggable, Exception e) throws Throwable {
        log.error("AFTER", e);
    }

@Loggable is my annotation.

Then I've added @EnableAspectJAutoProxy annotation to my configuration class.

First I've tried to annotate some method that throws an exception. It works fine but how can I make this work for all public methods in class annotated with @Loggable annotation?


Solution

  • You can create the aspect like this, where @LogMe is the annotation: @Pointcut("execution(@LogMe * *(..))") to match all the public methods.

    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.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.stereotype.Component;
    import org.springframework.util.StopWatch;
    
    
    @Aspect
    @Component
    public class LogExecutionTime {
    
        private static final String LOG_MESSAGE_FORMAT = "%s.%s execution time: %dms";
        private static final Logger logger = LoggerFactory.getLogger(LogExecutionTime.class);
    
        @Pointcut("execution(@LogMe * *(..))")
        public void isAnnotated() {}
    
        /**
         * Method will add log statement of running time of the methods which are annotated with @LogMe
         * @param joinPoint
         * @return
         * @throws Throwable
         */
        @Around("isAnnotated()")
        public Object logTimeMethod(ProceedingJoinPoint joinPoint) throws Throwable {
          StopWatch stopWatch = new StopWatch();
          stopWatch.start();
    
          Object retVal = joinPoint.proceed();
    
          stopWatch.stop();
    
          logExecutionTime(joinPoint, stopWatch);
    
          return retVal;
        }
    
        private void logExecutionTime(ProceedingJoinPoint joinPoint, StopWatch stopWatch) {
          String logMessage = String.format(LOG_MESSAGE_FORMAT, joinPoint.getTarget().getClass().getName(), joinPoint.getSignature().getName(), stopWatch.getTotalTimeMillis());
          logger.info(logMessage.toString());
        }
    }