根据aop实现自定义缓存注解

根据aop实现自定义缓存注解

自定义注解

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.concurrent.TimeUnit;

/**
 * @author: yanchenyang958@hellobike.com
 * @date: 2023-07-04 11:26
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface CacheAnnotation {

    /**
     * 是:全局缓存(每个用户看到的一样)
     * 否:对用户维度缓存
     *
     * @return 是否为全局
     */
    boolean isGlobal();

    /**
     * 缓存时间
     *
     * @return 缓存时间
     */
    long time();

    /**
     * 缓存单位
     *
     * @return 缓存单位
     */
    TimeUnit timeUnit();

    /**
     * 缓存和参数有关
     *
     * @return 参数
     */
    boolean paramsDependent() default false;
}


切面

package com.hello.smart.analyzer.common.cache;

import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import com.hello.smart.analyzer.common.util.UserHolder;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

/**
 * 缓存切面
 *
 * @author: yanchenyang958@hellobike.com
 * @date: 2023-07-04 16:16
 */
@Aspect
@Component
public class CacheAspect {

    /**
     * 方法对应的缓存
     * key:方法名
     * value:对应的caffeine缓存
     */
    private final Map<String, Cache<String, Object>> cacheHashMap = new HashMap<>(16);

    @Pointcut("@annotation(com.hello.smart.analyzer.common.cache.CacheAnnotation)")
    public void pointcut() {
        System.out.println("进入切面执行");
    }

    @Around(value = "pointcut()")
    public Object AroundMethod(ProceedingJoinPoint proceedingJoinPoint) {
        MethodSignature signature = (MethodSignature) proceedingJoinPoint.getSignature();
        Method method = signature.getMethod();
        String methodName = method.getName();
        String className = method.getDeclaringClass().getName();
        String mapKey = className + methodName;
        CacheAnnotation cacheAnnotation = method.getAnnotation(CacheAnnotation.class);
        //去全局map中查找方法名对应的caffeine缓存
        Cache<String, Object> cache = cacheHashMap.get(mapKey);
        //获得方法名
        StringBuilder key = new StringBuilder(cacheAnnotation.isGlobal() ? mapKey : String.format("%s%s", mapKey, UserHolder.getUserEmail()));
        //如果缓存和参数值有关
        if (cacheAnnotation.paramsDependent()) {
            Object[] args = proceedingJoinPoint.getArgs();
            for (Object arg : args) {
                key.append(arg.toString());
            }
        }
        //如果缓存存在
        if (cache != null) {
            Object resp = cache.getIfPresent(key.toString());
            if (resp != null) {
                return resp;
            }
        }
        //如果缓存不存在
        try {
            Object returnObj = proceedingJoinPoint.proceed();
            if (cache == null) {
                cache = Caffeine.newBuilder()
                        .expireAfterWrite(cacheAnnotation.time(), cacheAnnotation.timeUnit())
                        .maximumSize(5000)
                        .build();
                cacheHashMap.put(mapKey, cache);
            }
            cache.put(key.toString(), returnObj);
        } catch (Throwable e) {
            throw new RuntimeException(e);
        }
        return cache.getIfPresent(key.toString());
    }
}

使用

在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值