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

如何在AspectJ切面关联中获取Pointcut上下文的注解参数

解决方案

核心限制说明

AspectJ的pertarget/percflow这类切面实例化子句,仅支持绑定目标对象、this这类类级别的上下文,无法直接绑定方法级别的注解实例。而且你原有的方案存在逻辑缺陷:pertarget是按目标类实例创建切面,同一个类的多个@Memoized方法如果配置了不同的过期时间,是无法共用同一个切面实例的缓存的。

推荐实现方案

改用单例切面,维护一个方法级别的缓存映射表,第一次调用标注了@Memoized的方法时,自动读取注解的过期配置创建对应缓存,后续调用直接复用该缓存。代码实现如下:

import java.time.Duration;
import java.util.Arrays;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.google.common.util.concurrent.ExecutionError;
import com.google.common.util.concurrent.UncheckedExecutionException;

public aspect Memoize {
    // 存储每个方法对应的专属缓存,key为方法签名
    private final ConcurrentMap<String, Cache<String, Object>> methodCaches = new ConcurrentHashMap<>();

    public pointcut memoized(Memoized memoized) : call(@Memoized * *.*()) && @annotation(memoized) ;

    Object around(Memoized memoized): memoized(memoized) {
        String methodSignature = thisJoinPoint.getSignature().toShortString();
        // 首次调用时初始化对应过期时间的缓存
        Cache<String, Object> cache = methodCaches.computeIfAbsent(methodSignature, sig -> {
            Duration expireAfter = Duration.parse(memoized.value());
            return CacheBuilder.newBuilder()
                    .expireAfterWrite(expireAfter)
                    .build();
        });
        try {
            // 无参方法直接用方法签名作为缓存key即可
            return cache.get(methodSignature, () -> proceed(memoized));
        } catch (ExecutionException | UncheckedExecutionException | ExecutionError e) {
            throw new RuntimeException("缓存执行失败", e.getCause());
        }
    }
}

优化提示

如果后续需要支持带参数的方法缓存,可以将缓存key调整为「方法签名 + 参数值哈希」的组合;如果需要隔离不同对象实例的缓存,可以在key中加入目标对象的哈希值:
String cacheKey = thisJoinPoint.getTarget().hashCode() + "_" + methodSignature + "_" + Arrays.hashCode(thisJoinPoint.getArgs());


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 09:33:02