一、自定义注解
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Documented
public @interface RedisCache {
String key() default "";
long expire() default 1;
TimeUnit TIME_UNIT() default TimeUnit.HOURS;
Class clazz() default Object.class;
boolean isArray() default false;
}
二、AOP切面环绕通知
@Component
@Aspect
public class RedisCacheAspect {
private static final Logger log = LoggerFactory.getLogger(RedisCacheAspect.class);
@Autowired
private StringRedisTemplate stringRedisTemplate;
@Around("@annotation(com.xxx.xxx.web.aspect.RedisCache)")
public Object cacheInterceptor(ProceedingJoinPoint joinPoint) throws Throwable {
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = joinPoint.getTarget().getClass().getMethod(signature.getName(), signature.getParameterTypes());
RedisCache redisCache = method.getAnnotation(RedisCache.class);
String redisKey = redisCache.key();
if ( redisKey.indexOf("#") > -1 ) {
Expression expression = new SpelExpressionParser().parseExpression(redisKey);
EvaluationContext context = new StandardEvaluationContext();
Object[] args = joinPoint.getArgs();
DefaultParameterNameDiscoverer discoverer = new DefaultParameterNameDiscoverer();
String[] parameterNames = discoverer.getParameterNames(method);
for (int i = 0; i < parameterNames.length; i++) {
context.setVariable(parameterNames[i], args[i]);
}
redisKey = expression.getValue(context).toString();
}
log.info("redisKey: {}", redisKey);
String value = stringRedisTemplate.opsForValue().get(redisKey);
if ( value == null ) {
Object data = joinPoint.proceed();
stringRedisTemplate.opsForValue().set(redisKey, JSON.toJSONString(data), redisCache.expire(), redisCache.TIME_UNIT());
return data;
}
log.info("从redis获取...");
return redisCache.isArray() ? JSON.parseArray(value, redisCache.clazz()) : JSON.parseObject(value, redisCache.clazz());
}
}
三、使用场景
@Service
public class PropConfigServiceImpl extends ServiceImpl<PropConfigDao, PropConfig> implements PropConfigService {
@Override
public String getValueByKey(String key) {
Wrapper<PropConfig> wrapper = new EntityWrapper<>();
wrapper.eq("prop_key", key);
PropConfig propConfig = this.selectOne(wrapper);
if ( propConfig != null ) {
return propConfig.getPropValue();
}
return null;
}
@RedisCache(key = "aaaList", expire = 7, TIME_UNIT = TimeUnit.DAYS, clazz = String.class, isArray = true)
@Override
public List<String> getCacheValue(String key) {
return JSON.parseArray(getValueByKey(key), String.class);
}
}