Spring Boot集成Redis实现缓存

前言

Spring Boot 集成 Redis 实现数据缓存,只需要添加一些注解,就无侵入地使用缓存了,无需额外的代码。

步骤

Spring Boot 集成 Redis 实现缓存主要分为以下三步:

1)加入 Redis 依赖;

2)加入 Redis 配置;

3)添加 Redis 缓存相关注解。

 

一、加入依赖

首先我们创建一个项目,并在项目中加入 Redis 依赖,项目依赖如下所示(由于使用 Redis 连接池,需额外引入 commons-pool2):

<dependency>     
    <groupId>org.springframework.boot</groupId>     
    <artifactId>spring-boot-starter-web</artifactId> 
</dependency> 
<dependency>     
    <groupId>org.springframework.boot</groupId>     
    <artifactId>spring-boot-starter-data-redis</artifactId> 
</dependency> 
<dependency>     
    <groupId>org.apache.commons</groupId>     
    <artifactId>commons-pool2</artifactId> 
</dependency>

在 spring-boot-starter-data-redis 1.X 版本中默认使用 Jedis 客户端,而在 2.X 版本默认使用 Lettuce 客户端。如果更习惯使用 Jedis,可从 spring-boot-starter-data-redis 中排除 Lettuce 并引入 Jedis 依赖。

 

二、加入配置

①在配置文件 application.properties 中配置 Redis 的相关参数,具体内容如下:

#Redis 数据库索引(0~15,默认为 0) 
spring.redis.database=0 
#修改为自己的redis实例所在的ip地址 
spring.redis.host=127.0.0.1 
#Redis 密码,如果没有就默认不配置此参数 
spring.redis.password= spring.redis.port=6379 
#Redis 连接的超时时间  https://blog.csdn.net/haveqing/article/details/86524450 spring.redis.timeout=1000ms #连接池最大连接数(使用负值表示没有限制) spring.redis.lettuce.pool.max-active=20 #连接池最大阻塞等待时间(使用负值表示没有限制) spring.redis.lettuce.pool.max-wait=-1ms #连接池中的最大空闲连接 spring.redis.lettuce.pool.max-idle=10 #连接池中的最小空闲连接 
spring.redis.lettuce.pool.min-idle=0

②接下来在 config 包下创建一个 Redis 配置类 RedisConfig,在配置类上加入注解 @Configuration,注入一个 CacheManager 来配置一些相关信息,代码如下:

@Configuration

public class RedisConfig {

    /**

    * 首先通过 RedisCacheConfiguration 生成默认配置,然后对缓存进行自定义化配置,比如过期时间、缓存前缀、key/value 序列化方法等,然后构建出一个 RedisCacheManager
    * @param factory

    * @return

    */

    @Bean

    public CacheManager cacheManager(RedisConnectionFactory factory) {

        RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()

                .entryTtl(Duration.ofMinutes(30))

                //测试了一下,如果此处配置了key的前缀,则@CacheConfig(cacheNames = "user")无效,redis中的key前缀为cache:user:  可参见  https://blog.csdn.net/star_apple/article/details/105025008

                .prefixKeysWith("cache:user:")

                .disableCachingNullValues()

                .serializeKeysWith(keySerializationPair())

                .serializeValuesWith(valueSerializationPair());

        Map<String, RedisCacheConfiguration> cacheConfig = new HashMap<>();

        return RedisCacheManager.builder(factory) .withInitialCacheConfigurations(cacheConfig) .cacheDefaults(redisCacheConfiguration) .build();

    }

    //为 key 配置序列化

    private RedisSerializationContext.SerializationPair<String> keySerializationPair() {

        return RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer());

    }

    //为 value 配置序列化

    private RedisSerializationContext.SerializationPair<Object> valueSerializationPair() {

        return RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer());

    }

}

首先通过 RedisCacheConfiguration 生成默认配置,然后对缓存进行自定义化配置,比如过期时间、缓存前缀、key/value 序列化方法等,然后构建出一个 RedisCacheManager,其中通过 keySerializationPair 方法为 key 配置序列化,valueSerializationPair 为 value 配置序列化。

③启动类添加开启缓存注解

@SpringBootApplication 
@EnableCaching 
public class RedisCacheApplication{     
    private static final Logger logger = LoggerFactory.getLogger(RedisCacheApplication.class);  

 
    public static void main(String[] args) {               
       SpringApplication.run(RedisCacheApplication.class, args);         
       logger.info("项目运行");   
    } 
}

@EnableCaching 表明开启缓存,Spring Boot 会自动配置 Redis 缓存的 CacheManager。

 

三、添加 Redis 缓存相关注解

①定义用户实体类

在 entity 包下创建一个用户实体类:

public class User {     
    private Long id;     
    private String name;     
    private String password;  
   
    public Long getId() {         
        return id;     
    }    
 
    public void setId(Long id) {         
        this.id = id;     
    }  
   
    public String getName() {         
        return name;     
    }    
 
    public void setName(String name) {         
        this.name = name;     
    }  
   
    public String getPassword() {         
        return password;     
    }  
   
    public void setPassword(String password) {         
        this.password = password;     
    } 
}

②在服务中使用 SpringCache 注解

在 service 包下定义用户接口,分别包含添加用户、查询用户、更新用户以及删除用户四个接口,具体代码如下:

public interface UserService {    
 
    void addUser(User user);     

    User getUserById(Long id);     

    User updateUser(User user);    
 
    void deleteById(Long id); 
}

然后编写实现类,为了方便演示,在这里使用 Map<Long, User> userMap,没有真正连接数据库,下面使用到的注解有 @CacheConfig、@Cacheable、@CachePut 以及 @CacheEvict,具体代码如下:

@Service 
@CacheConfig(cacheNames = "user") 
public class UserServiceImpl implements UserService {     
    //此处使用HashMap来存储数据,表示数据库交互操作     
    Map<Long, User> userMap = Collections.synchronizedMap(new HashMap<>());  

   
    @Override     
     public void addUser(User user) {         
        userMap.put(user.getId(), user);     
    }   
 
    @Override     
    @Cacheable(key = "#id")     
    public User getUserById(Long id) {         
        try {             
            Thread.sleep(3000);         
        } catch (InterruptedException e) {             
            e.printStackTrace();         
        }         
        if (!userMap.containsKey(id)) {             
            return null;         
        }         
        return userMap.get(id);     
    }     

    @Override     
    @CachePut(key = "#user.id")     
    public User updateUser(User user) {         
        if (!userMap.containsKey(user.getId())) {             
            throw new RuntimeException("不存在该用户");         
        }         
        User newUser = userMap.get(user.getId());                         
        newUser.setPassword(user.getPassword());         
        userMap.put(newUser.getId(), newUser);         
        return newUser;     
    }     

    @Override     
    @CacheEvict(key = "#id")     
    public void deleteById(Long id) {         
        userMap.remove(id);     
    } 
}

简单说明一下这几个注解:

@CacheConfig 类级别的缓存注解,允许共享缓存名称。

@Cacheable  触发缓存的入口。 一般用于查询操作,根据 key 查询缓存。如果 key 不存在,就去查询数据库,并把查询结果更新到缓存中。如果 key 存在,直接查询缓存中的数据。

@CacheEvict 触发移除缓存。根据 key 删除缓存中的数据。

@CacahePut 触发更新缓存。一般用于更新和插入操作,每次都会请求 db,通过 key 去 Redis 中进行操作。如果 key 存在,更新内容。如果 key 不存在,插入内容。

③最后,在 controller 包下创建一个 UserController 类,提供用户 API 接口(未使用数据库),代码如下:

@RestController

@RequestMapping("/user")

public class UserController {

    @Autowired

    private UserService userService;

    @GetMapping("/{id}")

    public ResponseEntity<User> getUser(@PathVariable Long id) {

        return ResponseEntity.status(HttpStatus.CREATED).body(userService.getUserById(id));

    }

    @PostMapping

    public ResponseEntity<String> createUser(@RequestBody User user) {

        userService.addUser(user);

        return ResponseEntity.status(HttpStatus.CREATED).body("SUCCESS");

    }

    @PutMapping

    public ResponseEntity<User> updateUser(@RequestBody User user) {

        return ResponseEntity.status(HttpStatus.CREATED).body(userService.updateUser(user));

    }

    @DeleteMapping("/{id}")

    public ResponseEntity<String> deleteUser(@PathVariable Long id) {

        userService.deleteById(id);

        return ResponseEntity.status(HttpStatus.CREATED).body("SUCCESS");

    }

}

 

测试

①启动项目,先调用添加用户接口,http://localhost:8080/user  来添加以下数据:

{

    "id": 1,

    "name": "pino",

    "password": "1234"

}

 

 

 

②调用查询数据接口:http://localhost:8080/user/1   ,可以看到第一次调用时,耗时超过3s。

 

接着我们进行第二次调用,接口很快返回,说明缓存生效了。

③调用更新接口, http://localhost:8080/user

 

再次调用查询接口,返回最新数据,返回也很快。

 

 

总结

在Spring Boot框架中集成 Redis 实现数据缓存并不复杂,Spring 提供了缓存注解,使用这些注解可以有效简化编程过程。

 

遇到的问题:

springboot2 配置redis报错 redis timeout Value '1000' is not a valid duration解决办法:

解决方法:https://blog.csdn.net/haveqing/article/details/86524450

 

@CacheConfig(cacheNames = "user")  不生效

原因:https://blog.csdn.net/star_apple/article/details/105025008

 

 

参考链接:https://www.jianshu.com/p/e2d9cd3a5a8e

                  https://www.tianheyu.top/archives/springboot-redis-cache

 

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值