最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

SpringApplicationRunListener監(jiān)聽器源碼詳解

 更新時(shí)間:2023年11月15日 09:20:25   作者:立小研先森  
這篇文章主要介紹了SpringApplicationRunListener監(jiān)聽器源碼詳解,springboot提供了兩個(gè)類SpringApplicationRunListeners、SpringApplicationRunListener(EventPublishingRunListener),spring框架還提供了一個(gè)ApplicationListener接口,需要的朋友可以參考下

前言

springboot提供了兩個(gè)類SpringApplicationRunListeners、SpringApplicationRunListener(EventPublishingRunListener),spring框架還提供了一個(gè)ApplicationListener接口,那么這幾個(gè)類或接口的關(guān)系又是如何呢?

首先SpringApplicationRunListeners類是SpringApplicationRunListener接口的代理類,可以批量調(diào)用SpringApplicationRunListener接口方法,SpringApplicationRunListener接口只有一個(gè)實(shí)現(xiàn)類EventPublishingRunListener,其有一個(gè)屬性SimpleApplicationEventMulticaster,SimpleApplicationEventMulticaster即是一個(gè)ApplicationListener監(jiān)聽器接口的代理實(shí)現(xiàn)類,可以批量的執(zhí)行監(jiān)聽器的onApplicationEvent方法。

1.SpringApplicationRunListener接口源碼

SpringApplicationRunListener是對(duì)org.springframework.boot.SpringApplication類的run方法進(jìn)行監(jiān)聽,SpringApplicationRunListener實(shí)現(xiàn)類是通過SpringFactoriesLoader類加載(即springboot SPI);并且需要聲明一個(gè)包含SpringApplication實(shí)例及String[]的參數(shù)構(gòu)造方法。

public interface SpringApplicationRunListener {
	/**
	 * 當(dāng)run方法第一次啟動(dòng)時(shí)立即調(diào)用,可用于非常早期的初始化
	 */
	default void starting() {
	}
	/**
	 * 在ApplicationContext創(chuàng)建之前,一旦環(huán)境environment準(zhǔn)備好就調(diào)用。
	 * @param environment the environment
	 */
	default void environmentPrepared(ConfigurableEnvironment environment) {
	}
	/**
	 * 在資源(可以理解為配置主類)被加載完成之前,一旦ApplicationContext被創(chuàng)建并準(zhǔn)備好就立馬調(diào)用,
	 * @param context the application context
	 */
	default void contextPrepared(ConfigurableApplicationContext context) {
	}
	/**
	 * 在資源加載完成之后,但在刷新之前調(diào)用
	 * @param context the application context
	 */
	default void contextLoaded(ConfigurableApplicationContext context) {
	}
	/**
	 * 上下文已刷新,應(yīng)用程序已啟動(dòng),但是CommandLineRunner和ApplicationRunner尚未調(diào)用。
	 * @param context the application context.
	 * @since 2.0.0
	 */
	default void started(ConfigurableApplicationContext context) {
	}
	/**
	 * 當(dāng)ApplicationContext已經(jīng)refresh且所有的CommandLineRunner和ApplicationRunner都已被調(diào)用時(shí),在run方法完成之前立即調(diào)用。
	 * @param context the application context.
	 * @since 2.0.0
	 */
	default void running(ConfigurableApplicationContext context) {
	}
	/**
	 * 在運(yùn)行應(yīng)用程序時(shí)發(fā)生故障時(shí)調(diào)用
	 * @param context 應(yīng)用程序上下文,可能為null(在應(yīng)用程序上下文創(chuàng)建之前)
	 * @param exception the failure
	 * @since 2.0.0
	 */
	default void failed(ConfigurableApplicationContext context, Throwable exception) {
	}

2.EventPublishingRunListener

SpringApplicationRunListener接口唯一實(shí)現(xiàn)類EventPublishingRunListener

public class EventPublishingRunListener implements SpringApplicationRunListener, Ordered {
	//啟動(dòng)類實(shí)例對(duì)象
	private final SpringApplication application;
	//參數(shù)
	private final String[] args;
	//ApplicationListener監(jiān)聽器接口代理廣播類
	private final SimpleApplicationEventMulticaster initialMulticaster;
	public EventPublishingRunListener(SpringApplication application, String[] args) {
		this.application = application;
		this.args = args;
		this.initialMulticaster = new SimpleApplicationEventMulticaster();
    //獲取應(yīng)用程序的監(jiān)聽器類,并循環(huán)添加到代理類的監(jiān)聽器助手屬性對(duì)象中
		for (ApplicationListener<?> listener : application.getListeners()) {
			this.initialMulticaster.addApplicationListener(listener);
		}
	}
}

其中application.getListeners()獲取通過SPI方式定義的所有ApplicationListener監(jiān)聽器接口定義的監(jiān)聽器類,其初始化是在SpringApplication類中通過構(gòu)造函數(shù)的方式,如下:

//監(jiān)聽器對(duì)象集合
private List<ApplicationListener<?>> listeners;

public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
		this.resourceLoader = resourceLoader;
		Assert.notNull(primarySources, "PrimarySources must not be null");
		this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));
		this.webApplicationType = WebApplicationType.deduceFromClasspath();
  	//通過SPI方式初始化應(yīng)用程序初始化器
		setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));
		//通過SPI方式獲取ApplicationListener監(jiān)聽器
		setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
		this.mainApplicationClass = deduceMainApplicationClass();
	}

spring.factories配置文件:

# Application Listeners
org.springframework.context.ApplicationListener=\
org.springframework.boot.ClearCachesApplicationListener,\
org.springframework.boot.builder.ParentContextCloserApplicationListener,\
org.springframework.boot.cloud.CloudFoundryVcapEnvironmentPostProcessor,\
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.SpringApplicationRunListeners

SpringApplicationRunListener接口實(shí)現(xiàn)類集合類SpringApplicationRunListeners

class SpringApplicationRunListeners {

	private final Log log;
	//存儲(chǔ)SpringApplicationRunListener監(jiān)聽器集合
	private final List<SpringApplicationRunListener> listeners;

	SpringApplicationRunListeners(Log log, Collection<? extends SpringApplicationRunListener> listeners) {
		this.log = log;
		this.listeners = new ArrayList<>(listeners);
	}
}

4.獲取SpringApplicationRunListeners對(duì)象

org.springframework.boot.SpringApplication#run(java.lang.String…)方法中通過SPI方式獲取SpringApplicationRunListeners對(duì)象

public ConfigurableApplicationContext run(String... args) {
		StopWatch stopWatch = new StopWatch();
		stopWatch.start();
		ConfigurableApplicationContext context = null;
		Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();
		configureHeadlessProperty();
    //通過SPI方式獲取SpringApplicationRunListener監(jiān)聽器對(duì)象集合
		SpringApplicationRunListeners listeners = getRunListeners(args);
    //啟動(dòng)監(jiān)聽器,傳遞ApplicationStartingEvent事件
		listeners.starting();
		try {
			ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
      //environment準(zhǔn)備好之后調(diào)用監(jiān)聽器environmentPrepared方法
      //傳遞ApplicationEnvironmentPreparedEvent事件
			ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);
			configureIgnoreBeanInfo(environment);
			Banner printedBanner = printBanner(environment);
			context = createApplicationContext();
			exceptionReporters = getSpringFactoriesInstances(SpringBootExceptionReporter.class,
					new Class[] { ConfigurableApplicationContext.class }, context);
      //資源加載之前調(diào)用監(jiān)聽器的contextPrepared方法,傳遞ApplicationContextInitializedEvent事件
      //資源加載之后,refresh方法調(diào)用之前調(diào)用監(jiān)聽器的contextLoaded方法,傳遞ApplicationPreparedEvent事件
			prepareContext(context, environment, listeners, applicationArguments, printedBanner);
			refreshContext(context);
			afterRefresh(context, applicationArguments);
			stopWatch.stop();
			if (this.logStartupInfo) {
				new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), stopWatch);
			}
      //應(yīng)用程序refresh之后調(diào)用,傳遞ApplicationStartedEvent事件
			listeners.started(context);
			callRunners(context, applicationArguments);
		}
		catch (Throwable ex) {
      //應(yīng)用程序啟動(dòng)過程中出現(xiàn)異常調(diào)用failed方法
      //傳遞ApplicationFailedEvent事件
			handleRunFailure(context, ex, exceptionReporters, listeners);
			throw new IllegalStateException(ex);
		}
		try {
      //在應(yīng)用程序run方法運(yùn)行結(jié)束之前調(diào)用,傳遞ApplicationReadyEvent事件
			listeners.running(context);
		}
		catch (Throwable ex) {
			handleRunFailure(context, ex, exceptionReporters, null);
			throw new IllegalStateException(ex);
		}
		return context;
	}
	//通過SPI方式獲取SpringApplicationRunListener接口實(shí)現(xiàn)類,并創(chuàng)建SpringApplicationRunListeners集合類
	private SpringApplicationRunListeners getRunListeners(String[] args) {
		Class<?>[] types = new Class<?>[] { SpringApplication.class, String[].class };
		return new SpringApplicationRunListeners(logger,
				getSpringFactoriesInstances(SpringApplicationRunListener.class, types, this, args));
	}

spring.factories配置文件如下:

# Run Listeners
org.springframework.boot.SpringApplicationRunListener=\
org.springframework.boot.context.event.EventPublishingRunListener

到此這篇關(guān)于SpringApplicationRunListener監(jiān)聽器源碼詳解的文章就介紹到這了,更多相關(guān)SpringApplicationRunListener監(jiān)聽器內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 一步步教你如何使用Java實(shí)現(xiàn)WebSocket

    一步步教你如何使用Java實(shí)現(xiàn)WebSocket

    websocket協(xié)議是基于TCP的一種新的網(wǎng)絡(luò)協(xié)議,它實(shí)現(xiàn)了瀏覽器與服務(wù)器的全雙工通訊-允許服務(wù)器主動(dòng)發(fā)起信息個(gè)客戶端,websocket是一種持久協(xié)議,http是非持久協(xié)議,下面這篇文章主要給大家介紹了關(guān)于如何使用Java實(shí)現(xiàn)WebSocket的相關(guān)資料,需要的朋友可以參考下
    2023-05-05
  • Java MD5加密工具類的方法(支持多參數(shù)輸入)

    Java MD5加密工具類的方法(支持多參數(shù)輸入)

    在實(shí)際開發(fā)過程中,MD5加密是一種常見的數(shù)據(jù)安全處理手段,常用于密碼存儲(chǔ)、數(shù)據(jù)完整性校驗(yàn)等場(chǎng)景,這篇文章主要介紹了Java MD5加密工具類(支持多參數(shù)輸入),需要的朋友可以參考下
    2024-05-05
  • MyBatis3.X復(fù)雜Sql查詢的語句

    MyBatis3.X復(fù)雜Sql查詢的語句

    這篇文章主要介紹了MyBatis3.X復(fù)雜Sql查詢的相關(guān)資料,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-04-04
  • Mybatis中的高級(jí)映射一對(duì)一、一對(duì)多、多對(duì)多

    Mybatis中的高級(jí)映射一對(duì)一、一對(duì)多、多對(duì)多

    這篇文章主要介紹了Mybatis中的高級(jí)映射一對(duì)一、一對(duì)多、多對(duì)多的相關(guān)資料,需要的朋友可以參考下
    2016-08-08
  • java 如何讀取遠(yuǎn)程主機(jī)文件

    java 如何讀取遠(yuǎn)程主機(jī)文件

    這篇文章主要介紹了java 如何讀取遠(yuǎn)程主機(jī)文件的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2021-02-02
  • spring集成okhttp3的步驟詳解

    spring集成okhttp3的步驟詳解

    okhttp是一個(gè)封裝URL,比HttpClient更友好易用的工具,下面這篇文章主要給大家介紹了關(guān)于spring集成okhttp3的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起看看吧。
    2018-04-04
  • 基于SpringBoot實(shí)現(xiàn)HTTP請(qǐng)求簽名驗(yàn)證機(jī)制

    基于SpringBoot實(shí)現(xiàn)HTTP請(qǐng)求簽名驗(yàn)證機(jī)制

    在分布式系統(tǒng)交互中,API接口的安全性至關(guān)重要,本文將深入解析基于Spring Boot實(shí)現(xiàn)的HTTP請(qǐng)求簽名驗(yàn)證機(jī)制,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2025-04-04
  • Mybatis之#{}與${}的區(qū)別使用詳解

    Mybatis之#{}與${}的區(qū)別使用詳解

    這篇文章主要介紹了Mybatis之#{}與${}的區(qū)別詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-06-06
  • 詳解MyBatis配置typeAliases的方法

    詳解MyBatis配置typeAliases的方法

    這篇文章主要介紹了詳解MyBatis配置typeAliases的方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-10-10
  • 詳解SpringBoot Controller接收參數(shù)的幾種常用方式

    詳解SpringBoot Controller接收參數(shù)的幾種常用方式

    這篇文章主要介紹了詳解SpringBoot Controller接收參數(shù)的幾種常用方式,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-10-10

最新評(píng)論

即墨市| 合肥市| 呼图壁县| 浦北县| 祁阳县| 东港市| 巩义市| 怀来县| 上饶县| 师宗县| 会泽县| 威海市| 滦南县| 亳州市| 松桃| 东海县| 安徽省| 泾源县| 阜城县| 武安市| 宝兴县| 黎平县| 象州县| 涞源县| 理塘县| 从江县| 凤庆县| 柯坪县| 特克斯县| 教育| 桓仁| 璧山县| 曲阳县| 郓城县| 南丹县| 闻喜县| 东山县| 荆门市| 安多县| 翁源县| 潜江市|