在SpringBoot中,怎麼在程序啓動或退出時執行初始化或者清理工作?
有的時候我們需要在應用程序啓動的時候執行一些資源初始化的工作,或者在應用程序退出的時候進行一些資源釋放的工作,那麼該如何做呢?這篇文章針對兩個問題做一個彙總說明。
怎麼在應用程序啓動時執行一些初始化工作?
我們在開發中可能會有這樣的情景。需要在容器啓動的時候執行一些內容。比如讀取配置文件,數據庫連接之類的。SpringBoot給我們提供了兩個接口來幫助我們實現這種需求。這兩個接口分別爲CommandLineRunner和ApplicationRunner。他們的執行時機爲容器啓動完成的時候。
這兩個接口中有一個run方法,我們只需要實現這個方法即可。
這兩個接口的不同之處在於:ApplicationRunner中run方法的參數爲ApplicationArguments,而CommandLineRunner接口中run方法的參數爲String數組。
下面我寫兩個簡單的例子,來看一下這兩個接口的實現。
(1)通過CommandLineRunner接口實現
package com.majing.test.springbootdemo.init;
import org.springframework.boot.CommandLineRunner;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
@Component
@Order(1)
public class CommandLineRunnerTest implements CommandLineRunner {
@Override
public void run(String... args) throws Exception {
System.out.println("這是測試CommandLineRunner的示例。");
}
}
(2)通過ApplicationRunner接口實現
package com.majing.test.springbootdemo.init;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
@Component
@Order(2)
public class ApplicationRunnerTest implements ApplicationRunner {
@Override
public void run(ApplicationArguments args) throws Exception {
System.out.println("這是測試ApplicationRunner接口");
}
}
上面的初始化工作我們可以定義多個,當然正常情況下我們會定義一個然後在這一個裏面按照先後順序執行相應的邏輯,但是如果定義了多個,而我們由希望按照指定的順序執行,那麼該怎麼做呢?
@Order註解:如果有多個實現類,而你需要他們按一定順序執行的話,可以在實現類上加上@Order註解。@Order(value=整數值)。SpringBoot會按照@Order中的value值從小到大依次執行。
如下所示,如果不加@Order註解,那麼我本地運行的順序是先執行ApplicationRunner而後運行CommandLineRunner,但是加了@Order之後就按照我指定的順序執行了。
怎麼在應用程序退出時執行一些資源釋放邏輯?
和在啓動時執行一些初始化工作類似,在應用程序退出時,我們也可以通過一些方式來執行一些邏輯,這裏也提供兩種方式。
(1)通過實現DisposableBean接口
package com.majing.test.springbootdemo.init;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.stereotype.Component;
@Component
public class ExitCode implements DisposableBean {
@Override
public void destroy() throws Exception {
System.out.println("執行ExitCode中的退出代碼");
}
}
(2)通過@PreDistroy註解
package com.majing.test.springbootdemo.init;
import org.springframework.stereotype.Component;
import javax.annotation.PreDestroy;
@Component
public class AnnotationPreDistroyExitCode {
@PreDestroy
public void exit(){
System.out.println("執行AnnotationPreDistroyExitCode中的exit()退出代碼");
}
}
執行後的先後順序如下:
但是需要注意的是,對於通過上面兩種方式實現的退出,在執行順序上不能進行控制,即使使用了@Order註解,肯定是先執行實現了DisposableBean接口的類,之後纔是執行使用@PreDistroy註解的方法。