亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

springboot2.0.6中SpringApplication實例初始化

發布時間:2021-06-30 15:24:59 來源:億速云 閱讀:183 作者:chen 欄目:大數據

這篇文章主要介紹“springboot2.0.6中SpringApplication實例初始化”,在日常操作中,相信很多人在springboot2.0.6中SpringApplication實例初始化問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”springboot2.0.6中SpringApplication實例初始化”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!

SpringApplication實例初始化

public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
	// 設置資源加載器屬性
	this.resourceLoader = resourceLoader;
	// 校驗主要加載資源不能為空,為空拋出異常
	Assert.notNull(primarySources, "PrimarySources must not be null");
	// 設置primarySources(主要來源)屬性【后面會交給BeanDefinitionLoader,其分別load這些 primarySources 設置到scanner(掃描儀)中,避免重復掃描這些類進入容器】
	this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));
	// 獲取ApplicationContext類型,并設置到webApplicationType屬性中
	this.webApplicationType = WebApplicationType.deduceFromClasspath();
    // 獲取應用上下文初始化器實例集合,并設置到initializers屬性中
	setInitializers((Collection) getSpringFactoriesInstances(
				ApplicationContextInitializer.class));
    // 獲取應用監聽器實例集合,并設置到listeners屬性中
	setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
	// 找出main(主入口應用類)類,這里是CoreServerApplication類
	this.mainApplicationClass = deduceMainApplicationClass();
}

   1. webApplicationType 是一個枚舉類,用來判斷當前的springboot項目是什么類型的。

  1. NONE:既不是運行在 web 容器下的應用并且也不應該啟動一個內置的web服務。

  2. SERVLET:是需要運行在基于 servlet 的web應用且需要啟動一個內置 servlet-web 服務。

  3. REACTIVE:還是運行在 reactive 的web應用中且需要啟動一個 reactive-web 服務。

   2. WebApplicationType.deduceFromClasspath() 獲取獲取ApplicationContext類型

private static final String[] SERVLET_INDICATOR_CLASSES = { "javax.servlet.Servlet",
      "org.springframework.web.context.ConfigurableWebApplicationContext" };
private static final String WEBMVC_INDICATOR_CLASS = "org.springframework."
      + "web.servlet.DispatcherServlet";
private static final String WEBFLUX_INDICATOR_CLASS = "org."
      + "springframework.web.reactive.DispatcherHandler";
private static final String JERSEY_INDICATOR_CLASS = "org.glassfish.jersey.servlet.ServletContainer";
private static final String SERVLET_APPLICATION_CONTEXT_CLASS = "org.springframework.web.context.WebApplicationContext";
private static final String REACTIVE_APPLICATION_CONTEXT_CLASS = "org.springframework.boot.web.reactive.context.ReactiveWebApplicationContext";
static WebApplicationType deduceFromClasspath() {
   if (ClassUtils.isPresent(WEBFLUX_INDICATOR_CLASS, null)
         && !ClassUtils.isPresent(WEBMVC_INDICATOR_CLASS, null)
         && !ClassUtils.isPresent(JERSEY_INDICATOR_CLASS, null)) {
      return WebApplicationType.REACTIVE;
   }
   for (String className : SERVLET_INDICATOR_CLASSES) {
      if (!ClassUtils.isPresent(className, null)) {
         return WebApplicationType.NONE;
      }
   }
   return WebApplicationType.SERVLET;
}

    根據org.springframework.util.ClassUtils的靜態方法 isPresent 判斷classpath里面是否有包含 WEBFLUX_INDICATOR_CLASS 并且沒有包含 WEBMVC_INDICATOR_CLASS 和 JERSEY_INDICATOR_CLASSERVLET_INDICATOR_CLASSE ,滿足條件則表示啟動一個 REACTIVE 類型的WEB應用,不滿足上述條件且有 SERVLET_INDICATOR_CLASSES 包含的類,則表示啟動一個 SERVLET 類型的WEB應用,否則啟動一個標準應用。

    是否啟動一個WEB應用就是取決于 classpath 下是否滿足有 javax.servlet.Servlet 和 org.springframework.web.context.ConfigurableWebApplicationContext 或有 org. springframework.web.reactive.DispatcherHandler 并且沒有org.springframework.web.servlet.DispatcherServlet 和 org.glassfish.jersey.servlet.ServletContainer。

3. setInitalizers()

初始化 classpath 下的所有的可用的 ApplicationContextInitializer

    ApplicationContextInitializer 應用程序初始化器,做一些初始化的工作,是 springboot 準備調用 prepareContext 方法準備 spring 容器(此時spring容器已經創建需要refresh)之前調用的用來在這個時間點執行一些操作:比如設置 servletContext 等

    默認情況下,getSpringFActoriesInstances 方法從 spring.factories 文件中找出key為 ApplicationContextInitializer 類型的權限定名稱集合有:

  • org.springframework.boot.context.ConfigurationWarningsApplicationContextInitializer:

    • 向應用上下文中注冊后置處理器(ConfigurationWarningsPostProcessor)

  • org.springframework.boot.context.ContextIdApplicationContextInitializer

    • 設置應用上下文ID,并將上面生成的ContextId(ContextIdApplicationContextInitializer)對象,作為一個單例bean注冊到當前應用上下文。

  • org.springframework.boot.context.config.DelegatingApplicationContextInitializer

    • 執行環境屬性"context.initializer.classes"指定的初始化器,然后執行這些初始化器。這里實現springboot應用程序自己實現的ApplicationContextInitializer對應用程序做一些初始化工作。

  • org.springframework.boot.context.web.ServerPortInfoApplicationContextInitializer

    • 把自己作為監聽器注冊到應用上下文中

  • org.springframework.boot.autoconfigure.SharedMetadataReaderFactoryContextInitializer

    • 向應用上下文中注冊后置處理器(CachingMetadataReaderFactoryPostProcessor)

  • org.springframework.boot.autoconfigure.logging.ConditionEvaluationReportLoggingListener

    • 向應用上下文中注冊監聽器(ConditionEvaluationReportListener)當應用上下文實現GenercApplicationContext時,則設置“report”屬性

springboot2.0.6中SpringApplication實例初始化( 圖1-2 spring-boot.jar 中 spring.factories文件中applicationContextInitializer相關)springboot2.0.6中SpringApplication實例初始化

( 圖1  執行getSpringFactoriesInstances(ApplicationContextInitializer.class)獲取 spring.factories文件中applicationContextInitializer相關的工廠類,并進行初始化)

springboot2.0.6中SpringApplication實例初始化 

( 圖2 springApplication對象中instances屬性值)

4. setListeners()

初使化 classpath 下的所有的可用的 ApplicationListener

    ApplicationListener 應用程序事件(ApplicationEvent)監聽器

    這里的應用程序事件(ApplicationEvent)有應用程序啟動事件(ApplicationStartedEvent),失敗事件(ApplicationFailedEvent),準備事件(ApplicationPreparedEvent)等

    應用程序事件監聽器跟監聽事件是綁定的。比如 ConfigServerBootstrapApplicationListener 只跟 ApplicationEnvironmentPreparedEvent 事件綁定, LiquibaseServiceLocatorApplicationListener 只跟 ApplicationStartedEvent 事件綁定,LoggingApplicationListener 跟所有事件綁定等

    默認情況下,getSpringFactoriesInstances 方法從 spring.factories 文件中找出key為 ApplicationListener 類型的,類全限定名稱集合有:

  • org.springframework.boot.autoconfigure.BackgroundPreinitializer

  • org.springframework.boot.ClearCachesApplicationListener

  • org.springframework.boot.builder.ParentContextCloserApplicationListener

  • org.springframework.boot.context.FileEncodingApplicationListener

  • org.springframework.boot.context.config.AnsiOutputApplicationListener

  • org.springframework.boot.context.config.ConfigFileApplicationListener

  • org.springframework.boot.context.config.DelegatingApplicationListener

  • org.springframework.boot.context.logging.ClasspathLoggingApplicationListener

  • org.springframework.boot.context.logging.LoggingApplicationListener

  • org.springframework.boot.liquibase.LiquibaseServiceLocatorApplicationListener

( 圖3-1 spring-boot.jar 中 spring.factories文件中applicationlistener相關)

springboot2.0.6中SpringApplication實例初始化 

( 圖3-2 spring-boot.jar 中 spring.factories文件中applicationlistener相關)

springboot2.0.6中SpringApplication實例初始化

( 圖4  執行getSpringFactoriesInstances(Applicationlistener.class)獲取 spring.factories文件中applicationContextInitializer相關的工廠類,并進行初始化)

springboot2.0.6中SpringApplication實例初始化

  1. 由于spring 有一大堆事件比如 ContextRefreshedEvent,ContextStartedEvent 等等 我們有一個 ApplicationListener 就會監聽到這些事件進而做相應的處理。

  2. 其實都是 applicationContext 調用其 publishEvent 發送一些 event,該方法會從很多 listener 中找到對該 event 感興趣的 listener 調用其 onApplicationEvent,而實現這些的就是 SimpleApplicationEventMulticaster,如果有 Executor,其會優先使用Executor來執行這就可能導致我們的回調是異步的。

  3. applicationContext 還會把event傳播到其父容器(我們知道我們常用到AnnotationConfigApplicationContext 已經其有很多父容器)

  4. 這邊還有一個策略就是如果 earlyApplicationEvents 存在 則先把事件加入到 earlyApplicationEvents,稍后在發送,如果不存在則直接發送。

  5. applicationevent 中包含時間戳,springboot 啟動類(source),還有我們的spring容器

5. 自定義ApplicationContextInitializer 和 ApplicationListener

如果我們想自己在代碼中寫 ApplicationContextInitializer 和 ApplicationListener 的實現類時候可以采用下列方式:

  • 在項目中建立一個 META-INF/spring.factories 文件,里面以 key=value 存放我們的實現類

  • 手動調用 SpringApplication 的對應添加方法也可以

  • 在我們的 application.properties 里面配置 context.initializer.classes = 實現類(通過 DelegatingApplicationContextInitializer 獲取到我們配置的 initializer,進而可以保證在 prepareContext 時候調用),context.listener.classes = 實現類(無法監聽到 springboot 啟動時候的一些事件,因為那個時候該實現類還未加入容器)

  • 雖然我們使用 @Configuration 來講我們 ApplicationListener 的實現類加入到spring容器,且也能監聽到程序正常運行的一些事件(無法監聽到 springboot 啟動時候的一些事件,因為那個時候該實現類還未加入容器),但是 我們如果想監聽全部的事件最好使用上述三種方式配置這樣可以在 springboot 啟動的時候就監聽

6. getSpringFactoriesInstances()

通過系統加載類去指定目錄下根據 propties 文件獲取對應的 class 的全限定名稱

總結

SpringApplication 的構造方法主要就是設置 Initializers 和 Listeners 同時設置 primaryClass 方便后面先去加載 primaryClass,而且也順便確定了當前的 springboot 的運行環境

到此,關于“springboot2.0.6中SpringApplication實例初始化”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

巴中市| 玉龙| 右玉县| 郸城县| 绩溪县| 新野县| 沂水县| 贵溪市| 安西县| 阿坝县| 四平市| 浦县| 和林格尔县| 景德镇市| 奎屯市| 太仆寺旗| 嵊州市| 六安市| 灵台县| 阳曲县| 陈巴尔虎旗| 丹棱县| 遂宁市| 旺苍县| 清流县| 西乌珠穆沁旗| 金乡县| 昭觉县| 大理市| 巨野县| 商都县| 邯郸市| 绵阳市| 屯留县| 黔江区| 富裕县| 饶平县| 焉耆| 盐亭县| 门源| 冷水江市|