自定义注解类:
package com.puboot.common.annotation;
import java.lang.annotation.*;
import java.util.concurrent.TimeUnit;
/**
* Redis缓存自定义注解
*/
@Target({ElementType.METHOD}) //标明注解可作用的地方 FIELD--字段 METHOD--方法
@Retention(RetentionPolicy.RUNTIME) //存活阶段 RUNTIME 运行时 还有JVM Class
@Inherited //可继承
public @interface Cache {
/**
* 业务的名称
*/
String value() default "";
/**
* redis缓存的Key(默认类名-方法名-自定义key)
*/
String key() default "";
/**
* 是否刷新缓存,默认false
*/
boolean flush() default false;
/**
* 缓存失效时间,默认30
*/
long expire() default 30L;
/**
* 缓存时间单位,默认天
*/
TimeUnit unit() default TimeUnit.DAYS;
}
切面类
package com.puboot.common.aspect;
import com.puboot.common.annotation.Cache;
import com.puboot.common.util.AspectUtil;
import com.puboot.module.admin.service.RedisService;
import lombok.extern.slf4j.Slf4j;
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.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;
/**
* Redis缓存自定义注解对应的切面
*
*/
@Slf4j
@Aspect
@Component
public class RedisCacheAspect {
private static final String CACHE_PREFIX = "pb_cms_";
@Autowired
private RedisService redisService;
/**
* 注解切入点 当引用这个注解之后需要执行的操作
*/
@Pointcut("@annotation(com.puboot.common.annotation.Cache)")
public void pointcut() {
}
/**
* 环绕通知
* @param point
* @return
* @throws Throwable
*/
@Around("pointcut()")
public Object handle(ProceedingJoinPoint point) throws Throwable {
//获取当前切面执行方法的方法名
Method currentMethod = AspectUtil.getMethod(point);
//获取类方法上的@RedisCache注解
Cache cache = currentMethod.getAnnotation(Cache.class);
if (cache.flush()) {
String classPrefix = AspectUtil.getKeyOfClassPrefix(point, CACHE_PREFIX);
if (log.isDebugEnabled()) {
log.debug("清空缓存 - {}*", classPrefix);
}
redisService.delBatch(classPrefix);
return point.proceed();
}
String key = AspectUtil.getKey(point, cache.key(), CACHE_PREFIX);
try {
if (redisService.hasKey(key)) {
if (log.isDebugEnabled()) {
log.debug("{}从缓存中获取数据", key);
}
return redisService.get(key);
}
} catch (Exception e) {
log.error("从缓存中获取数据失败!", e);
}
//先执行业务
Object result = point.proceed();
try {
redisService.set(key, result, cache.expire(), cache.unit());
} catch (Exception e) {
log.error("向缓存设置数据失败!", e);
}
if (log.isDebugEnabled()) {
log.debug("{}从数据库中获取数据", key);
}
return result;
}
}
调用注解类
package com.puboot.module.admin.service.impl;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.puboot.common.annotation.Cache;
import com.puboot.common.util.CoreConst;
import com.puboot.module.admin.mapper.BizThemeMapper;
import com.puboot.module.admin.model.BizTheme;
import com.puboot.module.admin.service.BizThemeService;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
@Service
@AllArgsConstructor
public class BizThemeServiceImpl extends ServiceImpl<BizThemeMapper, BizTheme> implements BizThemeService {
private final BizThemeMapper themeMapper;
@Override
@Cache(flush = true)
public int useTheme(Integer id) {
themeMapper.setInvaid();
return themeMapper.updateStatusById(id);
}
@Override
@Cache
public BizTheme selectCurrent() {
return themeMapper.selectOne(Wrappers.<BizTheme>lambdaQuery().eq(BizTheme::getStatus, CoreConst.STATUS_VALID));
}
}
主要通过切面实现缓存的业务逻辑; 通过里面的flush属性来控制缓存的刷新是否开启 默认是false