@Pointcut和@Around可以在不同的类中吗?

时间:2019-02-15 08:38:21

标签: spring spring-boot spring-aop

我是AOP的新手。我在AOP的帮助下制作了一个通用的日志记录API,其中定义了建议。

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
import org.springframework.util.StopWatch;


@Component
@Aspect
public class LogExecutionTime {
  private static final String LOG_MESSAGE_FORMAT = "%s.%s execution time: %dms";
  private static final Log LOG =   LogFactory.getLog(LogExecutionTime.class);

  @Around("myPointCut()")
  public Object logTimeMethod(ProceedingJoinPoint joinPoint) throws Throwable {
    System.out.println("Inside aAdvice LogExecutionTime");
    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());
    LOG.info(logMessage.toString());
  }
}

现在,我已将此罐子包含在我的应用程序代码中并编写了切入点。

import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

@Component
@Aspect
public class ButterflyPointCut {

    @Pointcut("execution(* com.*.Abc.methodName(..))")
    public void myPointCut(){ 
        System.out.println("Executed");
    }

}

出现以下错误。我想知道是否是由于不同的类。我将jar包放入了组件扫描。

 Caused by: java.lang.IllegalArgumentException: error at ::0 can't find referenced pointcut myPointCut
        at org.aspectj.weaver.tools.PointcutParser.parsePointcutExpression(PointcutParser.java:317)
        at org.springframework.aop.aspectj.AspectJExpressionPointcut.buildPointcutExpression(AspectJExpressionPointcut.java:217)
        at org.springframework.aop.aspectj.AspectJExpressionPointcut.checkReadyToMatch(AspectJExpressionPointcut.java:190)
        at org.springframework.aop.aspectj.AspectJExpressionPointcut.getClassFilter(AspectJExpressionPointcut.java:169)
        at org.springframework.aop.support.AopUtils.canApply(AopUtils.java:220)
        at org.springframework.aop.support.AopUtils.canApply(AopUtils.java:279)
        at org.springframework.aop.support.AopUtils.findAdvisorsThatCanApply(AopUtils.java:311)
        at org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator.findAdvisorsThatCanApply(AbstractAdvisorAutoProxyCreator.java:119)
        at org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator.findEligibleAdvisors(AbstractAdvisorAutoProxyCreator.java:89)
        at org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator.getAdvicesAndAdvisorsForBean(AbstractAdvisorAutoProxyCreator.java:70)
        at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.wrapIfNecessary(AbstractAutoProxyCreator.java:346)
        at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.postProcessAfterInitialization(AbstractAutoProxyCreator.java:298)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization(AbstractAutowireCapableBeanFactory.java:422)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1588)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:553)
        ... 57 common frames omitted

2 个答案:

答案 0 :(得分:0)

  

是的,这是由于注释方法不同   类。

@Pointcut注释方法和@Around注释方法保留在同一类中,其他明智的用法是在@Around注释本身之内使用切点表达式。

@Around("execution(* com.*.Abc.methodName(..))")

答案 1 :(得分:0)

您还可以使用带有大约注释的切入点方法的完全限定名称(已在单独的类中定义)。 例如:

在这里,您需要使用圆点注释提及切入点方法的完整限定名称 例如@Around(“ domain.package.class.myPointCutMethodName()”)

@Around("domain.package.className.myPointCut()")
  public Object logTimeMethod(ProceedingJoinPoint joinPoint) throws Throwable {
    System.out.println("Inside aAdvice LogExecutionTime");
    StopWatch stopWatch = new StopWatch();
    stopWatch.start();
    Object retVal = joinPoint.proceed();
    stopWatch.stop();
    logExecutionTime(joinPoint, stopWatch);
    return retVal;
  }