Spring Boot携手Redis缓存实战:精通注解、配置与策略,加速你的应用至极致!

11 篇文章 0 订阅
9 篇文章 2 订阅


前言

    在Spring Boot项目中引入Redis作为缓存机制,并使用@Cacheable注解来简化缓存的操作,是一个常见且高效的实践。下面,我将概述如何在Spring Boot项目中引入Redis作为缓存,并展示如何使用@Cacheable注解。

基础篇参照:Spring Boot x Redis:零基础入门,性能飙升的实战秘籍!


一、Spring Boot 集成 Redis

1.添加依赖

    首先,你需要在你的pom.xml(如果你使用的是Maven)或build.gradle(如果你使用的是Gradle)文件中添加Spring Boot的Redis Starter依赖。

Maven:

<dependency>  
    <groupId>org.springframework.boot</groupId>  
    <artifactId>spring-boot-starter-data-redis</artifactId>  
</dependency><!-- 如果你需要使用Spring Cache的抽象层,则还需要添加 -->  
<dependency>  
    <groupId>org.springframework.boot</groupId>  
    <artifactId>spring-boot-starter-cache</artifactId>  
</dependency>

2.配置Redis

    在application.yml文件中配置Redis服务器的连接信息。

application.yml 示例:

spring:  
  redis:  
    host: localhost  
    port: 6379  
    # password: yourpassword  
    jedis:  
      pool:  
        max-active: 8  
        # 其他连接池配置...

3.开启缓存支持

    在你的Spring Boot主类或配置类上添加@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);  
    }  
}

    @EnableCaching 注解开启了缓存支持,RedisCacheManager 用来配置 Redis 缓存管理器。

二、Spring Cache 缓存管理器

    Spring Cache 缓存管理器(CacheManager)在Spring框架中扮演着重要的角色,它负责管理和维护各种缓存(Cache)组件。
    CacheManager 是 Spring Cache 提供的缓存管理的抽象接口,它屏蔽了不同缓存实现之间的差异,提供了统一的访问接口。
    CacheManager 主要负责缓存的创建、配置、获取和销毁等操作。通过它,开发者可以轻松地切换不同的缓存实现,如 Redis、EhCache、Caffeine 等,而无需修改业务代码。

1.创建 Spring Cache 缓存管理器

    要使用缓存,我们需要配置一个缓存管理器。

@Configuration
@EnableCaching
public class CacheConfig {
    @Bean
    public RedisCacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
        RedisCacheConfiguration cacheConfig = RedisCacheConfiguration.defaultCacheConfig()
                .entryTtl(Duration.ofHours(1)); // 设置缓存默认过期时间为1小时
        return RedisCacheManager.builder(redisConnectionFactory)
                .cacheDefaults(cacheConfig)
                .build();
    }
}

2.配置缓存策略

    我们可以配置不同的缓存策略,比如过期时间。

@Bean
public RedisCacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
    RedisCacheConfiguration defaultConfig = RedisCacheConfiguration.defaultCacheConfig()
            .entryTtl(Duration.ofMinutes(30)); // 默认过期时间30分钟RedisCacheConfiguration usersCacheConfig = RedisCacheConfiguration.defaultCacheConfig()
            .entryTtl(Duration.ofHours(6)); // users缓存过期时间6小时Map<String, RedisCacheConfiguration> cacheConfigurations = new HashMap<>();
    cacheConfigurations.put("users", usersCacheConfig);return RedisCacheManager.builder(redisConnectionFactory)
            .cacheDefaults(defaultConfig)
            .withInitialCacheConfigurations(cacheConfigurations)
            .build();
}

    这个配置定义了默认缓存过期时间为30分钟,而 users 缓存过期时间为6小时。

3.自定义缓存实现

    你也可以自定义缓存实现,以适应特殊需求。

@Bean
public RedisCacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
    RedisCacheConfiguration defaultConfig = RedisCacheConfiguration.defaultCacheConfig()
            .entryTtl(Duration.ofMinutes(30))
            .disableCachingNullValues(); // 不缓存null值return RedisCacheManager.builder(redisConnectionFactory)
            .cacheDefaults(defaultConfig)
            .build();
}

    缓存策略被设置为不缓存 null 值。

三、缓存过期策略

1.基于时间的过期

    在 Redis 中,你可以为缓存设置一个 TTL(Time-To-Live)。

@Bean
public RedisCacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
    RedisCacheConfiguration cacheConfig = RedisCacheConfiguration.defaultCacheConfig()
            .entryTtl(Duration.ofMinutes(10)); // 过期时间为10分钟
    return RedisCacheManager.builder(redisConnectionFactory)
            .cacheDefaults(cacheConfig)
            .build();
}

2.基于访问次数的过期

    可以通过编写自定义逻辑来实现基于访问次数的缓存过期策略。

@Component
public class CustomCacheManager {
    private final Map<String, Integer> accessCountMap = new ConcurrentHashMap<>();public void put(String key, Object value) {
        accessCountMap.put(key, 0);
        // 这里将对象放入缓存,比如 Redis
    }public Object get(String key) {
        Integer count = accessCountMap.get(key);
        if (count != null) {
            accessCountMap.put(key, count + 1);
            if (count + 1 > MAX_ACCESS_COUNT) {
                evict(key);
                return null;
            }
        }
        // 从缓存中取对象
        return null; // 返回缓存对象
    }public void evict(String key) {
        accessCountMap.remove(key);
        // 从缓存中删除对象
    }
}

3.基于空闲时间的过期

    设置缓存项在一定时间内未被访问时过期。

@Bean
public RedisCacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
    RedisCacheConfiguration cacheConfig = RedisCacheConfiguration.defaultCacheConfig()
            .entryTtl(Duration.ofMinutes(5)) // 过期时间为5分钟
            .disableCachingNullValues(); // 不缓存null值return RedisCacheManager.builder(redisConnectionFactory)
            .cacheDefaults(cacheConfig)
            .build();
}

4.缓存击穿

    缓存击穿是指缓存中某个热点数据失效,导致大量请求同时访问数据库,给数据库造成巨大压力,甚至导致系统崩溃,就像雪崩一样,来势汹汹。

解决方案:

  • 使用互斥锁:当缓存数据失效时,只有一个线程可以访问数据库,其他线程等待,就像排队一样,井然有序!
  • 设置热点数据永不过期:对于一些访问频率非常高的数据,可以设置永不过期,就像明星一样,永远闪耀!

5.缓存穿透

    缓存穿透是指恶意用户不断请求缓存中不存在的数据,导致所有请求都落到数据库上,给数据库造成巨大压力,就像敌人的炮弹一样,精准打击。

解决方案:

  • 缓存空值:对于查询数据库返回为空的结果,也将其缓存起来,并设置较短的过期时间,就像设置陷阱一样,迷惑敌人!
  • 使用布隆过滤器:布隆过滤器可以快速判断一个元素是否存在于一个集合中,可以用来拦截恶意请求,就像设置一道防护墙一样,保护数据库!

四、基于注解的缓存

1.@Cacheable 注解

     @Cacheable 是一个神奇的注解,它会帮你自动缓存方法的返回结果。下次调用这个方法时,如果参数一样,Spring 就不会再执行这个方法,而是直接从缓存里取值。

@Service
public class UserService {
    @Cacheable(value = "users", key = "#userId")
    public User getUserById(Long userId) {
        // 假装我们从数据库里取数据
        return userRepository.findById(userId).orElse(null);
    }
}

    getUserById 方法会把结果缓存到 Redis 里的 users 键下,键名是 userId 的值。

2.@CacheEvict 注解

    @CacheEvict 用来清除缓存。当你更新或删除数据时,缓存也需要同步更新。

@Service
public class UserService {
    @CacheEvict(value = "users", key = "#userId")
    public void deleteUser(Long userId) {
        // 删除了数据库里的数据,同时删除了缓存中数据
        userRepository.deleteById(userId);
    }
}

    调用 deleteUser 方法时,会自动清除 Redis 中 users 键下对应 userId 的缓存。

3.@CachePut 注解

    @CachePut是用来更新缓存的,它不会影响方法的实际调用。

@Service
public class UserService {
    @CachePut(value = "users", key = "#user.id")
    public User updateUser(User user) {
        // 假装我们更新了数据库里的数据
        return userRepository.save(user);
    }
}

    每次调用 updateUser 方法时,都会把返回的 User 对象更新到缓存里。

    :所有Spring Cache注解与数据库事务一样,采用的是Spring AOP实现,所以一定要注意,避免使用不当造成注解失效。


总结

    Spring Cache 缓存管理器是 Spring 框架中用于管理和维护缓存组件的重要组件。它提供了丰富的缓存实现和配置选项,使得开发者可以轻松地实现缓存功能,从而提高应用的性能和响应速度。

“笑对人生,智慧同行!博客新文出炉,微信订阅号更新更实时,等你笑纳~”
在这里插入图片描述

  • 8
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

拥有必珍惜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值