特别说明: 本文针对的是新版 spring boot 2.1.3, 其 spring data 依赖为 spring-boot-starter-data-Redis, 且其默认连接池为 lettuce
Redis 作为一个高性能的内存数据库, 如果不会用就太落伍了, 之前在 node.JS 中用过 Redis, 本篇记录如何将 Redis 集成到 spring boot 中. 提供 Redis 操作类, 和注解使用 Redis 两种方式. 主要内容如下:
docker 安装 Redis
springboot 集成 Redis
编写 Redis 操作类
通过注解使用 Redis
安装 Redis
通过 docker 安装, docker compose 编排文件如下:
- # docker-compose.YAML
- version: "2"
- services:
- Redis:
- container_name: Redis
- image: Redis:3.2.10
- ports:
- - "6379:6379"
然后在 docker-compose.YAML 所在目录使用 docker-compose up -d 命令, 启动 Redis.
集成 springboot
说明: springboot 版本为 2.1.3
添加 maven 依赖
只需添加 spring-boot-starter-data-Redis 依赖即可, 并排除 lettuce 依赖, 然后引入 jedis 和 jedis 的依赖 commons-pool2
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-data-Redis</artifactId>
- <exclusions>
- <exclusion>
- <groupId>io.lettuce</groupId>
- <artifactId>lettuce-core</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
- <dependency>
- <groupId>org.apache.commons</groupId>
- <artifactId>commons-pool2</artifactId>
- </dependency>
- <dependency>
- <groupId>Redis.clients</groupId>
- <artifactId>jedis</artifactId>
- </dependency>
编写 springboot 配置文件
配置文件如下:
- server:
- port: 8081
- servlet:
- context-path: /sso
- spring:
- application:
- name: SSO
- cache:
- type: Redis
- Redis:
- database: 0
- host: 192.168.226.5
- port: 6379
- # 有密码填密码, 没有密码不填
- password:
- # 连接超时时间 (ms)
- timeout: 1000ms
- # 高版本 springboot 中使用 jedis 或者 lettuce
- jedis:
- pool:
- # 连接池最大连接数 (负值表示无限制)
- max-active: 8
- # 连接池最大阻塞等待时间 (负值无限制)
- max-wait: 5000ms
- # 最大空闲链接数
- max-idle: 8
- # 最小空闲链接数
- min-idle: 0
编写配置类
配置类代码如下:
- @EnableCaching// 开启缓存
- @Configuration
- public class RedisConfig extends CachingConfigurerSupport {
- /**
- * 设置缓存管理器, 这里可以配置默认过期时间等
- *
- * @param connectionFactory 连接池
- * @return
- */
- @Bean
- public CacheManager cacheManager(RedisConnectionFactory connectionFactory) {
- RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration
- .defaultCacheConfig()
- .entryTtl(Duration.ofSeconds(60));
- // 注意: 请勿使用先 new 配置对象, 然后在调用 entryTtl 方法的方式来操作
- // 会导致配置不生效, 原因是调用. entryTtl 方法会返回一个新的配置对象, 而不是在原来的配置对象上修改
- RedisCacheWriter redisCacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(connectionFactory);
- RedisCacheManager manager = new RedisCacheManager(redisCacheWriter, redisCacheConfiguration);
- return manager;
- }
- @SuppressWarnings("all")
- @Bean
- public RedisTemplate<String, String> redisTemplate(JedisConnectionFactory factory) {
- StringRedisTemplate template = new StringRedisTemplate(factory);
- 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);
- RedisSerializer stringSerializer = new StringRedisSerializer();
- template.setKeySerializer(stringSerializer);
- template.setValueSerializer(jackson2JsonRedisSerializer);
- template.setHashKeySerializer(stringSerializer);
- template.setHashValueSerializer(jackson2JsonRedisSerializer);
- template.afterPropertiesSet();
- return template;
- }
- // 使用 jedis 连接池建立 jedis 连接工厂
- @Bean
- public JedisConnectionFactory jedisConnectionFactory() {
- logger.info("jedisConnectionFactory: 初始化了");
- JedisPoolConfig config = new JedisPoolConfig();
- config.setMaxIdle(maxIdle);
- config.setMinIdle(minIdle);
- config.setMaxWaitMillis(maxWaitMillis);
- config.setMaxTotal(maxActive);
- // 链接耗尽时是否阻塞, 默认 true
- config.setBlockWhenExhausted(true);
- // 是否启用 pool 的 jmx 管理功能, 默认 true
- config.setJmxEnabled(true);
- JedisConnectionFactory factory = new JedisConnectionFactory();
- factory.setPoolConfig(config);
- factory.setHostName(host);
- factory.setPort(port);
- factory.setPassword(password);
- factory.setDatabase(database);
- factory.setTimeout(timeout);
- return factory;
- }
- }
使用方法
有两种方法来进行缓存操作, 一种是在方法上添加缓存注解实现各种操作, 一种是手动控制. 个人比较喜欢手动控制, 觉得这样都在自己的掌控中.
通过注解使用
主要有以下 5 个注解:
@CacheConfig: 类级别缓存, 设置缓存 key 前缀之类的
@Cacheable: 触发缓存入口
@CacheEvict: 触发移除缓存
@CachePut: 更新缓存
@Caching: 组合缓存
@CacheConfig
该注解可以将缓存分类, 它是类级别注解, 主要用于给某个类的缓存全局配置, 例子如下:
- @CacheConfig(cacheNames = "redis_test")
- @Service
- public class RedisService {
- //....
- }
上面 CacheConfig 会给类下通过注解生成的 key 加上 redis_test 的前缀.
@Cacheable
方法级别注解, 根据 key 查询缓存:
如果 key 不存在, 将方法返回值缓存到 Redis 中
如果 key 存在, 直接从缓存中取值
例子如下:
- /**
- * 缓存时间, 首次查询后会缓存结果, key 中的值可使用表达式计算.
- * 如不提供 key, 将使用默认 key 构造方法生成一个 key
- * @return long
- */
- @Cacheable(key = "'currentTime'")
- public long getTime() {
- return System.currentTimeMillis();
- }
多次调用此段代码会发现每次返回的值都是一样的.
CachePut
用于更新缓存, 每次调用都会想 db 请求, 缓存数据
如果 key 存在, 更新内容
如果 key 不存在, 插入内容
代码如下:
- /**
- * 一般用于更新查插入操作, 每次都会请求 db
- */
- @CachePut(key = "'currentTime'+#id")
- public long updateTime(String id) {
- return System.currentTimeMillis();
- }
每次调用此方法都会根据 key 刷新 Redis 中的缓存数据.
@CacheEvict
根据 key 删除缓存中的数据. allEntries=true 表示删除缓存中所有数据.
代码如下:
- @CacheEvict(key = "'currentTime'+#id",allEntries=false)
- public void deleteTime(String id) {
- }
- @Caching
本注解可将其他注解组合起来使用. 比如下面的例子:
- //value 属性为 key 指定前缀
- @Caching(put = {@CachePut(value = "user", key = "'name_'+#user.name"),
- @CachePut(value = "user", key = "'pass_'+#user.password")})
- public User testCaching(User user) {
- return user;
- }
上面的代码执行后将在 Redis 中插入两条记录. 使用 keys * 将看到如下结果:
手动控制
手动控制就相当于 mybatis 的手写 sql 语句, 需要调用 redisTemplate 中的各种方法来进行缓存查询, 缓存更新, 缓存删除等操作.
使用方法参见 util/RedisUtil 中的方法. redisTemplate 基本可以实现所有的 Redis 操作.
来源: https://www.cnblogs.com/wuyoucao/p/10941792.html