淺談SpringBoot資源初始化加載的幾種方式
一、問題
在平時的業(yè)務(wù)模塊開發(fā)過程中,難免會需要做一些全局的任務(wù)、緩存、線程等等的初始化工作,那么如何解決這個問題呢?方法有多種,但具體又要怎么選擇呢?
二、資源初始化
1、既然要做資源的初始化,那么就需要了解一下springboot啟動過程(這里大體說下啟動過程,詳細:http://www.dhdzp.com/article/133648.htm)

按照前面的分析,Spring-boot容器啟動流程總體可劃分為2部分:
- 執(zhí)行注解:掃描指定范圍下的bean、載入自動配置類對應(yīng)的bean加載到IOC容器。
- man方法中具體SpringAppliocation.run(),全流程貫穿SpringApplicationEvent(經(jīng)典的spring事件驅(qū)動模型),有6個子類:
- ApplicationFailedEvent.class
- ApplicationPreparedEvent.class
- ApplicationReadyEvent.class
- ApplicationStartedEvent.class
- ApplicationStartingEvent.class
- SpringApplicationEvent.class
2、CommandLineRunner和ApplicationRunner
由上可知,我們只要實現(xiàn)這兩個中的任何一個接口便可以完成我們的資源初始化任務(wù),可以看到它們的加載是在容器完全啟動之前。它兩的區(qū)別是:前者的run方法參數(shù)是String...args,直接傳入字符串,后者的參數(shù)是ApplicationArguments,對參數(shù)進行了封裝。功能上是一樣的。同時也可以使用 @Order注解來實現(xiàn)資源加載的先后順序,值越小,優(yōu)先級越高。實例如下:
@Component
@Order(1)
public class MyCommandLineRunner implements CommandLineRunner {
@Override
public void run(String... args) throws Exception {
System.out.println("...init resources by implements CommandLineRunner");
}
}
@Component
@Order(2)
public class MyApplicationRunner implements ApplicationRunner {
@Override
public void run(ApplicationArguments applicationArguments) throws Exception {
System.out.println("...init resources by implements ApplicationRunner");
}
}
3、@PostConstruct
在具體Bean的實例化過程中執(zhí)行,@PostConstruct注解的方法,會在構(gòu)造方法之后執(zhí)行,順序為Constructor > @Autowired > @PostConstruct > 靜態(tài)方法,所以這個注解就避免了一些需要在構(gòu)造方法里使用依賴組件的尷尬(與之對應(yīng)的還有@PreDestroy,在對象消亡之前執(zhí)行,原理差不多)。使用特點如下:
- 只有一個非靜態(tài)方法能使用此注解
- 被注解的方法不得有任何參數(shù)
- 被注解的方法返回值必須為void
- 被注解方法不得拋出已檢查異常
- 此方法只會被執(zhí)行一次
@Component
public Class AAA {
@Autowired
private BBB b;
public AAA() {
System.out.println("此時b還未被注入: b = " + b);
}
@PostConstruct
private void init() {
System.out.println("此時b已經(jīng)被注入: b = " + b);
}
}
4、InitializingBean
InitializingBean 是 Spring 提供的一個接口,只包含一個方法 afterPropertiesSet()。凡是實現(xiàn)了該接口的類,當其對應(yīng)的 Bean 交由 Spring 管理后,當其必要的屬性全部設(shè)置完成后,Spring 會調(diào)用該 Bean 的 afterPropertiesSet()。在Bean在實例化的過程中執(zhí)執(zhí)行順序為:Constructor > @PostConstruct > InitializingBean > init-method
public class InitSequenceBean implements InitializingBean {
public InitSequenceBean() {
System.out.println("InitSequenceBean: constructor");
}
@PostConstruct
public void postConstruct() {
System.out.println("InitSequenceBean: postConstruct");
}
public void initMethod() {
System.out.println("InitSequenceBean: init-method");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("InitSequenceBean: afterPropertiesSet");
}
}
5、ApplicationListener
ApplicationListener 就是spring的監(jiān)聽器,能夠用來監(jiān)聽事件,典型的觀察者模式。如果容器中有一個ApplicationListener Bean,每當ApplicationContext發(fā)布ApplicationEvent時,ApplicationListener Bean將自動被觸發(fā)。這種事件機制都必須需要程序顯示的觸發(fā)。其中spring有一些內(nèi)置的事件,當完成某種操作時會發(fā)出某些事件動作。比如監(jiān)聽ContextRefreshedEvent事件,當所有的bean都初始化完成并被成功裝載后會觸發(fā)該事件,實現(xiàn)ApplicationListener接口可以收到監(jiān)聽動作,然后可以寫自己的邏輯。同樣事件可以自定義、監(jiān)聽也可以自定義,完全根據(jù)自己的業(yè)務(wù)邏輯來處理。所以也能做到資源的初始化加載!
@Component
public class DataSourceInitListener implements ApplicationListener<ContextRefreshedEvent> {//ContextRefreshedEvent為啟動事件
private static final Logger LOGGER = LoggerFactory.getLogger(DataSourceInitListener.class);
@Autowired
private SystemConfigService systemConfigService;
@Autowired
private ItemService itemService;
@Autowired
private SystemResultService systemResultService;
@Override
public void onApplicationEvent(ContextRefreshedEvent event) {
if(event.getApplicationContext().getParent() == null) {//判斷是否執(zhí)行過,執(zhí)行過則不再執(zhí)行
LOGGER.info("初始化systemConfig數(shù)據(jù)");
systemConfigService.initConfig();
LOGGER.info("初始化返回消息數(shù)據(jù)");
systemResultService.initResult();
LOGGER.info("系統(tǒng)初始化結(jié)束...........");
}
}
}
到此這篇關(guān)于淺談SpringBoot資源初始化加載的幾種方式的文章就介紹到這了,更多相關(guān)SpringBoot資源初始化加載內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
濫用@PathVariable導(dǎo)致bug原因分析解決
這篇文章主要為大家介紹了濫用@PathVariable導(dǎo)致bug原因分析解決,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-12-12
Shiro 控制并發(fā)登錄人數(shù)限制及登錄踢出的實現(xiàn)代碼
本文通過shiro實現(xiàn)一個賬號只能同時一個人使用,本文重點給大家分享Shiro 控制并發(fā)登錄人數(shù)限制及登錄踢出的實現(xiàn)代碼,需要的朋友參考下吧2017-09-09

