首页 > 其他分享 >面试官:SpringBoot如何实现缓存预热?

面试官:SpringBoot如何实现缓存预热?

时间:2024-01-20 22:32:44浏览次数:34  
标签:... 面试官 预热 SpringBoot CommandLineRunner 缓存 ApplicationRunner public

面试官:SpringBoot如何实现缓存预热?_面试

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

那么问题来了,在 Spring Boot 项目启动之后,在什么时候?在哪里可以将数据加载到缓存系统呢?

实现方案概述

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

  1. 使用启动监听事件实现缓存预热。
  2. 使用 @PostConstruct 注解实现缓存预热。
  3. 使用 CommandLineRunner 或 ApplicationRunner 实现缓存预热。
  4. 通过实现 InitializingBean 接口,并重写 afterPropertiesSet 方法实现缓存预热。

具体实现方案

① 启动监听事件

可以使用 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);
    }
}

② @PostConstruct 注解

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

@Component
public class CachePreloader {
    
    @Autowired
    private YourCacheManager cacheManager;

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

③ 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) 方法,它接收一个 ApplicationArguments 对象作为参数,这个对象提供了对传入的所有命令行参数(包括选项和非选项参数)的访问。
  1. 参数解析方式不同
  • CommandLineRunner 接口更简单直接,适合处理简单的命令行参数。
  • ApplicationRunner 接口提供了一种更强大的参数解析能力,可以通过 ApplicationArguments 获取详细的参数信息,比如获取选项参数及其值、非选项参数列表以及查询是否存在特定参数等。
  1. 使用场景不同
  • 当只需要处理一组简单的命令行参数时,可以使用 CommandLineRunner。
  • 对于需要精细控制和解析命令行参数的复杂场景,推荐使用 ApplicationRunner。

④ 实现InitializingBean接口

实现 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 项目启动时,预先将数据加载到缓存系统(如 Redis)中的一种机制。它可以通过监听 ContextRefreshedEvent 或 ApplicationReadyEvent 启动事件,或使用 @PostConstruct 注解,或实现 CommandLineRunner 接口、ApplicationRunner 接口,和 InitializingBean 接口的方式来完成。

课后思考

以上四种缓存预热方法的执行先后顺序是怎么样的?为什么?


标签:...,面试官,预热,SpringBoot,CommandLineRunner,缓存,ApplicationRunner,public
From: https://blog.51cto.com/vipstone/9346705

相关文章

  • 面试官:分库分表后如何生成全局ID?
    分库分表后就不能使用自增ID来作为表的主键了,因为数据库自增ID只适用于单机环境,但如果是分布式环境,是将数据库进行分库、分表或数据库分片等操作时,那么数据库自增ID就会生成重复ID,从而导致业务查询上的问题。所以此时,可以使用UUID或雪花ID来作为全局主键ID。1.UUID作为......
  • 面试官:如何保证本地缓存的一致性?
    有人可能看到“本地缓存”这四个字就会觉得不屑,“哼,现在谁还用本地缓存?直接用分布式缓存不就完了嘛”。然而,这就像你有一辆超级豪华的房车一样,虽然它空间很大,设备很全,但你去市中心的时候,依然会开小轿车一样,为啥?好停车啊!所以,不同的缓存类型是有不同得使用场景的。并且,为了防止缓存雪......
  • springboot多模块项目(微服务项目)正确打包(jar)方式
    大致步骤新建一个springboot项目名称为父亲添加父快捷方式。新建子模块,子模块同时插入新建springboot的项目,依次创建enty和web模块(关键是并配置好pom文件)web模块依赖于entiy模块中的实体类,创建测试控制器,先测试项目没问题再开始打包(jar)开始打包测试jar是否有用创建项目注意点:子模......
  • springBoot项目正确认识打war包方式(含打包代码链接)
    一:新建一个普普通通的springBoot项目二:并且编写测试controller@RequestMapping@RestControllerpublicclassController{@RequestMapping("/zzh")publicStringtoString(){return"zzh666";}}三:改造启动类(重点)主要就是继承SpringBootServletInitiali......
  • shiro缓存配置流程
    以前搞shiro的时候没有刻意去研究过这些配置文件,导致用shiro的时候也是迷迷糊糊,惭愧啊,要想成为人上人,读源码,懂配置是真滴重要!安全管理器配置(SecurityManager)配置项意思一setCacheManager配置缓存管理器用来缓存realm和session信息二setRealm登录时假如用的UsernamePasswordToken,......
  • springboot整合springSecurity入门案例(实现登录,记住我等常用标签使用)
    一,整合进依赖每个依赖都标了注释,大家可以按照自己需要的来添加,置于配置问件啥的,大家可以参考springboot+mybatisplus+redis整合(附上脚手架完整代码)<!--主要就是加了这个依赖--><dependency><groupId>org.springframework.security</groupId><artifact......
  • springboot+mybatis-plus+redis整合(附上脚手架完整代码)
    首先新建一个springboot项目next到这里的时候,我们可以选择用jdk几,还有就是Group,这个一般就是com.公司名字了,artifact就是项目名字。个人开发我还是喜欢用com.名字前缀哈。到了这一步的话,如果对这个项目有什么别的需求,比如需要用到mybatis啥的可以勾相应的选项。其实就是idea自动帮......
  • springboot项目结合filter,jdk代理实现敏感词过滤(简单版)
    我们对getParameter()这个方法得到的参数进行敏感词过滤。实现思路:利用过滤器拦截所有的路径请求同时在在过滤器执行的时候对getParameter得到的value值进行过滤。最后呢,到我们自己的实现的逻辑中呢?这个value值就被我们做过处理了。1:自定义的过滤配置文件把文件位置放在resource下的......
  • 正确理解springboot国际化简易运行流程
    看源码可以看出–》大致原理localeResolver国际化视图(默认的就是根据请求头带来的区域信息获取Locale进行国际化)返回的本地解析是根据响应头来决定的)接着按住ctrl点localeresolver可知localeresolver是一个接口于是有了这些我们只需通过继承LocaleResolver来自定义我们自己的Loca......
  • springboot中优雅的个性定制化错误页面+源码解析
    boot项目的优点就是帮助我们简化了配置,并且为我们提供了一系列的扩展点供我们使用,其中不乏错误页面的个性化开发。理解错误响应流程我们来到org.springframework.boot.autoconfigure.web.servlet.error下的ErrorMvcAutoConfiguration这里面配置了错误响应的规则。主要介绍里面注册......