根据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()); } }
使用
下一篇:
CodeBlocks下载与安装教程