正文 跟靈分別後,我在椅子上發了很久的呆。可能有五分鐘吧。就這樣感受著微風吹過身體,聽著身邊熙熙攘攘的聲音。 我不知道為什麼要發呆。自然而然就這樣做了。 過了很久,我意識到可能必須要吃飯了,才起身找飯館。 今天情緒不太好。我不知道是不是因為沒睡夠。不過,並沒有從一開始就很糟糕,到晚上才開始。 先是發 ...
1 、使用介面ApplicationRunner和CommandLineRunner
這兩個介面都是在容器運行後執行的,如下圖示
如果項目需要在系統啟動時,初始化資源,可以繼承這兩個介面,實現諸如緩存預熱、DB連接等。
實現ApplicationRunner介面
@Component public class MyApplicationRunner implements ApplicationRunner { @Override public void run(ApplicationArguments args) throws Exception { System.out.println("緩存預熱~"); System.out.println("DB連接~"); System.out.println("日誌系統初始化~"); System.out.println("資源文件初始化~"); System.out.println("常駐後臺線程的資源初始化~"); } }View Code
實現CommandLineRunner介面
@Component public class MyCommandLineRunner implements CommandLineRunner { @Override public void run(String... args) throws Exception { System.out.println("緩存預熱~"); System.out.println("DB連接~"); System.out.println("日誌系統初始化~"); System.out.println("資源文件初始化~"); System.out.println("常駐後臺線程的資源初始化~"); } }View Code
2、監聽spring事件ApplicationListener<>
ApplicationContext事件的實現機制是觀察者模式,通過兩個介面ApplicationEvent和ApplicationListener來實現。
spring容器在初始化時,會在不同的階段,發佈ApplicationEvent事件,因此,可以通過ApplicationListener監聽各個階段的事件來實現不同的功能。
spring提供了以下ApplicationEvent事件:
- ContextStartedEvent 上下文啟動事件,此 Start 事件是當Spring容器啟動時發佈,即調用 start() 方法是執行,意味著所有Lifecyc Bean 都監聽到了 start 事件。
- ContextRefreshedEvent 上下文刷新事件
此 Refreshed 事件是當容器實例化時發佈,即執行 refresh() 方法,此時所有的 Bean 都已載入,後置處理器被激活,容器中所有的對象就可以使用,如果容器支持熱重載,則 refresh 可以被觸發多次(XmlWebApplicatonContext支持熱刷新,而GenericApplicationContext則不支持)。
- ContextStoppedEvent 上下文停止事件 當使用 ConfigurableApplicationContext 介面中的 stop() 停止 ApplicationContext 時,發佈這個事件。你可以在接受到這個事件後做必要的清理的工作。
- ContextClosedEvent 上下文關閉事件 當使用 ConfigurableApplicationContext 介面中的 close() 方法關閉 ApplicationContext 時,該事件被髮布。一個已關閉的上下文到達生命周期末端;它不能被刷新或重啟。
- RequestHandledEvent 請求處理完成事件 此 Request handled 事件只在使用spring的DispatcherServlet時有效,當一個請求被處理完成時發佈。
基於以上事件類型,我們可以監聽ContextRefreshedEvent事件,初始化系統資源,以及監聽ContextStoppedEvent事件來清理資源。
初始化資源:
@Component public class MyApplicationListener implements ApplicationListener<ContextRefreshedEvent> { @Override public void onApplicationEvent(ContextRefreshedEvent event) { System.out.println("做一些初始化的工作,比如緩存預熱~"); ApplicationContext ct= event.getApplicationContext(); System.out.println(ct); } }View Code
清理資源:
@Component public class MyApplicationStopListener implements ApplicationListener<ContextStoppedEvent> { @Override public void onApplicationEvent(ContextStoppedEvent event) { System.out.println("做一些清理資源的工作,比如緩存清理,DB連接清理~"); ApplicationContext ct= event.getApplicationContext(); System.out.println(ct); } @Override public boolean supportsAsyncExecution() { return ApplicationListener.super.supportsAsyncExecution(); } }View Code
3、@PostConstruct、@PreDestroy註解
@PostConstruct註解時針對Bean初始化完成後,要執行的方法,@PreDestroy註解時Bean銷毀時執行。
@Component public class RedisInit { @PostConstruct public void init(){ System.out.println("緩存預熱~"); } @PreDestroy public void destroy(){ System.out.println("緩存清理~"); } }View Code
4、InitializingBean、DisposableBean介面
InitializingBean、DisposableBean 介面也是針對的Bean的。
@Component public class RedisInitializingBean implements InitializingBean, DisposableBean { @Override public void afterPropertiesSet() throws Exception { System.out.println("緩存預熱~"); } @Override public void destroy() throws Exception { System.out.println("緩存清理~"); } }View Code
5、配置Bean時,指定Bean的init和destroy方法
@Bean(name = "redisInit",initMethod = "init",destroyMethod = "") public RedisInit redisInit(){ return new RedisInit(); }View Code
6、SmartLifecycle介面
SmartLifecycle介面有三個方法start stop isRuning,可以在start方法里初始化資源,在stop方法里實現資源清理
@Component public class RedisSmartLifecycle implements SmartLifecycle { private boolean running = false; @Override public void start() { System.out.println("緩存預熱~"); running=true; } @Override public void stop() { System.out.println("緩存清理~"); running=false; } @Override public boolean isRunning() { return running; } }View Code