Spring AOP AspectJ试图建议不匹配切入点的课程

时间:2017-08-24 00:06:03

标签: java spring spring-boot aop aspectj

我在一个项目中设置了AOP日志,但在另一个项目中没有。

来自build.gradle:

compile "org.springframework.boot:spring-boot-starter-web:1.4.2.RELEASE" 
[...]
compile "org.aspectj:aspectjrt:1.8.10"
compile "org.aspectj:aspectjweaver:1.8.10"

我有一个基本方面来登录一些API:

@Aspect
public abstract class Profiler {
    private static final Logger logger = LoggerFactory.getLogger(getClass());

    protected abstract void toLog();   

    @Around("toLog()")
    public Object logAround(ProceedingJoinPoint joinPoint) {

[...]

我有派生类来定义切入点:

@Aspect
public class SDKProfiler extends Profiler {
    @Override
    @Pointcut("execution(public * com.company.app.stuff.*.*(..))")
    protected void toLog() {}
}

我在配置上使用@EnableAspectJAutoProxy启用了aspecjtJ。 当我尝试在main中加载ConfigurableApplicationContext时,我最终得到了这个异常:

[...]  
Caused by: java.lang.IllegalArgumentException: error at ::0 can't find referenced pointcut toLog
    at org.aspectj.weaver.tools.PointcutParser.parsePointcutExpression(PointcutParser.java:301)
    at org.springframework.aop.aspectj.AspectJExpressionPointcut.buildPointcutExpression(AspectJExpressionPointcut.java:207)
    at org.springframework.aop.aspectj.AspectJExpressionPointcut.checkReadyToMatch(AspectJExpressionPointcut.java:193)
    at org.springframework.aop.aspectj.AspectJExpressionPointcut.getClassFilter(AspectJExpressionPointcut.java:170)
    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)
    [...]

当Spring尝试自动装配一个与切入点表达式无关的类时,会发生这种情况。如果我删除那个bean,它将以相同的方式对另一个与切入点表达式不匹配的bean失败。看看以前的问题,我看到人们通过升级他们的AspectJ版本取得了成功。在撰写本文时,由于1.8.10是当前最新版本,因此不适用。

此代码在类似的应用程序中正常工作,其中唯一明显的区别是构建工具maven。但是,没有编译时编织,所以不应该成为一个因素。

任何想法为什么春天试图找到一个' toLog'第三方课程中的切入点与表达式不匹配?

1 个答案:

答案 0 :(得分:1)

原始项目和新项目之间的显着不同。新项目通过配置类将方面添加到上下文中,而旧(工作)项目通过组件扫描添加方面。切换到方面的组件扫描修复了问题。 坏:

@Configuration
public class LoggerConfig {

    @Bean
    public SDKProfiler sdkProfiler() { return new SDKProfiler(); }
}

好:

@Configuration
@ComponentScan("com.company.app.logging")
public class LoggerConfig {
} 

这些方面位于com.company.app.logging包中。

感谢Abhijit花时间回复。我真的以为在发布之前我已经考虑了项目之间的所有不同。