You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring AOP切面未触发问题排查与解决

解决Spring AOP切面未触发问题

问题现象

预期切面生效时,日志应包含切面输出:

Sep 27, 2020 1:11:11 PM aspects.LoggingAspect log
INFO: Method will execute
Sep 27, 2020 1:11:11 PM com.cms.services.CommentService publishComment
INFO: Publishing comment:Demo comment
Sep 27, 2020 1:11:11 PM aspects.LoggingAspect log
INFO: Method executed

但实际仅输出业务日志,切面完全未触发:

com.cms.services.CommentService publishComment
INFO: Publishing Comment: Demo Comment

代码与环境

项目通过Main.java加载Spring上下文调用CommentService.java,CommentService位于services包下;LoggingAspect.java实现切面逻辑;CommentConfig.java配置@EnableAspectJAutoProxy并注册切面Bean。

Main.java

public class Main {
    public static void main(String[] args) {
        var c = new AnnotationConfigApplicationContext(CommentConfig.class);
        var service = c.getBean(CommentService.class);

        Comment comment = new Comment();
        comment.setText("Demo Comment");
        comment.setAuthor("Natasha");

        service.publishComment(comment);
    }
}

CommentService.java

@Service
public class CommentService {

    private Logger logger = Logger.getLogger(CommentService.class.getName());
    public void publishComment(Comment comment) {
        logger.info("Publishing Comment: " + comment.getText());
    }
}

原LoggingAspect.java

@Aspect
@Component
public class LoggingAspect {

    private Logger logger = Logger.getLogger(LoggingAspect.class.getName());

    @Around("execution(* services.*.*(..))")
    public void log(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("method will execute");
            logger.info("Method will execute");
            joinPoint.proceed();
            logger.info("Method has executed");
        System.out.println("method has executed");
    }
}

CommentConfig.java

@Configuration
@ComponentScan(basePackages = {"com.cms"})
@EnableAspectJAutoProxy
public class CommentConfig {
    @Bean
    public LoggingAspect aspect() {
        return new LoggingAspect();
    }
}

依赖配置

<properties>
    <maven.compiler.source>17</maven.compiler.source>
    <maven.compiler.target>17</maven.compiler.target>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

<dependencies>
    <!-- Spring Context -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>5.3.23</version>
    </dependency>

    <!-- Spring Aspects -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-aspects</artifactId>
        <version>5.3.23</version>
    </dependency>

    <!-- Spring AOP -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-aop</artifactId>
        <version>5.3.24</version>
    </dependency>
</dependencies>

包结构

├─src
│  ├─main
│  │  ├─java
│  │  │  └─com
│  │  │      └─cms
│  │  │          │  Main.java
│  │  │          │
│  │  │          ├─aspect
│  │  │          │      LoggingAspect.java
│  │  │          │
│  │  │          ├─config
│  │  │          │      CommentConfig.java
│  │  │          │
│  │  │          ├─model
│  │  │          │      Comment.java
│  │  │          │
│  │  │          ├─proxies
│  │  │          │      CommentNotificationProxy.java
│  │  │          │      CommentPushNotificationProxyImpl.java
│  │  │          │      EmailCommentNotificationProxyImpl.java
│  │  │          │
│  │  │          ├─repositories
│  │  │          │      CommentRepository.java
│  │  │          │      DBCommentRepositoryImpl.java
│  │  │          │
│  │  │          └─services
│  │  │                  CommentService.java
│  │  │
│  │  └─resources

问题原因

切面未触发的核心原因是@Around注解的execution切点表达式遗漏了完整包名。原表达式execution(* services.*.*(..))仅匹配根路径下的services包,而实际CommentService位于com.cms.services包下,导致切点无法匹配目标方法。

修复方案

修改LoggingAspect.java中的切点表达式,补充完整包路径com.cms.services,同时修正@Around方法的返回值类型(需返回Object并返回joinPoint.proceed()的结果,确保方法正常执行):

@Aspect
@Component
public class LoggingAspect {
    private Logger logger = Logger.getLogger(LoggingAspect.class.getName());

    @Around("execution(* com.cms.services.*.*(..))")    // 修正点:补充完整包名
    public Object log(ProceedingJoinPoint joinPoint) throws Throwable {
        String methodName = joinPoint.getSignature().getName();
        Object arguments[] = joinPoint.getArgs();

        logger.info("Method " + methodName + " with Parameters " +
                Arrays.asList(arguments) + " will execute");
        Object returnedByMethod = joinPoint.proceed();
        logger.info("Method executed and returned " + returnedByMethod);
        return returnedByMethod;
    }
}

参考建议

建议学习Spring官方文档中关于AspectJ切点表达式的语法规则,确保切点路径匹配准确。


内容的提问来源于stack exchange,提问作者mchun

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 13:30:04