SpringBoot如何实现缓存预热?【监听ioc或者bean更新事件、PostConstruct、初始化事件中添加、】

时间:2024-03-26 08:23:51

转自 www.javacn.site

SpringBoot如何实现缓存预热?

  • 实现方案概述
    • 1.使用启动监听事件实现缓存预热
        • 可以使用 Applicationlistener 监听 ContextRefreshedEvent 或 ApplicationReadyEvent 等应用上下文初始化完成事件,在这些事件触发后执行数据加载到缓存的操作,具体实现如下:
        • ContextRefreshedEvent Vs ApplicationReadyEvent
    • 2.使用 @PostConstruct 注解实现缓存预热
    • 3.使用 CommandLineRunner 或 ApplicationRunner 实现缓存预热
    • 4.通过实现 InitializingBean 接口,并重写 afterPropertiesSet 方法实现缓存预热。

SpringBoot 缓存预热是指在 Spring Boot 项目启动时,预先将数据加载到缓存系统(如 Redis)中的一种机制。

实现方案概述

在 Spring Boot 启动之后,可以通过以下手段实现缓存预热:

1.使用启动监听事件实现缓存预热

可以使用 Applicationlistener 监听 ContextRefreshedEvent 或 ApplicationReadyEvent 等应用上下文初始化完成事件,在这些事件触发后执行数据加载到缓存的操作,具体实现如下:
@Component
class cacheWarmer implements ApplicationListener<ContextRefreshedEvent> {
    @Override
    public void onApplicationEvent(ContextRefreshedEvent event) {
        // 执行缓存预热业务
        cacheManager.put("key",dataList);
    }
}
@Component
class cacheWarmer implements ApplicationListener<ApplicationReadyEvent> {
    @Override
    public void onApplicationEvent(ApplicationReadyEvent applicationReadyEvent) {
        // 执行缓存预热业务
        cacheManager.put("key",dataList);
    }
}
ContextRefreshedEvent Vs ApplicationReadyEvent

ContextRefreshedEvent 和 ApplicationReadyEvent 发生的时间和应用场景略有不同:

  1. ContextRefreshedEvent(上下文刷新事件):当 ApplicationContext 容器初始化或刷新时触发该事件,这个事件在 Bean 的初始化方法之前触发,意味着在该事件完成之前,Bean 已经完成实例化和配置了。
  2. ApplicationReadyEvent(应用就绪事件):当 Spring Boot 应用完全启动并准备接受请求时触发该事件。在该事件触发时,Spring Boot 应用的所有初始化工作已完成,包括 Bean 的实例化、依赖注入等。这个事件通常用于在应用启动完成后执行一些特定的操作,比如启动定时任务、加载缓存数据等。

所以说,ContextRefreshedEvent 事件被触发时,Spring容器中的 Bean 已经准备好了,但应用可能还没有完全启动,尚未准备好接收请求。而 ApplicationReadyEvent 事件则表示应用已经完全启动并准备好处理请求。

2.使用 @PostConstruct 注解实现缓存预热

在需要进行缓存预热的类上添加 @Component 注解,并在其方法中添加 @PostConstruct 注解和缓存预热的业务逻辑,具体实现代码如下:

@Component
class cachePreloader {
    @Autowired
    private YourCacheManager cacheManager;

    @PostConstruct
    public void preloadcache() {
        // 执行缓存预热业务...
        cacheManager.put("key", dataList);
    }
}

3.使用 CommandLineRunner 或 ApplicationRunner 实现缓存预热

CommandLineRunner 和 ApplicationRunner 都是 Spring Boot 应用程序启动后要执行的接口,它们都允许我们在应用启动后执行一些自定义的初始化逻辑,例如缓存预热。
CommandLineRunner 实现示例如下:

@Component
public class MyCommandLineRunner implements CommandLineRunner {
    @Override
    public void run(String... args)throws Exception{
        // 执行缓存预热业务...
        cacheManager.put("key",dataList);
    }
}

ApplicationRunner 实现示例如下:

@Component
public class MyApplicationRunner implements ApplicationRunner {
    @Override
    public void run(ApplicationArguments args)throws Exception {
        //执行缓存预热业务.
        cacheManager.put("key",dataList);
    };
}

CommandLineRunner 和ApplicationRunner 区别如下

  1. 方法签名不同:
    CommandLineRunner 接口有一个 run(String…. args)方法,它接收命令行参数作为可变长度字符串数组。。。 ApplicationRunner 接口则提供了一个 run(ApplicationArguments args)方法,它接收一个ApplicationArquments 对象作为参数,这个对象提供了对传入的所有命令行参数(包括选项和非选项参数的访问。
  2. 参数解析方式不同:
    CommandLineRunner 接口更简单直接,适合处理简单的命令行参数
    ApplicationRunner 接口提供了一种更强大的参数解析能力,可以通过 ApplicationArquments 获取详细的参。
    数信息,比如获取选项参数及其值、非选项参数列表以及查询是否存在特定参数等。
  3. 使用场景不同:
    当只需要处理一组简单的命令行参数时,可以使用 CommandLineRunner。
    对于需要精细控制和解析命令行参数的复杂场景,推荐使用 ApplicationRunner。

4.通过实现 InitializingBean 接口,并重写 afterPropertiesSet 方法实现缓存预热。

实现 InitializingBean 接口并重写 afterPropertiesSet 方法,可以在 Spring Bean 初始化完成后执行缓存预热,具体实现代码如下:

@Component
public class cachePreloader implements InitializingBean {
    @Autowired
    private YourcacheManager cacheManager;
    @Override
    public void afterpropertiesset()throws Exception {
        // 执行缓存预热业务
        cacheManager.put("key",dataList);
    }
}

小结
Spring Boot 缓存预热是指在 Spring Boot 项目启动时,预先将数据加载到缓存系统(如 Redis)中的一种机制。它可以通过监听 ContextRefreshedEvent 或 ApplicationReadyEvent 启动事件,或使用 @PostConstruct 注解,或实现 CommandLineRunner 接口、ApplicationRunner 接口,和 InitializingBean 接囗的方式来完成。