Spring Boot 学习笔记:整合 Redis 实现缓存管理

1. 引言

在构建高并发、高性能的 Spring Boot 应用时,缓存是提高访问速度、降低数据库负载的重要手段之一。Redis 作为一个高性能的键值对存储数据库,非常适合作为缓存层。本文将详细介绍如何在 Spring Boot 中整合 Redis 实现缓存管理。

2. Redis 简介与安装

Redis 简介

Redis 是一个开源的、使用内存存储数据的键值对数据库,它可以支持多种类型的数据结构,如字符串(String)、哈希(Hash)、列表(List)、集合(Set)、有序集合(Sorted Set)等。由于其高性能和丰富的数据结构支持,Redis 常被用作缓存、消息队列等场景。

Redis 安装

  1. 下载 Redis:访问 Redis 官方网站(https://redis.io/download),下载最新版本的 Redis 源代码包或二进制包。
  2. 解压:将下载的包解压到指定目录。
  3. 编译(可选):如果下载的是源代码包,需要编译成可执行文件。通常二进制包已经编译好了,可以直接使用。
  4. 启动 Redis:进入 Redis 目录,运行 ./redis-server 命令启动 Redis 服务。
  5. 测试连接:运行 ./redis-cli 命令,输入一些 Redis 命令(如 set key valueget key)测试连接。

(注:以下图片展示了 Redis 的下载、解压和启动过程)

3. Spring Boot 整合 Redis

要在 Spring Boot 中整合 Redis,首先需要添加 Redis 相关的依赖。

添加依赖

在 pom.xml 文件中添加以下依赖:

<dependency>  
    <groupId>org.springframework.boot</groupId>  
    <artifactId>spring-boot-starter-data-redis</artifactId>  
</dependency>

配置 Redis

在 application.properties 或 application.yml 文件中配置 Redis 的连接信息:

spring.redis.host=localhost  
spring.redis.port=6379  
spring.redis.password=yourpassword  # 如果没有设置密码,可以省略此行

4. 配置 Redis 作为缓存管理器

Spring Boot 提供了 CacheManager 接口,Redis 可以作为该接口的一个实现。我们需要在配置类中配置 RedisCacheManager。

配置类

import org.springframework.cache.CacheManager;  
import org.springframework.cache.annotation.EnableCaching;  
import org.springframework.cache.interceptor.KeyGenerator;  
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.serializer.GenericJackson2JsonRedisSerializer;  
import org.springframework.data.redis.serializer.RedisSerializationContext.SerializationPair;  
  
import java.time.Duration;  
  
@Configuration  
@EnableCaching  
public class CacheConfig {  
  
    @Bean  
    public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {  
        RedisCacheConfiguration cacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()  
                .entryTtl(Duration.ofHours(1))  // 设置缓存过期时间  
                .serializeValuesWith(SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()));  // 设置值序列化器  
  
        return RedisCacheManager.builder(redisConnectionFactory)  
                .cacheDefaults(cacheConfiguration)  
                .build();  
    }  
  
    // 自定义 Key 生成器(可选)  
    @Bean("customKeyGenerator")  
    public KeyGenerator customKeyGenerator() {  
        return (target, method, params) -> {  
            StringBuilder sb = new StringBuilder();  
            sb.append(target.getClass().getSimpleName());  
            sb.append(".");  
            sb.append(method.getName());  
            sb.append("(");  
            for (Object obj : params) {  
                sb.append(obj.toString());  
            }  
            sb.append(")");  
            return sb.toString();  
        };  
    }  
}

5. 使用 RedisTemplate 操作 Redis

虽然我们可以直接使用 Spring Cache 注解来操作缓存,但有时需要直接操作 Redis。这时可以使用 RedisTemplate

配置 RedisTemplate

import org.springframework.context.annotation.Bean;  
import org.springframework.context.annotation.Configuration;  
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.StringRedisSerializer;  
  
@Configuration  
public class RedisConfig {  
  
    @Bean  
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {  
        RedisTemplate<String, Object> template = new RedisTemplate<>();  
        template.setConnectionFactory(redisConnectionFactory);  
  
        // 设置 key 序列化器  
        template.setKeySerializer(new StringRedisSerializer());  
        // 设置 value 序列化器  
        template.setValueSerializer(new GenericJackson2JsonRedisSerializer());  
  
        template.afterPropertiesSet();  
        return template;  
    }  
}

使用 RedisTemplate

import org.springframework.beans.factory.annotation.Autowired;  
import org.springframework.data.redis.core.RedisTemplate;  
import org.springframework.stereotype.Service;  
  
@Service  
public class CacheService {  
  
    @Autowired  
    private RedisTemplate<String, Object> redisTemplate;  
  
    public void setCache(String key, Object value) {  
        redisTemplate.opsForValue().set(key, value);  
    }  
  
    public Object getCache(String key) {  
        return redisTemplate.opsForValue().get(key);  
    }  
  
    public void deleteCache(String key) {  
        redisTemplate.delete(key);  
    }  
}

6. 自定义缓存注解

有时我们需要更灵活地控制缓存行为,可以自定义缓存注解。

自定义注解

import java.lang.annotation.*;  
  
@Target({ElementType.METHOD, ElementType.TYPE})  
@Retention(RetentionPolicy.RUNTIME)  
@Documented  
public @interface MyCacheable {  
    String value();  
    String key() default "";  
    long ttl() default 3600;  // 默认缓存过期时间(秒)  
}

自定义缓存拦截器

import org.aspectj.lang.ProceedingJoinPoint;  
import org.aspectj.lang.annotation.Around;  
import org.aspectj.lang.annotation.Aspect;  
import org.springframework.beans.factory.annotation.Autowired;  
import org.springframework.cache.CacheManager;  
import org.springframework.cache.interceptor.SimpleKeyGenerator;  
import org.springframework.data.redis.core.RedisTemplate;  
import org.springframework.stereotype.Component;  
  
import java.util.concurrent.TimeUnit;  
  
@Aspect  
@Component  
public class MyCacheAspect {  
  
    @Autowired  
    private RedisTemplate<String, Object> redisTemplate;  
  
    @Autowired  
    private CacheManager cacheManager;  
  
    @Around("@annotation(myCacheable)")  
    public Object around(ProceedingJoinPoint joinPoint, MyCacheable myCacheable) throws Throwable {  
        String cacheName = myCacheable.value();  
        String key = myCacheable.key().isEmpty() ? new SimpleKeyGenerator().generate(joinPoint.getArgs(), joinPoint.getTarget().getClass()) : myCacheable.key();  
        Object value = redisTemplate.opsForValue().get(key);  
  
        if (value != null) {  
            return value;  
        }  
  
        Object result = joinPoint.proceed();  
        redisTemplate.opsForValue().set(key, result, myCacheable.ttl(), TimeUnit.SECONDS);  
  
        // 可选:将缓存同步到 CacheManager(如果使用了 Spring Cache)  
        // cacheManager.getCache(cacheName).put(key, result);  
  
        return result;  
    }  
}

7. 遇到的问题与解决过程

问题 1:Redis 连接失败

  • 现象:启动应用时,报错 Connection refused
  • 原因:Redis 服务未启动或配置信息错误。
  • 解决:确保 Redis 服务已启动,并检查 application.properties 中的 Redis 配置信息。

问题 2:- - - - - - 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值