java - Spring AOP AspectJ 尝试建议与切入点不匹配的类

标签 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 尝试 Autowiring 一个与切入点表达式不匹配的类时,就会发生这种情况。如果我删除该 bean,它将以同样的方式针对与切入点表达式不匹配的另一个 bean 失败。查看之前的问题,我看到人们通过升级 AspectJ 版本取得了成功。截至撰写本文时,这不是一个选项,因为 1.8.10 是当前最新版本。

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

知道为什么 spring 试图在与表达式不匹配的第 3 方类中找到“toLog”切入点吗?

最佳答案

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

@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 抽出时间回复。我真的认为在发布之前我已经考虑了项目之间的所有不同之处。

关于java - Spring AOP AspectJ 尝试建议与切入点不匹配的类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45850985/

相关文章:

java - Spring 安全 : Cannot determine value type from string 'admin'

spring - 通过curl路由上传到Amazon S3

java - org.thymeleaf.exceptions.TemplateInputException : Error resolving fragment: template or fragment could not be resolved

java - Hystrix 回退方法最佳实践

java - 在 Spring Data JPA 中,派生的 find 方法在一个事务中多次调用时不使用一级缓存,但默认的 findById 会

java - 带有 lambda 表达式的 invokeAndWait 在静态初始值设定项中永远挂起

java - 为什么这个法术能给施法者带来满血?

java - 将 JobLaunchingGateway 与 spring-batch 和 spring-integration 一起使用抛出 DestinationResolutionException

java - 运行 JUnit 测试时找不到资源文件

java - 为什么 Java TreeMap 不打印所有插入的条目