根据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@Componentpublic class CacheAspect {/** * 方法对应的缓存 * key:方法名 * value:对应的caffeine缓存 */private final Map<String, Cache> 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 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());}}

使用