package com.xs.common.redis.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.PARAMETER, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface XsCache {
String time() default "-1";
Class arrayClassType() default Object.class;
}
package com.xs.common.redis.aspect;
import com.alibaba.fastjson.JSON;
import com.xs.common.redis.annotation.XsCache;
import com.xs.common.redis.annotation.XsCacheDelete;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.annotation.Order;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.DigestUtils;
import javax.annotation.Resource;
import java.lang.reflect.Method;
import java.nio.charset.StandardCharsets;
import java.util.Collection;
import java.util.Random;
import java.util.concurrent.TimeUnit;
@Aspect
@Component
@Order(Integer.MIN_VALUE)
public class BusCacheAspect {
@Resource
StringRedisTemplate stringRedisTemplate;
@Around("@annotation(com.xs.common.redis.annotation.XsCache)")
public Object around(ProceedingJoinPoint point) throws Throwable {
MethodSignature signature = (MethodSignature) point.getSignature();
Method method = signature.getMethod();
XsCache xsCache = method.getAnnotation(XsCache.class);
String time = xsCache.time();
Long cacheTime = getCacheTime(time);
String className = point.getTarget().getClass().getName();
String methodName = signature.getName();
Object[] args = point.getArgs();
String hashKey = DigestUtils.md5DigestAsHex(JSON.toJSONString(args).getBytes(StandardCharsets.UTF_8));
String key = "buscache" + ":" + className + ":" + methodName;
Class<?> returnType = method.getReturnType();
BoundHashOperations<String, String, String> ops = stringRedisTemplate.boundHashOps(key);
String cacheData = ops.get(hashKey);
if (cacheData != null) {
if (Collection.class.isAssignableFrom(returnType)){
Class arrayClassType = xsCache.arrayClassType();
return JSON.parseArray(cacheData,arrayClassType);
}else {
return JSON.parseObject(cacheData, returnType);
}
}
Object result = point.proceed();
if (!cacheTime.equals(0L)) {
if (cacheTime.equals(-1L)) {
ops.put(hashKey, JSON.toJSONString(result));
} else {
ops.put(hashKey, JSON.toJSONString(result));
ops.expire(cacheTime, TimeUnit.SECONDS);
}
}
return result;
}
private Long getCacheTime(String time) {
Long cacheTime;
try {
if (time.contains("#")) {
String[] timeInterval = time.split("#");
Long start = Long.valueOf(timeInterval[0]);
if (start.compareTo(0L) <= 0) {
throw new RuntimeException("随机起始时间不能等于小于0");
}
Long end = Long.valueOf(timeInterval[1]);
if (start.compareTo(end) > 0) {
throw new RuntimeException("随机起始时间不能大于结束时间");
}
Random r = new Random();
cacheTime = start + ((long) (r.nextDouble() * (end - start)));
} else {
Long temp = Long.valueOf(time);
if (temp.compareTo(0L) <= 0) {
cacheTime = -1L;
} else {
cacheTime = temp;
}
}
} catch (Exception e) {
cacheTime = 0L;
}
return cacheTime;
}
@Before("@annotation(com.xs.common.redis.annotation.XsCacheDelete)")
public void beforeAdvice(JoinPoint point) {
MethodSignature signature = (MethodSignature) point.getSignature();
Method method = signature.getMethod();
XsCacheDelete xsCacheDelete = method.getAnnotation(XsCacheDelete.class);
String k = xsCacheDelete.key();
stringRedisTemplate.delete(k);
}
}
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
@XsCache(time = "720#1080")
package com.xs.common.redis.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.PARAMETER, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface XsCacheDelete {
String key();
}
@XsCacheDelete(key = "buscache:com.xs.thirdparty.service.impl.TaskAccessRecordServiceImpl:queryCareRule")