SpringBoot自带Cache存在问题:
1.生成Key过于简单,容易冲突 默认为cacheNames + ":" + Key2.无法设置过期时间,默认时间是永久3.配置序列化方式,默认是JDKSerializable,可能造成乱码
自定义Cache分三个步骤:
1.自定义KeyGenerator2.自定义cacheManager 设置缓存过期时间3.自定义序列化方式 JackSon
1.修改pom.xml文件
org.springframework.boot
spring-boot-starter-data-redis
org.springframework.boot
spring-boot-starter-cache
2.添加RedisConfig.java配置
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.cache.RedisCacheWriter;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import java.time.Duration;
import java.util.HashMap;
import java.util.Map;
/**
* @EnableCaching 开启SpringBoot的Cache缓存
*
* */
@Configuration
@EnableCaching
public class RedisConfig {
@Bean
public RedisTemplate redisTemplate(RedisConnectionFactory factory){
RedisTemplate template = new RedisTemplate<>();
template.setConnectionFactory(factory);
return template;
}
/**
* 自定义key值格式
*
* */
@Bean
public KeyGenerator simpleKeyGenerator(){
return (o, method, objects) -> {
StringBuilder builder = new StringBuilder();
//获取类名称
builder.append(o.getClass().getSimpleName());
builder.append(".");
//获取方法名称
builder.append(method.getName());
builder.append("[");
//遍历方法参数
for (Object obj : objects){
builder.append(obj.toString());
}
builder.append("]");
return builder.toString();
};
}
@Bean
public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory){
return new RedisCacheManager(
RedisCacheWriter.lockingRedisCacheWriter(redisConnectionFactory),
//默认Cache缓存的超时配置
this.getRedisCacheConfigurationWithTtl(30),
//自定义Cache缓存Key的超时配置
this.getRedisCacheConfigurationMap()
);
}
/**
* 配置自定义Cache缓存Key的超时规则
*
* */
public Map getRedisCacheConfigurationMap(){
Map redisCacheConfigurationMap = new HashMap<>();
redisCacheConfigurationMap.put("UserInfoCacheList", this.getRedisCacheConfigurationWithTtl(20));
// redisCacheConfigurationMap.put("UserInfoCacheAnother", this.getRedisCacheConfigurationWithTtl(30));
return redisCacheConfigurationMap;
}
/**
* 自定义Cache缓存超时规则
*
* */
public RedisCacheConfiguration getRedisCacheConfigurationWithTtl(Integer seconds){
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig();
//修改Key的命名规则 默认:cacheName + ":"
// .computePrefixWith(cacheName -> cacheName.concat(":"))
// .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()));
redisCacheConfiguration = redisCacheConfiguration.serializeValuesWith(
RedisSerializationContext
.SerializationPair
.fromSerializer(jackson2JsonRedisSerializer)
).entryTtl(Duration.ofSeconds(seconds));
return redisCacheConfiguration;
}
}
3.添加Service配置
备注:
只有最后一个是自定义的 前面的是springboot自带的方法
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.theng.shopuser.entity.UserInfo;
import com.theng.shopuser.entity.dto.UserInfoDto;
import com.theng.shopuser.mapper.UserInfoMapper;
import com.theng.shopuser.service.UserInfoService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Service;
import java.io.Serializable;
import java.util.List;
/**
*
* 服务实现类
*
*
* @author tianheng
* @since 2020-02-09
*/
@Service
@CacheConfig(cacheNames = "userInfoCache")
public class UserInfoService {
@Autowired
private UserInfoMapper userInfoMapper;/**
* 获取缓存中的UserInfo
* #p0: 对应方法参数 0表示第一个参数
*
* */
@Override
@Nullable
@Cacheable(key = "#p0", unless = "#result == null")
public UserInfo findUserInfoCache(String code){
return userInfoMapper.findUserInfoByCode(code);
}
/**
* 向缓存中插入UserInfo
* return: 必须要有返回值 否则无法保存到缓存中
*
* */
@Override
@CachePut(key = "#p0.userCode")
public UserInfo insertUserInfoCache(UserInfo userInfo){
return null;
}
/**
* 向缓存中插入UserInfo
* return: 必须要有返回值 否则无法保存到缓存中
*
* */
@Override
@CachePut(key = "#p0.userCode")
public UserInfo updateUserInfoCache(UserInfo userInfo){
return null;
}
/**
* 删除cacheNames = "userInfoCache",key值为指定值的缓存
*
* */
@Override
@CacheEvict(key = "#p0")
public void deleteUserInfoCache(String userCode){
}
/**
* 清除cacheNames = "userInfoCache"下的所有缓存
* 如果失败了,则不会清除
*
* */
@Override
@CacheEvict(allEntries = true)
public void deleteAllUserInfoCache(){
}
@Nullable
@Cacheable(value = "UserInfoCacheList", keyGenerator = "simpleKeyGenerator")
public UserInfo customUserInfoCache(){
return null;
}
}
4.修改controller.java
import com.theng.shopuser.bean.UserSessionBean;
import com.theng.shopuser.entity.UserInfo;
import com.theng.shopuser.service.UserInfoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.*;
import java.util.concurrent.TimeUnit;
@RestController
@RequestMapping("/user-info")
public class UserInfoController {
@Autowired
private UserInfoService userInfoService;
//测试
@GetMapping("/list2")
public Object getList2() {
UserInfo userInfo = userInfoService.findUserInfoByCode("YH006");
return "success";
}
@GetMapping("/list3")
public Object getList3() {
UserInfo userInfo = userInfoService.customUserInfoCache();
return "success";
}
}
5.修改pom.xml文件
spring:
redis:
database: 0
host: localhost
port: 6379
password:
6.输出结果
自定义
Original: https://www.cnblogs.com/tianhengblogs/p/15322852.html
Author: 玉天恒
Title: SpringBoot——自定义Redis缓存Cache
原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/529132/
转载文章受原作者版权保护。转载请注明原作者出处!