启动类在加上注解 @EnableCaching
开启缓存注解,主要适用于整个接口返回结果需要缓存的场景,其他情况,由于业务场景比较复杂,也就是单独某段代码需要缓存,使用redis的客户端会更加灵活。@Cacheable 的cacheNames可以理解为缓存key的前缀或者一级目录(redis可视化工具下)。
引入依赖:
org.springframework.boot
spring-boot-starter-cache
org.springframework.boot
spring-boot-starter-data-redis
@Configuration
@Slf4j
public class ActivityRedisConfig extends CachingConfigurerSupport {
@Bean
@SuppressWarnings(value = {"unchecked", "rawtypes"})
public RedisTemplate
方式一:
@PostMapping("users/info")
@Cacheable(cacheNames = "测试", key = "#user.id", unless = "!#result?.result")
@CapCode
public ResultMessage info(@RequestBody User user) {
System.out.println("controller[url=users/login]");
return ResultMessage.success(user);
}
方式二:自定义keyGenerator
@PostMapping("users/info")
@Cacheable(cacheNames = "测试", keyGenerator = "activityKeyGenerator", unless = "!#result?.result")
@CapCode
public ResultMessage info(@RequestBody User user) {
System.out.println("controller[url=users/login]");
return ResultMessage.success(user);
}
其中unless的使用非常重要,决定什么情况下使用缓存,一般是接口查询成功才使用缓存,失败了就不需要缓存,具体使用看文章底部参考文章,另外说一点unless处理boolean类型时,表达式返回结果是false才缓存,上文接口处理成功,unless = "!#result?.result"。
返回封装如下:
public class ResultMessage implements Serializable {
/**
*
*/
private static final long serialVersionUID = 3443815263986524969L;
public ResultMessage() {
}
/**
* @param result
* @param code
* @param msg
* @param data
*/
public ResultMessage(Boolean result, int code, String msg, T data) {
this.result = result;
this.code = code;
this.msg = msg;
this.data = data;
}
/**
* 结果,true 成功,false 失败
*/
private Boolean result = true;
/**
* 编码
*/
private int code;
/**
* 提示信息
*/
private String msg;
/**
* 业务数据
*/
private T data;
/**
* 成功
*
* @param msg
* @param data
* @return
*/
public static ResultMessage success(String msg, TT data) {
return new ResultMessage(Boolean.TRUE, Constants.SUCCESS_CODE, msg, data);
}
/**
* 成功
*
* @param data
* @return
*/
public static ResultMessage success(TT data) {
return new ResultMessage(Boolean.TRUE, Constants.SUCCESS_CODE, Constants.RET_SUCCESS_MESSAGE, data);
}
/**
* 成功
*
* @param msg
* @return
*/
public static ResultMessage success(String msg) {
return new ResultMessage(Boolean.TRUE, Constants.SUCCESS_CODE, msg, null);
}
/**
* 失败
*
* @param msg
* @param data
* @return
*/
public static ResultMessage fail(String msg, TT data) {
return new ResultMessage(Boolean.FALSE, Constants.FAIL_CODE, msg, data);
}
/**
* 失败
*
* @param data
* @return
*/
public static ResultMessage fail(TT data) {
return new ResultMessage(Boolean.FALSE, Constants.FAIL_CODE, Constants.RET_FAIL_MESSAGE, data);
}
/**
* 失败
*
* @param msg
* @return
*/
public static ResultMessage fail(String msg) {
return new ResultMessage(Boolean.FALSE, Constants.FAIL_CODE, msg, null);
}
/**
* 异常
*
* @param msg
* @param data
* @return
*/
public static ResultMessage error(String msg, TT data) {
return new ResultMessage(Boolean.FALSE, Constants.ERROR_CODE, msg, data);
}
/**
* 异常
*
* @param data
* @return
*/
public static ResultMessage error(TT data) {
return new ResultMessage(Boolean.FALSE, Constants.ERROR_CODE, Constants.RET_ERROR_MESSAGE, data);
}
/**
* 异常
*
* @param msg
* @return
*/
public static ResultMessage error(String msg) {
return new ResultMessage(Boolean.FALSE, Constants.ERROR_CODE, msg, null);
}
/**
* 返回结果
*
* @param result
* @param code
* @param msg
* @param data
* @return
*/
public static ResultMessage result(Boolean result, int code, String msg, TT data) {
return new ResultMessage(result, code, msg, data);
}
public Boolean getResult() {
return result;
}
public void setResult(Boolean result) {
this.result = result;
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
@Override
public String toString() {
return "ResultMessage{" +
"result=" + result +
", code=" + code +
", msg='" + msg + '\'' +
", data=" + data +
'}';
}
}
public class FastJson2JsonRedisSerializer implements RedisSerializer {
@SuppressWarnings("unused")
private ObjectMapper objectMapper = new ObjectMapper();
public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");
private Class clazz;
static {
ParserConfig.getGlobalInstance().setAutoTypeSupport(true);
}
public FastJson2JsonRedisSerializer(Class clazz) {
super();
this.clazz = clazz;
}
@Override
public byte[] serialize(T t) throws SerializationException {
if (t == null) {
return new byte[0];
}
return JSON.toJSONString(t, SerializerFeature.WriteClassName).getBytes(DEFAULT_CHARSET);
}
@Override
public T deserialize(byte[] bytes) throws SerializationException {
if (bytes == null || bytes.length <= 0) {
return null;
}
String str = new String(bytes, DEFAULT_CHARSET);
return JSON.parseObject(str, clazz);
}
public void setObjectMapper(ObjectMapper objectMapper) {
Assert.notNull(objectMapper, "'objectMapper' must not be null");
this.objectMapper = objectMapper;
}
protected JavaType getJavaType(Class> clazz) {
return TypeFactory.defaultInstance().constructType(clazz);
}
}
参考:
redis@Cacheable注解unless用法
Springboot 之 @Cacheable 各种序列化及有效时间设置