在SpringBoot 项目中同时使用 Redis 基本用法和 Spring Cache 注解用法

185 阅读4分钟

SpringBoot 项目中同时使用 Redis 基本用法和 Spring Cache 注解用法

在 SpringBoot 项目中同时配置 Redis 基本用法和 Spring Cache 注解用法的步骤如下:

1. 添加依赖

首先在 pom.xml 中添加必要的依赖:

<dependencies>
    <!-- Spring Boot Starter for Redis -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>
    
    <!-- Spring Boot Starter for Cache -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-cache</artifactId>
    </dependency>
    
    <!-- 其他你项目需要的依赖 -->
</dependencies>

2. 配置 application.yml

application.yml 中配置 Redis 连接和缓存相关设置:

spring:
  redis:
    host: localhost     # Redis服务器地址
    port: 6379          # Redis服务器端口
    password:           # Redis密码,如果没有则留空
    database: 0         # 使用的数据库索引(0-15)
    timeout: 5000       # 连接超时时间(毫秒)
    lettuce:
      pool:
        max-active: 8   # 连接池最大连接数
        max-idle: 8      # 连接池最大空闲连接数
        min-idle: 0      # 连接池最小空闲连接数
        max-wait: -1ms   # 连接池最大阻塞等待时间(负值表示无限制)
  
  cache:
    type: redis         # 使用Redis作为缓存
    redis:
      time-to-live: 600000  # 缓存过期时间(毫秒),10分钟
      key-prefix: "cache:"  # 缓存key前缀
      use-key-prefix: true  # 是否使用key前缀
      cache-null-values: false  # 是否缓存null值

3. 配置 RedisTemplate 和 CacheManager

创建一个配置类来配置 RedisTemplate 和 CacheManager:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.StringRedisSerializer;

import java.time.Duration;

@Configuration
public class RedisConfig {

    /**
     * 配置RedisTemplate
     * 设置序列化方式,避免存储乱码
     */
    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(redisConnectionFactory);
        
        // 使用StringRedisSerializer来序列化和反序列化redis的key值
        template.setKeySerializer(new StringRedisSerializer());
        template.setHashKeySerializer(new StringRedisSerializer());
        
        // 使用GenericJackson2JsonRedisSerializer来序列化和反序列化redis的value值
        template.setValueSerializer(new GenericJackson2JsonRedisSerializer());
        template.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());
        
        template.afterPropertiesSet();
        return template;
    }

    /**
     * 配置RedisCacheManager
     * 设置缓存过期时间和序列化方式
     */
    @Bean
    public RedisCacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
                .entryTtl(Duration.ofMinutes(10))  // 设置默认过期时间10分钟
                .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()))
                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()))
                .disableCachingNullValues();  // 不缓存null值

        return RedisCacheManager.builder(redisConnectionFactory)
                .cacheDefaults(config)
                .transactionAware()
                .build();
    }
}

4. 启用缓存功能

在主应用类上添加 @EnableCaching 注解:

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;

@SpringBootApplication
@EnableCaching
public class YourApplication {
    public static void main(String[] args) {
        SpringApplication.run(YourApplication.class, args);
    }
}

5. 使用 Redis 基本操作

创建一个服务类来演示 Redis 基本操作:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

@Service
public class RedisBasicService {

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    /**
     * 设置键值对
     */
    public void set(String key, Object value) {
        redisTemplate.opsForValue().set(key, value);
    }

    /**
     * 设置键值对并设置过期时间
     */
    public void setWithExpire(String key, Object value, long timeout, TimeUnit unit) {
        redisTemplate.opsForValue().set(key, value, timeout, unit);
    }

    /**
     * 获取值
     */
    public Object get(String key) {
        return redisTemplate.opsForValue().get(key);
    }

    /**
     * 删除键
     */
    public Boolean delete(String key) {
        return redisTemplate.delete(key);
    }

    /**
     * 检查键是否存在
     */
    public Boolean hasKey(String key) {
        return redisTemplate.hasKey(key);
    }

    /**
     * 设置过期时间
     */
    public Boolean expire(String key, long timeout, TimeUnit unit) {
        return redisTemplate.expire(key, timeout, unit);
    }
}

6. 使用 Spring Cache 注解

创建一个服务类来演示 Spring Cache 注解用法:

import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

@Service
@CacheConfig(cacheNames = "userCache") // 指定该类使用的缓存名称
public class UserService {

    /**
     * 根据ID查询用户
     * 如果缓存中有,则直接返回缓存数据
     * 如果没有,则执行方法并将结果存入缓存
     */
    @Cacheable(key = "#id")
    public User getUserById(Long id) {
        // 模拟从数据库查询
        System.out.println("查询数据库获取用户: " + id);
        return new User(id, "用户" + id, "user" + id + "@example.com");
    }

    /**
     * 更新用户信息
     * 同时更新缓存
     */
    @CachePut(key = "#user.id")
    public User updateUser(User user) {
        // 模拟更新数据库
        System.out.println("更新用户信息: " + user.getId());
        return user;
    }

    /**
     * 删除用户
     * 同时从缓存中删除
     */
    @CacheEvict(key = "#id")
    public void deleteUser(Long id) {
        // 模拟从数据库删除
        System.out.println("删除用户: " + id);
    }

    /**
     * 清除所有用户缓存
     */
    @CacheEvict(allEntries = true)
    public void clearAllCache() {
        System.out.println("清除所有用户缓存");
    }
}

7. 创建测试控制器

创建一个控制器来测试两种用法:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/test")
public class TestController {

    @Autowired
    private RedisBasicService redisBasicService;
    
    @Autowired
    private UserService userService;

    // 测试Redis基本操作
    @GetMapping("/redis/{key}")
    public Object testRedis(@PathVariable String key) {
        return redisBasicService.get(key);
    }

    @PostMapping("/redis/{key}")
    public String testRedisSet(@PathVariable String key, @RequestParam String value) {
        redisBasicService.set(key, value);
        return "OK";
    }

    // 测试Spring Cache注解
    @GetMapping("/user/{id}")
    public User testCache(@PathVariable Long id) {
        return userService.getUserById(id);
    }

    @PutMapping("/user")
    public User testCacheUpdate(@RequestBody User user) {
        return userService.updateUser(user);
    }

    @DeleteMapping("/user/{id}")
    public String testCacheDelete(@PathVariable Long id) {
        userService.deleteUser(id);
        return "Deleted";
    }
}

8. 创建User类(示例)

import java.io.Serializable;

public class User implements Serializable {
    private Long id;
    private String name;
    private String email;

    // 构造方法、getter和setter
    public User(Long id, String name, String email) {
        this.id = id;
        this.name = name;
        this.email = email;
    }

    // 省略getter和setter...
}

使用说明

  1. Redis基本操作

    • 通过 RedisBasicService 可以直接操作Redis
    • 提供了基本的set/get/delete等操作
  2. Spring Cache注解

    • @Cacheable: 先查缓存,没有再执行方法并缓存结果
    • @CachePut: 总是执行方法,并更新缓存
    • @CacheEvict: 删除缓存
    • @CacheConfig: 类级别的缓存配置
  3. 缓存名称和key

    • 缓存名称在 @CacheConfig 中配置为 "userCache"
    • key使用方法的参数生成,如 #id 表示使用id参数作为key
  4. 序列化

    • 配置中使用了JSON序列化,存储的值是可读的JSON格式

注意事项

  1. 确保Redis服务器已启动且连接配置正确
  2. 缓存的对象需要实现Serializable接口
  3. 根据实际需求调整缓存过期时间
  4. 生产环境建议配置Redis密码和适当的连接池参数
  5. 对于复杂的缓存需求,可以自定义KeyGenerator和CacheManager

这样配置后,就可以在项目中同时使用Redis的基本操作和Spring Cache的注解简化缓存操作了。