- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-Redis</artifactId>
- </dependency>
现在会提示 Project build error: 'dependencies.dependency.version' for org.springframework.boot:spring-boot-starter-Redis:jar is missing. 提示 spring-boot-starter-Redis:jar 找不到.
这是因为 Spring Boot 1.4 之后不再支持 spring-boot-starter-Redis, 更换 spring-boot-starter-data-Redis 之后就可以了. 如果你的 pom 文件报错, 请检查是否将 spring-boot-starter-Redis 改成了 spring-boot-starter-data-Redis.
Spring Boot 2.x 要使用下面的依赖:
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-data-Redis</artifactId>
- </dependency>
2. application.properties 添加配置文件
这是之前版本的配置文件:
- # Redis (RedisProperties)
- # Redis 数据库索引 (默认为 0)
- spring.Redis.database=0
- # Redis 服务器地址
- spring.Redis.host=127.0.0.1
- # Redis 服务器连接端口
- spring.Redis.port=6379
- # Redis 服务器连接密码 (默认为空)
- spring.Redis.password=
- # 连接池最大连接数 (使用负值表示没有限制)
- spring.Redis.pool.max-active=8
- # 连接池最大阻塞等待时间 (使用负值表示没有限制)
- spring.Redis.pool.max-wait=-1
- # 连接池中的最大空闲连接
- spring.Redis.pool.max-idle=8
- # 连接池中的最小空闲连接
- spring.Redis.pool.min-idle=0
- # 连接超时时间 (毫秒)
- spring.Redis.timeout=0
如果 Spring Boot 2.x 这么配置, 有错误提示 Property 'spring.redis.pool.max-active' is Deprecated: Use 'spring.redis.jedis.pool.max-idle' instead. 'spring.redis.pool.max-active'已经被弃用了, 推荐使用'spring.redis.jedis.pool.max-idle'来代替.
这是因为在 2.x 中配置 Redis 的连接池信息时, 不再使用 spring.Redis.pool 的属性, 而是直接使用 Redis 的 lettuce 或 jedis 客户端来配置. 现在的配置如下:
- # Redis (RedisProperties)
- # Redis 数据库索引 (默认为 0)
- spring.Redis.database=0
- # Redis 服务器地址
- spring.Redis.host=127.0.0.1
- # Redis 服务器连接端口
- spring.Redis.port=6379
- # Redis 服务器连接密码 (默认为空)
- spring.Redis.password=
- # 连接池最大连接数 (使用负值表示没有限制)
- spring.Redis.jedis.pool.max-active=8
- # 连接池最大阻塞等待时间 (使用负值表示没有限制)
- spring.Redis.jedis.pool.max-wait=-1
- # 连接池中的最大空闲连接
- spring.Redis.jedis.pool.max-idle=8
- # 连接池中的最小空闲连接
- spring.Redis.jedis.pool.min-idle=0
- # 连接超时时间 (毫秒)
- spring.Redis.timeout=0
3. 配置 CacheManager
这是之前的 RedisConfig 配置类:
- @Configuration
- @EnableCaching
- public class RedisConfig extends CachingConfigurerSupport {
- @Bean
- public CacheManager cacheManager(RedisTemplate<?, ?> redisTemplate) {
- CacheManager cacheManager = new RedisCacheManager(redisTemplate);
- return cacheManager;
- }
- @Bean
- public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory factory) {
- RedisTemplate<String, String> redisTemplate = new RedisTemplate<String, String>();
- redisTemplate.setConnectionFactory(factory);
- return redisTemplate;
- }
- }
现在这么写会有报错 The constructor RedisCacheManager(RedisTemplate<capture#1-of ?,capture#2-of ?>) is undefined.
这是因为 Spring Boot 2.x 版本删除了 RedisCacheManager 这个构造器, 也不可以通过之前的 setDefaultExpiration 方法设置默认的缓存过期时间等.
那么要怎样构造一个 RedisCacheManager? 看看官方文档中怎么说? 文档地址:
官方文档 5.13.1. Support for the Spring Cache Abstraction(对 Spring Cache Abstraction 的支持) 是关于怎么配置缓存的说明, 我尝试着翻译了一下 (蓝色部分), 英文水平有限, 各位轻喷.
Spring Redis provides an implementation for the Spring cache abstraction through the org.springframework.data.Redis.cache package. To use Redis as a backing implementation, add RedisCacheManager to your configuration, as follows:
Spring Redis 在 org.springframework.data.Redis.cache 包中为 Spring 缓存抽象提供了一个实现方案. 要使用 Redis 作为支持实现, 需要将 RedisCacheManager 添加到配置中, 如下所示:
- @Bean
- public RedisCacheManager cacheManager(RedisConnectionFactory connectionFactory) {
- return RedisCacheManager.create(connectionFactory);
- }
RedisCacheManager behavior can be configured with RedisCacheManagerBuilder, letting you set the default RedisCacheConfiguration, transaction behavior, and predefined caches.
RedisCacheManager 可以用 RedisCacheManagerBuilder 进行配置, 允许自定义设置默认的 RedisCacheConfiguration, 事务行为和预定义的缓存.
- RedisCacheManager cm = RedisCacheManager.builder(connectionFactory)
- .cacheDefaults(defaultCacheConfig())
- .initialCacheConfigurations(singletonMap("predefined", defaultCacheConfig().disableCachingNullValues()))
- .transactionAware()
- .build();
- As shown in the preceding example, RedisCacheManager allows definition of configurations on a per-cache basis.
正如上面的例子所示, RedisCacheManager 允许基于每个缓存进行配置.
The behavior of RedisCache created with RedisCacheManager is defined with RedisCacheConfiguration. The configuration lets you set key expiration times, prefixes, and RedisSerializer implementations for converting to and from the binary storage format, as shown in the following example:
RedisCacheManager 创建 RedisCache 的行为被定义为 RedisCacheConfiguration. 该配置允许设置键值过期时间, 前缀和 RedisSerializer 实现等属性, 以便与二进制存储格式进行转换, 如下所示:
- RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
- .entryTtl(Duration.ofSeconds(1))
- .disableCachingNullValues();
RedisCacheManager defaults to a lock-free RedisCacheWriter for reading and writing binary values. Lock-free caching improves throughput. The lack of entry locking can lead to overlapping, non-atomic commands for the putIfAbsent and clean methods, as those require multiple commands to be sent to Redis. The locking counterpart prevents command overlap by setting an explicit lock key and checking against presence of this key, which leads to additional requests and potential command wait times.
RedisCacheManager 默认是无锁的, 用于读写二进制值的 RedisCacheWriter. 无锁缓存可提高吞吐量. 缺少锁定可能导致 putIfAbsent 和 clean 方法的非原子命令重叠, 因为这些方法需要向 Redis 发送多条命令. 锁对应程序通过设置显式锁定的 key 并检查是否存在该 key 来防止命令重叠, 这会导致额外的请求和潜在的命令等待时间.
It is possible to opt in to the locking behavior as follows:
也可以选择锁定行为, 如下所示:
- RedisCacheManager cm = RedisCacheManager.build(RedisCacheWriter.lockingRedisCacheWriter())
- .cacheDefaults(defaultCacheConfig())
- ...
- By default, any key for a cache entry gets prefixed with the actual cache name followed by two colons. This behavior can be changed to a static as well as a computed prefix.
默认情况下, 缓存条目的任何 key 目以实际缓存名称为前缀, 后跟两个冒号. 此行为可以更改为静态前缀和计算前缀.
The following example shows how to set a static prefix:
以下示例显示如何设置静态前缀:
- // static key prefix
- RedisCacheConfiguration.defaultCacheConfig().prefixKeysWith("( ͡° ͡°)");
- The following example shows how to set a computed prefix:
- // computed key prefix
- RedisCacheConfiguration.defaultCacheConfig().computePrefixWith(cacheName -> "¯\_(ツ)_/¯" + cacheName);
- The following table lists the default settings for RedisCacheManager:
下表列出了 RedisCacheManager 的默认设置:
Setting | Value |
Cache Writer | Non-locking |
Cache Configuration | RedisCacheConfiguration#defaultConfiguration |
Initial Caches | None |
Trasaction Aware | No |
The following table lists the default settings for RedisCacheConfiguration:
下表列出了 RedisCacheConfiguration 的默认设置:
Key Expiration | None |
Cache null | Yes |
Prefix Keys | Yes |
Default Prefix | The actual cache name |
Key Serializer | StringRedisSerializer |
Value Serializer | JdkSerializationRedisSerializer |
Conversion Service | DefaultFormattingConversionService with default cache key converters |
对于 Spring Boot 2.x, 这里我使用 RedisCacheConfiguration 简单配置一下缓存时间, 完成 RedisCacheManager 的配置, 代码如下:
- @Configuration
- @EnableCaching
- public class RedisConfig extends CachingConfigurerSupport {
- @Bean
- public CacheManager cacheManager(RedisConnectionFactory factory) {
- RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofSeconds(1));
- RedisCacheManager cacheManager = RedisCacheManager.builder(factory).cacheDefaults(config).build();
- return cacheManager;
- }
- }
4. Service 层
使用缓存的情况一般是这样的: 第一次访问的时候先从数据库读取数据, 然后将数据写入到缓存, 再次访问同一内容的时候就从缓存中读取, 如果缓存中没有则从数据库中读取.
添加缓存逻辑的时候, 从数据库中将内容读取出来之后, 先 set 入缓存, 然后再从缓存中添加读取行为, 如果缓存为空则从数据库中进行读取.
在这里仅创建一个简单的 RedisService, 来进行存取缓存数据.
- @Service
- public class RedisService {
- @Resource
- private RedisTemplate<String, Object> redisTemplate;
- public void set(String key, Object value) {
- // 更改在 Redis 里面查看 key 编码问题
- RedisSerializer redisSerializer = new StringRedisSerializer();
- redisTemplate.setKeySerializer(redisSerializer);
- ValueOperations<String, Object> vo = redisTemplate.opsForValue();
- vo.set(key, value);
- }
- public Object get(String key) {
- ValueOperations<String, Object> vo = redisTemplate.opsForValue();
- return vo.get(key);
- }
- }
5. Model 层
实体类没有修改, 和之前文章里面用的一样:
- @Entity
- @Table(name = "user")
- public class User implements Serializable {
- private static final long serialVersionUID = 1L;
- @Id
- @GeneratedValue
- private Long id;
- @Column(name = "username")
- private String userName;
- @Column(name = "password")
- private String passWord;
- public User() {
- super();
- }
- public User(String userName, String passWord) {
- super();
- this.userName = userName;
- this.passWord = passWord;
- }
- public User(Long id, String userName, String passWord) {
- super();
- this.id = id;
- this.userName = userName;
- this.passWord = passWord;
- }
- public Long getId() {
- return id;
- }
- public void setId(Long id) {
- this.id = id;
- }
- public String getUserName() {
- return userName;
- }
- public void setUserName(String userName) {
- this.userName = userName;
- }
- public String getPassWord() {
- return passWord;
- }
- public void setPassWord(String passWord) {
- this.passWord = passWord;
- }
- }
6. Controller 层
在 user.Controller 添加两个测试方法, 一个写入 Redis, 一个从 Redis 读取:
- @RestController
- @RequestMapping("user")
- public class UserController {
- @Autowired
- private UserRepository userRepository;
- @Autowired
- private RedisService redisService;
- @RequestMapping("/saveUser")
- public String saveUser(Long id, String userName, String passWord) {
- User user = new User(id, userName, passWord);
- redisService.set(id + "", user);
- return "success";
- }
- @RequestMapping("/getUserById")
- public User getUserById(Long id) {
- User res = (User) redisService.get(id + "");
- return res;
- }
- }
7. 测试
使用 Postman 进行测试, 访问, 添加了一个 User.
看看 Redis 数据库, 使用 get key 查看, 得到一个对象:
http://localhost:8080//user/getUserById?id=12 , 通过 id 获取 User.
这是过滤器和拦截器的日志信息, 可以看到没有进行 MySQL 数据库的操作, 直接从缓存中读取, 说明 Redis 配置生效了:
如果访问之前的接口, 是有操作数据库的:
总结
以上就是 Spring Boot 2.x 整合 Redis 的全过程, 和 Spring Boot 之前的版本在使用上有些细微的差别.
本文水平有限, 或多或少有欠妥之处, 还望各位大佬指正!
来源: https://www.cnblogs.com/sgh1023/p/10073354.html