春天AOP。如何在带注释的类中为所有公共方法制作切入点

时间:2017-03-24 07:36:04

标签: java spring spring-aop spring-aspects

我需要处理从带有一些注释的类的公共方法抛出的所有异常。 我试图使用Spring AOP。这是我的记录器:

@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是我的注释。

我已将@EnableAspectJAutoProxy注释添加到配置类中。

首先,我试图注释一些抛出异常的方法方法。它运行正常,但是如何使用@Loggable注释注释的类中的所有公共方法都可以使用它?

2 个答案:

答案 0 :(得分:3)

您可以像这样创建方面,其中logMe是注释。  @Pointcut(“execution(@LogMe * *(..))”)匹配所有公共方法

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() {}

 @Around("isAnnotated()")
/**
 * method will add log statement of running time of the methods which are annotated with @LogMe
 * @param joinPoint
 * @return
 * @throws Throwable
 */
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());
 }
}

答案 1 :(得分:1)

使用@Aspect注释的类不是@Component,因此如果您启用了组件扫描,则不会选中它。如果您的上下文中没有Aspect,则AOP没有任何用处。

要解决此问题,您可以执行以下三项操作之一:

  1. @Component放在@Aspect
  2. 旁边
  3. @Aspect定义为@Bean
  4. 添加额外的`@ComponentScan(includeFilter = {@ Filter(org.aspectj.lang.annotation.Aspect)}
  5. 显然,选项#1是最容易做到的。

      

    首先,我试图注释一些抛出异常的方法方法。它运行正常,但是如何使用@Loggable注释注释的类中的所有公共方法都可以使用它?

    你需要写一个与之匹配的切点。像下面这样的东西可以解决问题。

    @Pointcut("public * ((@Loggable *)+).*(..)) && within(@Loggable *)")
    

    一起
    @Pointcut("@Loggable * *(..)")
    

    对于带注释的类中的带注释的方法或公共方法,将会遇到这种情况。这是受到Spring Framework AnnotationTransactionAspect中代码的启发。