1. 程式人生 > >Spring 啟動加載資源到內存

Spring 啟動加載資源到內存

ica ... 業務場景 sel style fail nap 發布 new

前言

在一些業務場景中,當容器初始化完成之後,需要處理一些操作,比如一些數據的加載、初始化緩存、特定任務的註冊等等。我找到了三種方式解決下面的問題。

1、使用PostConstruct註解

  這種解決方法比較適用於: 在對於接口響應時間要求比較短,而接口中又需要頻繁調用數據庫查詢,或者調用外部系統的情況下,為了加快接口的響應速度,在項目啟動時,將通過途徑獲取的結果初始化到靜態變量或者放置到各種緩存中。

首先靜態代碼塊不行,靜態代碼塊的執行順序在Spring註解之前,當執行的時候,調用請求的Service還沒有註入進來,執行時會報空指針錯誤。

在啟動時完成一些初始化的操作,而這些初始化的操作,又要依賴於依賴註入的結果,就無法在構造方法中實現了。為此需要使用@PostConstruct

在構造方法之後執行,被@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 啟動加載資源到內存