Springboot系列:Springboot+Redis优雅的实现分布式缓存(redisTemplate及Annotation)
致力于让开发者快速搭建基础环境并让应用跑起来,并提供使用示例供使用者参考,快速上手。
本博客项目源码地址:
pom.xml
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-data-redisartifactId>
dependency>
<dependency>
<groupId>org.springframework.sessiongroupId>
<artifactId>spring-session-data-redisartifactId>
dependency>
<dependency>
<groupId>org.apache.commonsgroupId>
<artifactId>commons-pool2artifactId>
<version>2.10.0version>
dependency>
application.yml
spring:
# redis 配置
redis:
database: 0
host: 127.0.0.1
port: 6379
#连接超时时间
timeout: 3000
password: 123456
#连接池配置
lettuce:
pool:
max-active: 8
max-idle: 8
min-idle: 0
max-wait: -1
RedisConfig.java
配置,配置序列化方式@Configuration
@EnableCaching
public class RedisConfig extends CachingConfigurerSupport {
/**
* RedisTemplate 默认使用 jdk 序列化,存在乱码等问题,将 value 的序列化方式换为 Jackson 后,value 中不再出现乱码。
*/
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(redisConnectionFactory);
template.setKeySerializer(RedisSerializer.string());
template.setValueSerializer(new GenericJackson2JsonRedisSerializer());
template.setHashKeySerializer(new StringRedisSerializer());
template.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());
template.setEnableTransactionSupport(true);
return template;
}
}
RedisUtils.java
/**
* Redis工具类
*/
@Component
@Slf4j
public class RedisUtils {
@Resource
private RedisTemplate<String, Object> rt;
private static RedisTemplate<String, Object> redisTemplate;
@PostConstruct
public void init() {
// bean赋值给静态变量
redisTemplate = rt;
}
/**
* 存储
*
* @param cacheKey 缓存key
* @param value 值
* @param timeout 超时时间 秒
*/
public static void save(String cacheKey, Object value, long timeout) {
redisTemplate.opsForValue().set(cacheKey, value, timeout, TimeUnit.SECONDS);
}
public static void save(String cacheKey, Object value) {
save(cacheKey, value, -1);
}
/**
* 获取
*
* @param cacheKey 缓存key
* @param c 返回值类型
* @return c类型的对象
*/
public static <T> T get(String cacheKey, Class<T> c) {
Object o = redisTemplate.opsForValue().get(cacheKey);
return JSON.parseObject(JSON.toJSONString(o), c);
}
/**
* 缓存是否存在
*
* @param cacheKey 缓存key
* @return true 存在
*/
public static boolean hasKey(String cacheKey) {
return Boolean.TRUE.equals(redisTemplate.hasKey(cacheKey));
}
/**
* 添加到set集合
*
* @param cacheKey 缓存key
* @param value 值 一个或多个
*/
public static void addForSet(String cacheKey, Object... value) {
redisTemplate.opsForSet().add(cacheKey, value);
}
/**
* 获取set集合
*
* @param cacheKey 缓存
* @param c 返回值类型
* @return c类型的set集合
*/
public static <T> Set<T> getForSet(String cacheKey, Class<T> c) {
Set<Object> set = redisTemplate.boundSetOps(cacheKey).members();
if (Objects.isNull(set)) {
return null;
}
return set.stream().map(o -> JSON.parseObject(JSON.toJSONString(o), c)).collect(Collectors.toSet());
}
/**
* 设置过期时间
*
* @param cacheKey 缓存 key
* @param timeout 过期时间(秒)
*/
public static void expire(String cacheKey, long timeout) {
redisTemplate.expire(cacheKey, timeout, TimeUnit.MINUTES);
}
/**
* 删除指定缓存
*
* @param cacheKey 缓存key
*/
public static Boolean delete(String cacheKey) {
return redisTemplate.delete(cacheKey);
}
/**
* 指定元素删除
*
* @param cacheKey 缓存
* @param objKey 集合元素
*/
public static void remove(String cacheKey,String objKey) {
redisTemplate.boundSetOps(cacheKey).remove(objKey);
}
}
User.java
@Data
@Accessors(chain = true)
public class User implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 用户id
*/
private Long userId;
/**
* 用户名
*/
private String username;
/**
* 性别
*/
private String sex;
/**
* 备注
*/
private String remark;
}
@RestController
@RequiredArgsConstructor
public class IndexController {
/**
* 手动设置缓存
*/
@GetMapping("/set")
public String set() {
RedisUtils.save("key", new User().setUserId(999L).setSex("男").setUsername("王小锤"), 6000);
return "设置成功 !";
}
/**
* 手动获取缓存
*/
@GetMapping("/get")
public User get() {
return RedisUtils.get("key", User.class);
}
}
RedisConfig.java
中加入如下配置 /**
* 此处重写·springboot注解方式·缓存的Key生成规则
* key=包+方法名+参数
*/
@Override
@Bean
public KeyGenerator keyGenerator() {
return (target, method, params) -> {
StringBuilder sb = new StringBuilder();
sb.append(target.getClass().getName());
sb.append(method.getName());
for (Object obj : params) {
sb.append(Objects.nonNull(obj) ? obj.toString() : "null");
}
System.out.println(sb);
return sb.toString();
};
}
/**
* 此处重写·springboot注解方式·缓存的序列化方式及有效时间
* key=包+方法名+参数
*/
@Bean
public CacheManager cacheManager(RedisConnectionFactory connectionFactory) {
RedisCacheConfiguration cacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
// 将::改写为一个:
.computePrefixWith(cacheName -> cacheName + ":")
// 设置缓存有效期24小时
.entryTtl(Duration.ofHours(24))
// 禁止空值
.disableCachingNullValues()
// 设置序列化规则
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()));
return RedisCacheManager.builder(connectionFactory)
.cacheDefaults(cacheConfiguration)
.build();
}
IUserService.java
public interface IUserService {
/**
* 缓存测试
*
* @param id 用户id 随便输入
* @return 用户数据
*/
User getUser(Long id);
/**
* 删除缓存测试
*
* @param id 用户id 随便输入
*/
void delUser(Long id);
}
UserServiceImpl.java
,模拟数据库存储@Cacheable(value = "user-key")
@CacheEvict(value = "user-key", allEntries = true)
@Service
@Slf4j
public class UserServiceImpl implements IUserService {
@Override
@Cacheable(value = "user-key")
public User getUser(Long id) {
return this.getUserInfo(id);
}
@Override
@CacheEvict(value = "user-key", allEntries = true)
public void delUser(Long id) {
this.delUserInfo(id);
}
public void delUserInfo(Long id) {
log.info("删除{}用户数据执行了!!", id);
}
/**
* 模拟数据库查询
*/
private User getUserInfo(Long id) {
log.info("获取用户数据执行了!!");
return new User().setUserId(id).setUsername("王小锤").setSex("男").setRemark("注解方式aop实现缓存");
}
}
本项目已收录