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

使用aspectj-maven-plugin与AspectJ实现日志拦截遇问题求助

问题分析与解决方案

1. 思路是否有误?

是的,你的核心思路存在两个关键偏差:

  • ProjectA定位错误:你将ProjectA做成了提前完成织入的Jar,但实际上你需要的是纯切面类Jar(仅包含AspectJ切面代码,不提前织入第三方依赖),因为你的目标是在ProjectB编译阶段动态织入,以此规避版本冲突。
  • weaveDependencies使用场景错误:在ProjectA中配置weaveDependencies为logback-classic,会导致ProjectA打包时就将织入切面后的logback-classic类打进Jar,这不仅引入冗余代码,还会和ProjectB自身的logback版本冲突,完全违背了「在ProjectB端织入」的初衷。

2. 失败原因及正确实现方式

失败原因

  • ProjectA打包时已将织入后的logback-classic类封装进Jar,而ProjectB配置aspectLibrary引用ProjectA时,AspectJ只会用ProjectA的切面去织入ProjectB自身的类,不会覆盖ProjectB独立引入的logback-classic依赖,导致织入效果不可见。
  • ProjectA中提前织入的logback类会与ProjectB的logback依赖产生版本冲突,进一步导致织入逻辑失效。

正确实现方式

步骤1:重构ProjectA模块设计

每个功能模块(如logback-module、mysql-module)仅保留纯AspectJ切面代码,不提前织入任何第三方依赖:

  • 移除模块中aspectj-maven-plugin的weaveDependencies配置,仅保留编译切面类的基础配置:
<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>aspectj-maven-plugin</artifactId>
    <version>1.14.0</version>
    <executions>
        <execution>
            <goals>
                <goal>compile</goal> <!-- 仅编译切面类,不织入第三方依赖 -->
            </goals>
        </execution>
    </executions>
    <dependencies>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjrt</artifactId>
            <version>1.9.9.1</version>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjtools</artifactId>
            <version>1.9.9.1</version>
        </dependency>
    </dependencies>
    <configuration>
        <source>1.8</source> <!-- 匹配你的JDK版本 -->
        <target>1.8</target>
        <complianceLevel>1.8</complianceLevel>
    </configuration>
</plugin>
  • 模块依赖仅保留API级别依赖,例如logback-module引入logback-classic时使用provided scope(避免打包时引入):
<dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-classic</artifactId>
    <version>1.2.11</version>
    <scope>provided</scope>
</dependency>

步骤2:ProjectB端配置AspectJ织入逻辑

在ProjectB的pom.xml中,配置aspectj-maven-plugin,将ProjectA的对应模块(如logback-module)设为aspectLibraries,并指定需要织入的目标依赖:

<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>aspectj-maven-plugin</artifactId>
    <version>1.14.0</version>
    <executions>
        <execution>
            <id>compile-with-aspectj</id>
            <goals>
                <goal>compile</goal>
                <goal>test-compile</goal>
            </goals>
            <configuration>
                <aspectLibraries>
                    <aspectLibrary>
                        <groupId>your.group.id</groupId>
                        <artifactId>projectA-logback-module</artifactId>
                    </aspectLibrary>
                </aspectLibraries>
                <!-- 指定需要织入的第三方依赖 -->
                <weaveDependencies>
                    <weaveDependency>
                        <groupId>ch.qos.logback</groupId>
                        <artifactId>logback-classic</artifactId>
                    </weaveDependency>
                </weaveDependencies>
            </configuration>
        </execution>
    </executions>
    <dependencies>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjrt</artifactId>
            <version>1.9.9.1</version>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjtools</artifactId>
            <version>1.9.9.1</version>
        </dependency>
    </dependencies>
</plugin>
  • 引入ProjectA模块时使用compile scope,确保切面类能被AspectJ工具识别:
<dependency>
    <groupId>your.group.id</groupId>
    <artifactId>projectA-logback-module</artifactId>
    <version>your-version</version>
</dependency>

步骤3:解决开发环境运行问题

SpringBoot开发环境直接运行主类时,默认不会触发AspectJ的编译时织入(CTW),需添加以下配置:

  • 在src/main/resources/META-INF/aop.xml中声明切面类:
<!DOCTYPE aspectj PUBLIC "-//AspectJ//DTD//EN" "https://www.eclipse.org/aspectj/dtd/aspectj.dtd">
<aspectj>
    <weaver>
        <!-- 织入logback的类 -->
        <include within="ch.qos.logback.classic..*"/>
        <!-- 织入业务类(按需配置) -->
        <include within="your.projectB.package..*"/>
    </weaver>
    <aspects>
        <!-- 声明ProjectA中的切面类 -->
        <aspect name="your.projectA.logback.aspect.LogbackInterceptorAspect"/>
    </aspects>
</aspectj>
  • 添加AspectJ代理依赖:
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
</dependency>

此时开发环境运行时,Spring AOP会结合AspectJ的加载时织入(LTW)完成切面织入,避免版本冲突。

关键注意事项

  • 版本隔离:ProjectA的多版本模块(如mysql-module-8.0/5.7)仅保留对应版本的API依赖(provided scope),ProjectB根据自身依赖版本选择对应的ProjectA模块,实现版本适配。
  • 禁止提前织入:所有织入逻辑必须在使用方(ProjectB)完成,绝对不要在ProjectA中对第三方依赖进行织入操作,确保依赖版本由使用方完全控制。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 19:00:32