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

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

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

前言

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

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

1.SpringApplicationRunListener接口源碼

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

public interface SpringApplicationRunListener {
	/**
	 * 當(dāng)run方法第一次啟動時立即調(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)用程序已啟動,但是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)用時,在run方法完成之前立即調(diào)用。
	 * @param context the application context.
	 * @since 2.0.0
	 */
	default void running(ConfigurableApplicationContext context) {
	}
	/**
	 * 在運行應(yīng)用程序時發(fā)生故障時調(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接口唯一實現(xiàn)類EventPublishingRunListener

public class EventPublishingRunListener implements SpringApplicationRunListener, Ordered {
	//啟動類實例對象
	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)聽器助手屬性對象中
		for (ApplicationListener<?> listener : application.getListeners()) {
			this.initialMulticaster.addApplicationListener(listener);
		}
	}
}

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

//監(jiān)聽器對象集合
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接口實現(xiàn)類集合類SpringApplicationRunListeners

class SpringApplicationRunListeners {

	private final Log log;
	//存儲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對象

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

public ConfigurableApplicationContext run(String... args) {
		StopWatch stopWatch = new StopWatch();
		stopWatch.start();
		ConfigurableApplicationContext context = null;
		Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();
		configureHeadlessProperty();
    //通過SPI方式獲取SpringApplicationRunListener監(jiān)聽器對象集合
		SpringApplicationRunListeners listeners = getRunListeners(args);
    //啟動監(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)用程序啟動過程中出現(xiàn)異常調(diào)用failed方法
      //傳遞ApplicationFailedEvent事件
			handleRunFailure(context, ex, exceptionReporters, listeners);
			throw new IllegalStateException(ex);
		}
		try {
      //在應(yīng)用程序run方法運行結(jié)束之前調(diào)用,傳遞ApplicationReadyEvent事件
			listeners.running(context);
		}
		catch (Throwable ex) {
			handleRunFailure(context, ex, exceptionReporters, null);
			throw new IllegalStateException(ex);
		}
		return context;
	}
	//通過SPI方式獲取SpringApplicationRunListener接口實現(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)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

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

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

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

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

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

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

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

    Mybatis中的高級映射一對一、一對多、多對多

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

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

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

    spring集成okhttp3的步驟詳解

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

    基于SpringBoot實現(xiàn)HTTP請求簽名驗證機制

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

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

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

    詳解MyBatis配置typeAliases的方法

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

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

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

最新評論

亚东县| 扶绥县| 会泽县| 文山县| 盖州市| 澄迈县| 桐柏县| 山丹县| 吉木萨尔县| 泰宁县| 邹城市| 嘉鱼县| 南陵县| 贡山| 扬中市| 晋宁县| 菏泽市| 金门县| 滦平县| 澄江县| 大余县| 娱乐| 阜南县| 抚州市| 抚远县| 宁南县| 彭水| 米易县| 花莲市| 敖汉旗| 上虞市| 石家庄市| 拉萨市| 缙云县| 石家庄市| 蚌埠市| 叶城县| 边坝县| 房产| 芜湖县| 永修县|