Spring 啟動加載資源到內存
前言
在一些業務場景中,當容器初始化完成之後,需要處理一些操作,比如一些數據的加載、初始化緩存、特定任務的註冊等等。我找到了三種方式解決下面的問題。
1、使用PostConstruct註解
這種解決方法比較適用於: 在對於接口響應時間要求比較短,而接口中又需要頻繁調用數據庫查詢,或者調用外部系統的情況下,為了加快接口的響應速度,在項目啟動時,將通過途徑獲取的結果初始化到靜態變量或者放置到各種緩存中。
首先靜態代碼塊不行,靜態代碼塊的執行順序在Spring註解之前,當執行的時候,調用請求的Service還沒有註入進來,執行時會報空指針錯誤。
在啟動時完成一些初始化的操作,而這些初始化的操作,又要依賴於依賴註入的結果,就無法在構造方法中實現了。為此需要使用@PostConstruct
關於Constructor,Spring註解,@PostConstruct執行順序:Constructor >Spring註解> @PostConstruct
@Component public class TestUtils { @Autowired ICommonService commonService; public static List<Rsp> resourceList = new ArrayList<>(); //初始化的全局靜態變量 private static ICommonService reCommonService; @PostConstruct public void Init() { //查詢所有的 Req reqBean = new Req(); reCommonService=commonService;
reqBean.setFindType(PROVINCE_CITY_FIND_TYPE.FIND_TYPE_B.toString());//查詢所有 城市 Rsp rsp=reCommonService.getPaAreaCityInfo(reqBean); resourceList.add(rsp); } }
2、使用ApplicationListener
在初始化緩存或者特定任務的註冊的場景下,可以使用Spring提供的ApplicationListener來進行操作。
首先,要實現ApplicationListener接口並實現onApplicationEvent方法。舉例(使用SpringBoot)如下:
public class ApplicationEventListener implements ApplicationListener<ApplicationEvent> { @Autowired private PubSubService pubSubService; @Override public void onApplicationEvent(ApplicationEvent event) { if (event instanceof ContextRefreshedEvent) { ApplicationContext applicationContext = ((ContextRefreshedEvent) event).getApplicationContext(); GlobolParameters.context = applicationContext; BaseLogger.info("ContextRefreshed初始化開始..."); // 設置上下文 } if (event instanceof ApplicationReadyEvent) { //啟動發布訂閱 pubSubService = GlobolParameters.context.getBean(PubSubService.class); // redis subscribe job pubSubService.subscribe(); // redis publish job pubSubService.publish(); } if (event instanceof ApplicationFailedEvent) { Throwable exception = ((ApplicationFailedEvent) event).getException(); BaseLogger.error("【ApplicationFailedEvent】Spring IOC init error ", exception); } } }
然後實例化ApplicationEventListener類,在Spring Boot中通過一個配置類進行實例化:
@Configuration public class ListenerConfig { @Bean public ApplicationEventListener applicationEventListener(){ return new ApplicationEventListener(); } }
通過上述代碼,在SpringListener中做到,啟動了發布訂閱的服務。
3、啟動類顯式調用
如果對外調用的服務,需要依賴啟動後放置在容器中的上下文的情況,則需要手動在啟動類中獲取相應的Bean,調用初始化的方法進行初始化。
public class StartIiApplication{ public static void main(String[] args) { ApplicationContext applicationContext = SpringApplication.run(StartIiApplication.class, args); BeanUtil.setApplicationContext(applicationContext); //從啟動的容器中獲取Bean,並調用初始化方法 TestUtils util=(TestUtils) applicationContext.getBean("testUtils"); util.Init(); } }
Spring 啟動加載資源到內存