一般的项目中都会使用缓存,如果你的项目是集群的,那么你肯定会使用 redis 来做缓存。
今天给大家讲讲 SpringBoot 如何整合 redis,以及一些常用的用法。示例有:@Cacheable、@CacheEvict、保存、查询、删除、消息订阅发布、id 自增、分布式锁、lua 脚本、哨兵、redis cluster 集群。
整体结构
pom 配置
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.cimu</groupId>
<artifactId>redis</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>redis</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.0.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<pool>2.4.2</pool>
<fastjson-version>1.2.47</fastjson-version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.20</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
核心代码
RedisConfig 类:配置了 key 生成策略,缓存管理器,不同泛型的 redisTemplate,配置不同的 RedisConnectionFactory。列出部分代码,具体源码可以看文末源码地址。
/**
* Redis缓存配置类
*/
@Configuration
@EnableRedisRepositories
public class RedisConfig extends CachingConfigurerSupport {
@Autowired
private RedisConnectionFactory factory;
/**
* 自定义缓存key生成策略
*/
@Bean
@Override
public KeyGenerator keyGenerator() {
return new KeyGenerator() {
@Override
public Object generate(Object target, Method method, Object... params) {
StringBuffer sb = new StringBuffer();
sb.append(target.getClass().getName()).append("_");
sb.append(method.getName());
for (Object obj : params) {
sb.append("_").append(obj == null ? "" : obj.toString());
}
return sb.toString();
}
};
}
/**
* 缓存管理器
*/
@Bean
@Primary
public CacheManager cacheManager(RedisConnectionFactory factory) {
// 设置缓存有效期一小时
RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(Duration.ofHours(1));
return RedisCacheManager
.builder(RedisCacheWriter.nonLockingRedisCacheWriter(factory))
.cacheDefaults(redisCacheConfiguration).build();
}
/**
* 5分钟失效缓存管理器
*/
@Bean
public CacheManager fiveMinutesManager(RedisConnectionFactory factory) {
// 设置缓存有效期5分钟
RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(Duration.ofMinutes(5));
return RedisCacheManager
.builder(RedisCacheWriter.nonLockingRedisCacheWriter(factory))
.cacheDefaults(redisCacheConfiguration).build();
}
@Bean
@ConditionalOnMissingBean(name = "redisTemplate")
public RedisTemplate<Serializable, Serializable> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<Serializable, Serializable> template = new RedisTemplate<>();
template.setConnectionFactory(factory);
//设置序列化工具
setSerializer(template);
template.afterPropertiesSet();
return template;
}
@Bean
@ConditionalOnMissingBean(StringRedisTemplate.class)
public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory factory) {
StringRedisTemplate template = new StringRedisTemplate();
template.setConnectionFactory(factory);
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
template.setValueSerializer(stringRedisSerializer);
template.setKeySerializer(stringRedisSerializer);
template.afterPropertiesSet();
return template;
}
/**
* 设置序列化工具
* @param template RedisTemplate
*/
@SuppressWarnings({"rawtypes", "unchecked"})
private void setSerializer(RedisTemplate template) {
GenericJackson2JsonRedisSerializer jackson2JsonRedisSerializer = new GenericJackson2JsonRedisSerializer();
template.setDefaultSerializer(jackson2JsonRedisSerializer);//发布订阅的时候,传输对象如果使用@Builder注解,需要实现无参构造函数
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
template.setKeySerializer(stringRedisSerializer);
template.setHashKeySerializer(stringRedisSerializer);
}
}
RedisSubListenerConfig 类:配置了发布订阅的相对于的类,监听的通道。
@Configuration
public class RedisSubListenerConfig {
@Autowired
RedisPublisher redisPublisher;
/**
* 初始化监听器 */ @Bean
RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory,
MessageListenerAdapter listenerAdapter) {
RedisMessageListenerContainer container = new RedisMessageListenerContainer();
container.setConnectionFactory(connectionFactory);
container.addMessageListener(listenerAdapter, new ChannelTopic(redisPublisher.getChannel()));
return container;
}
/**
* 利用反射来创建监听到消息之后的执行方法 */ @Bean
MessageListenerAdapter listenerAdapter(RedisReceiver redisReceiver) {
return new MessageListenerAdapter(redisReceiver, "receiveMessage");
}
}
发布/订阅处理的业务类:
如图,包里面是发布/订阅的代码
RedisPublisher:为发布消息逻辑。
RedisReceiver:为接收消息,在这里可以实现你的业务代码。
MessageHandler:为接口,业务处理的类都要实现该接口。messageType 方法表示支持哪些业务,processMsg 方法为具体的处理方法。不同的业务消息,只要你的消息类中定义了业务类型,并传入相应的业务类型,在 RedisReceiver 中判断支持哪些业务,在获取相应业务的处理类进行处理,具体实现可以看源码。
UserServiceTest 为单元测试类,所有的测试代码都在这里。
ClusterConfigProperties 类为 redis cluster 的节点配置。
配置
application.properties 文件:
#spring.redis.host=127.0.0.1
#spring.redis.database=0
#spring.redis.port=6379
#spring.redis.password=
spring.cache.type=redis
spring.redis.jedis.pool.max-idle=8
spring.redis.jedis.pool.min-idle=0
spring.redis.jedis.pool.max-active=8
spring.redis.jedis.pool.max-wait=10000
#spring.redis.sentinel.master=mymaster
#spring.redis.sentinel.nodes=127.0.0.1:5000,127.0.0.1:5001,127.0.0.1:5002
redis.cluster.nodes=127.0.0.1:6379,127.0.0.1:6380,127.0.0.1:6381
redis.cluster.maxRedirects=3
脚本
lua.script 目录下是 lua 脚本,lua 的语法可以去官网看看。
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于