Redis数据预热实现
缓存预热是指在 Spring Boot 项目启动时,预先将数据加载到缓存系统(如 Redis)中的一种机制。它可以通过监听 ContextRefreshedEvent 或 ApplicationReadyEvent 启动事件,或使用 @PostConstruct 注解,或实现 CommandLineRunner 接口、ApplicationRunner 接口,和 InitializingBean 接口的方式来完成
1. CommandLineRunner接口
CommandLineRunner
是 Spring Boot 提供的一个接口,用于在应用程序启动后立即执行一些特定的代码。实现这个接口的类会在 Spring 容器启动完成并且所有 Bean 都已初始化后执行run
方法
实现CommandLineRunner接口的类需要被Spring容器扫描到,可以使用@Component注解或其他方式将其注册为Spring Bean
先后顺序示例 可以通过@Order()来设置Runner的先后顺序,在上面例子的基础上增加
2. Redis数据预热实现
@Slf4j
@Component
@RequiredArgsConstructor
public class MyCommandLineRunner implements CommandLineRunner {
private final StringRedisTemplate stringRedisTemplate;
@Override
public void run(String... args) throws Exception {
// 此处模拟需要预热的数据,可以从其他处获取或者读取数据库
List<String> dataList = fetchDataForCache();
log.info("开始进行 Redis 数据预热----------------");
// 预热 Redis 缓存
for (int i = 0; i < dataList.size(); i++) {
stringRedisTemplate.opsForValue().set("key" + i, dataList.get(i));
}
log.info("Redis 数据预热完毕----------------");
}
private List<String> fetchDataForCache() {
// 实现获取数据的方法
// 这里只是示例,返回一个简单的列表
return Arrays.asList("data1", "data2", "data3");
}
}
3. CommandLineRunner的其余用法
4. 其他方法实现数据预热
在 Spring Boot 启动之后,可以通过以下手段实现缓存预热:
- 使用启动监听事件实现缓存预热。
- 使用 @PostConstruct 注解实现缓存预热。
- 使用 CommandLineRunner 或 ApplicationRunner 实现缓存预热。
- 通过实现 InitializingBean 接口,并重写 afterPropertiesSet 方法实现缓存预热
4.1 启动监听事件
可以使用 ApplicationListener 监听 ContextRefreshedEvent 或 ApplicationReadyEvent 等应用上下文初始化完成事件,在这些事件触发后执行数据加载到缓存的操作,具体实现如下:
@Component
public class CacheWarmer implements ApplicationListener<ContextRefreshedEvent> {
@Override
public void onApplicationEvent(ContextRefreshedEvent event) {
// 执行缓存预热业务...
cacheManager.put("key", dataList);
}
}
或监听 ApplicationReadyEvent 事件,如下代码所示:
@Component
public class CacheWarmer implements ApplicationListener<ApplicationReadyEvent> {
@Override
public void onApplicationEvent(ApplicationReadyEvent event) {
// 执行缓存预热业务...
cacheManager.put("key", dataList);
}
}
4.2 @PostConstruct 注解
在需要进行缓存预热的类上添加 @Component 注解,并在其方法中添加 @PostConstruct 注解和缓存预热的业务逻辑,具体实现代码如下:
@Component
public class CachePreloader {
@Autowired
private YourCacheManager cacheManager;
@PostConstruct
public void preloadCache() {
// 执行缓存预热业务...
cacheManager.put("key", dataList);
}
}
4.3 CommandLineRunner或ApplicationRunner
CommandLineRunner 和 ApplicationRunner 都是 Spring Boot 应用程序启动后要执行的接口,它们都允许我们在应用启动后执行一些自定义的初始化逻辑,例如缓存预热。
ApplicationRunner 实现示例如下:
@Component
public class MyApplicationRunner implements ApplicationRunner {
@Override
public void run(ApplicationArguments args) throws Exception {
// 执行缓存预热业务...
// 存入redis
}
}
CommandLineRunner 和 ApplicationRunner 区别如下:
- 方法签名不同
- CommandLineRunner 接口有一个 run(String... args) 方法,它接收命令行参数作为可变长度字符串数组
- ApplicationRunner 接口则提供了一个 run(ApplicationArguments args) 方法,它接收一个 ApplicationArguments 对象作为参数,这个对象提供了对传入的所有命令行参数(包括选项和非选项参数)的访问
- 参数解析方式不同
- CommandLineRunner 接口更简单直接,适合处理简单的命令行参数
- ApplicationRunner 接口提供了一种更强大的参数解析能力,可以通过 ApplicationArguments 获取详细的参数信息,比如获取选项参数及其值、非选项参数列表以及查询是否存在特定参数等
- 使用场景不同
- 当只需要处理一组简单的命令行参数时,可以使用 CommandLineRunner
- 对于需要精细控制和解析命令行参数的复杂场景,推荐使用 ApplicationRunner
4.4 实现InitializingBean接口
实现 InitializingBean 接口并重写 afterPropertiesSet 方法,可以在 Spring Bean 初始化完成后执行缓存预热,具体实现代码如下:
@Component
public class CachePreloader implements InitializingBean {
@Autowired
private YourCacheManager cacheManager;
@Override
public void afterPropertiesSet() throws Exception {
// 执行缓存预热业务...
// 存入redis
}
}
5. 参考补充
5.1 免费的Redis服务
https://redislabs.com/redis-cloud
对于临时测试Demo足够了
5.2 spring-boot-starter-data-redis和spring-data-redis依赖
spring-boot-starter-data-redis
- 作用:
spring-boot-starter-data-redis
是一个 Spring Boot 启动器(starter),它用于简化 Spring Boot 项目中 Redis 的集成和配置 - 依赖性:它不仅包括
spring-data-redis
,还包括与 Redis 相关的所有必要依赖(例如连接池、Lettuce 或 Jedis 等 Redis 客户端库) - 自动配置:当你在 Spring Boot 项目中引入
spring-boot-starter-data-redis
依赖时,Spring Boot 会自动配置 Redis 相关的 Bean(例如RedisTemplate
、连接工厂等),并且可以通过简单的配置文件来定制化设置 - 推荐使用场景:如果你正在使用 Spring Boot,并希望利用 Spring Boot 的自动配置功能来简化 Redis 的配置和使用,那么应该使用
spring-boot-starter-data-redis
//直接使用
private final StringRedisTemplate stringRedisTemplate;
spring-data-redis
- 作用:
spring-data-redis
是 Spring Data 项目的一部分,它提供了对 Redis 的低级别访问功能和操作支持。它不包含自动配置,需要手动配置 Redis 相关的 Bean - 依赖性:
spring-data-redis
只提供核心的 Redis 操作功能,它不会包含具体的 Redis 客户端实现。你需要手动添加所需的客户端库(如 Lettuce 或 Jedis) - 灵活性:它提供了更多自定义配置的灵活性,适用于那些需要手动配置或不使用 Spring Boot 的项目
- 推荐使用场景:如果你不使用 Spring Boot,或者需要对 Redis 配置进行更细粒度的控制,那么应该使用
spring-data-redis