问:在Spring生态下,实现预热功能(比如提前加载本地缓存),需要使用哪些扩展点?为什么?
答:
1、实现SmartLifecycle接口。
注意:排序在WebServerStartStopLifecycle之前运行(默认不用管)。
2、实现接口org.springframework.context.ApplicationListener<ContextRefreshedEvent>,监听ContextRefreshedEvent事件。
注意:监听事件执行的线程池配置,不能异步线程池执行哦😑。
3、实现接口org.springframework.boot.ApplicationRunner(spring boot)。
4、实现接口org.springframework.boot.CommandLineRunner(spring boot)。
5、使用注解@PostConstruct(在当前bean初始化完后就会执行目标方法)。
6、实现接口
org.springframework.beans.factory.InitializingBean(在当前bean初始化完后就会执行目标方法)
注意5、6不要异步执行,可能会碰到死锁现象哦😑。
因为实现预热功能,需要在流量流入系统之前,容器启动准备之后实现业务逻辑。
1、SmartLifecycle的运行时机:在容器启动最后finishRefresh阶段,在web服务真正启动之前(WebServerStartStopLifecycle,自己实现的SmartLifecycle注意与它的执行顺序)。
org.springframework.context.support.AbstractApplicationContext#refresh
排序后执行,注意web服务启动的WebServerStartStopLifecycle需要最后执行。
org.springframework.context.support.DefaultLifecycleProcessor#startBeans
2、监听ContextRefreshedEvent事件的运行时机:在SmartLifecycle的运行完之后,会发布事件ContextRefreshedEvent。
3、ApplicationRunner、CommandLineRunner的运行时机:是spring boot启动最后阶段,健康状态设置为健康之前。
org.springframework.boot.SpringApplication#run(java.lang.String...)
ApplicationRunner、CommandLineRunner运行:
org.springframework.boot.SpringApplication#callRunners
健康状态相关事件发布: