根據(jù)aop實(shí)現(xiàn)自定義緩存注解
自定義注解
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 {
/**
* 是:全局緩存(每個(gè)用戶看到的一樣)
* 否:對(duì)用戶維度緩存
*
* @return 是否為全局
*/
boolean isGlobal();
/**
* 緩存時(shí)間
*
* @return 緩存時(shí)間
*/
long time();
/**
* 緩存單位
*
* @return 緩存單位
*/
TimeUnit timeUnit();
/**
* 緩存和參數(shù)有關(guān)
*
* @return 參數(shù)
*/
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 {
/**
* 方法對(duì)應(yīng)的緩存
* key:方法名
* value:對(duì)應(yīng)的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("進(jìn)入切面執(zhí)行");
}
@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中查找方法名對(duì)應(yīng)的caffeine緩存
Cache<String, Object> cache = cacheHashMap.get(mapKey);
//獲得方法名
StringBuilder key = new StringBuilder(cacheAnnotation.isGlobal() ? mapKey : String.format("%s%s", mapKey, UserHolder.getUserEmail()));
//如果緩存和參數(shù)值有關(guān)
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());
}
}
使用
文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-542036.html
文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-542036.html
到了這里,關(guān)于根據(jù)aop實(shí)現(xiàn)自定義緩存注解的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!