根据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());
}
}
使用
文章来源地址https://www.toymoban.com/news/detail-542036.html
文章来源:https://www.toymoban.com/news/detail-542036.html
到了这里,关于根据aop实现自定义缓存注解的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!