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

如何通过AspectJ替换System.currentTimeMillis()调用?切面为何未生效?

问题:AspectJ切面无法替换System.currentTimeMillis()返回值

我需要在测试用例中用自定义值替换System.currentTimeMillis()的返回结果,编写了如下AspectJ切面代码与测试代码:

切面代码

package org.example.aspectj;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;

@Aspect
public class TimeAspect
{
    @Around("execution(public static native long currentTimeMillis())")
    public long changeCallsToCurrentTimeInMillisMethod(ProceedingJoinPoint pjp)
    {
        return 0;
    }
}

测试代码

package org.example.aspectj;

public class TimeDemo
{
    public static void main(String[] args) {
        long currentTimeMillis = System.currentTimeMillis();
        System.out.println("currentTimeMillis -> " + currentTimeMillis);
    }
}

运行时出现警告:

[warning] advice defined in org.example.aspectj.TimeAspect has not been applied [Xlint:adviceDidNotMatch]

控制台输出原时间:

Task :TimeDemo.main()
  currentTimeMillis -> 1710770641050

时间并未被替换,请问问题出在哪里?


问题原因与解决办法

1. 切点表达式选错:用execution而非call

execution切入点匹配的是方法执行的逻辑位置,但System.currentTimeMillis()是JDK核心类java.lang.System的native方法,AspectJ无法修改JDK类的方法执行逻辑。我们需要匹配的是调用这个方法的代码位置,因此必须使用call切入点:

修正后的切面切点:

@Around("call(public static native long java.lang.System.currentTimeMillis())")

2. 必须使用原生AspectJ织入,不能用Spring AOP

如果是Spring环境,Spring AOP基于动态代理,不支持静态方法的切面拦截,必须切换为原生AspectJ的织入方式:

  • 编译时织入(CTW):在Maven/Gradle等构建工具中配置AspectJ编译器,让切面代码被织入到调用System.currentTimeMillis()的目标类中。
  • 加载时织入(LTW):通过JVM参数指定AspectJ代理类加载器,在类加载阶段动态织入切面逻辑。

3. 修正后的完整切面代码

package org.example.aspectj;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;

@Aspect
public class TimeAspect
{
    @Around("call(public static native long java.lang.System.currentTimeMillis())")
    public long changeCallsToCurrentTimeInMillisMethod(ProceedingJoinPoint pjp) {
        // 返回自定义时间戳
        return 1600000000000L;
    }
}

4. Gradle构建配置示例

如果用Gradle,需要添加AspectJ插件并配置织入范围:

plugins {
    id 'java'
    id 'io.freefair.aspectj' version '8.6'
}

dependencies {
    implementation 'org.aspectj:aspectjrt:1.9.21'
    implementation 'org.aspectj:aspectjweaver:1.9.21'
}

aspectj {
    ajcOptions {
        // 确保织入包含调用System.currentTimeMillis()的类
        include 'org/example/aspectj/**'
    }
}

内容的提问来源于stack exchange,提问作者Alexandre Marechal Ferrant

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 11:43:23