Spring AOP:找不到引用的切入点注释

时间:2019-08-30 05:02:47

标签: java spring spring-aop

我正在尝试监视某些方法的运行。运行程序时出现此错误。

Glide.with(this)
        .load(imageUri)
        .listener(object : RequestListener<Drawable> {
          override fun onLoadFailed(e: GlideException?, model: Any?, target: com.bumptech.glide.request.target.Target<Drawable>?, isFirstResource: Boolean): Boolean {

            return false
          }

          override fun onResourceReady(resource: Drawable?, model: Any?, target: com.bumptech.glide.request.target.Target<Drawable>?, dataSource: DataSource?, isFirstResource: Boolean): Boolean {

            return false
          }
        })
        .apply(RequestOptions()
                .dontTransform()
                .centerCrop()
        .into(adImage)

我定义了一个注释来标记要记录的方法。注释是

Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'arithmeticCalculator' defined in URL [jar:file:/home/android/java/spring-5-recipes-master/spring-recipes-UPDATED-master/ch02/recipe_2_17_i/build/libs/recipe_2_17_i-4.0.0-SNAPSHOT.jar!/com/apress/springrecipes/calculator/ArithmeticCalculatorImpl.class]: Initialization of bean failed; nested exception is java.lang.IllegalArgumentException: error at ::0 can't find referenced pointcut annotation
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:591)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:502)
        at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:312)
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:310)
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:760)
        at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:868)
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:549)
        at org.springframework.context.support.GenericXmlApplicationContext.<init>(GenericXmlApplicationContext.java:71)
        at com.apress.springrecipes.calculator.Main.main(Main.java:11)
Caused by: java.lang.IllegalArgumentException: error at ::0 can't find referenced pointcut annotation
        at org.aspectj.weaver.tools.PointcutParser.parsePointcutExpression(PointcutParser.java:319)
        at org.springframework.aop.aspectj.AspectJExpressionPointcut.buildPointcutExpression(AspectJExpressionPointcut.java:226)
        at org.springframework.aop.aspectj.AspectJExpressionPointcut.obtainPointcutExpression(AspectJExpressionPointcut.java:197)
        at org.springframework.aop.aspectj.AspectJExpressionPointcut.getClassFilter(AspectJExpressionPointcut.java:176)
        at org.springframework.aop.support.AopUtils.canApply(AopUtils.java:224)
        at org.springframework.aop.support.AopUtils.canApply(AopUtils.java:283)
        at org.springframework.aop.support.AopUtils.findAdvisorsThatCanApply(AopUtils.java:315)
        at org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator.findAdvisorsThatCanApply(AbstractAdvisorAutoProxyCreator.java:124)
        at org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator.findEligibleAdvisors(AbstractAdvisorAutoProxyCreator.java:93)
        at org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator.getAdvicesAndAdvisorsForBean(AbstractAdvisorAutoProxyCreator.java:74)
        at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.wrapIfNecessary(AbstractAutoProxyCreator.java:352)
        at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.postProcessAfterInitialization(AbstractAutoProxyCreator.java:304)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization(AbstractAutowireCapableBeanFactory.java:438)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1714)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:583)
        ... 10 more

然后我将切入点定义为

@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface LoggingRequired {
}

然后将切入点应用于一个方面。方面是记录方法的运行状态。

@Aspect
public class CalculatorPointcuts {

    @Pointcut("annotation(com.apress.springrecipes.calculator.LoggingRequired)")
    public void loggingOperation() {}

}

AritheticCalculator接口及其实现是

@Aspect
@Component
public class CalculatorLoggingAspect {

    private Log log = LogFactory.getLog(this.getClass());

    @Before("CalculatorPointcuts.loggingOperation()")
    public void logBefore(JoinPoint joinPoint) {
        log.info("The method " + joinPoint.getSignature().getName()
              + "() begins with " + Arrays.toString(joinPoint.getArgs()));
    }

    @After("CalculatorPointcuts.loggingOperation()")
    public void logAfter(JoinPoint joinPoint) {
        log.info("The method " + joinPoint.getSignature().getName()
                + "() ends");
    }

}

有人知道哪里出问题了吗?

谢谢

1 个答案:

答案 0 :(得分:1)

我注意到两件事

1)@annotation在方法级别而非类级别工作。将其更改为@within

@Pointcut("@within(com.apress.springrecipes.calculator.LoggingRequired)")
public void loggingOperation() {}

2)在另一个类引用中定义切入点将是另一个问题。而是在同一个类中定义它


@Aspect
@Component
public class CalculatorLoggingAspect {

    private Log log = LogFactory.getLog(this.getClass());

    @Pointcut("@within(com.apress.springrecipes.calculator.LoggingRequired)")
public void loggingOperation() {}  

    @Before("loggingOperation()")
    public void logBefore(JoinPoint joinPoint) {
        log.info("The method " + joinPoint.getSignature().getName()
              + "() begins with " + Arrays.toString(joinPoint.getArgs()));
    }

    @After("loggingOperation()")
    public void logAfter(JoinPoint joinPoint) {
        log.info("The method " + joinPoint.getSignature().getName()
                + "() ends");
    }

}

GitHub reference issue-57720747-aspect-logging-annotation