banner
RustyNail

RustyNail

coder. 【blog】https://rustynail.me 【nostr】wss://ts.relays.world/ wss://relays.world/nostr

SpringBootの起動には何が起こっているのか。

まず最初に、SpringApplication.runメソッドがあります。このメソッドはprimary sourceを受け取り、そのソース(App.class として渡されるもの)を解析して設定をロードします。

次に、SpringApplicationを作成します。作成時に、このプロジェクトのタイプを検出します。this.webApplicationType = WebApplicationType.deduceFromClasspath();

public static ConfigurableApplicationContext run(Class<?>[] primarySources,
			String[] args) {
		return new SpringApplication(primarySources).run(args);
}

引数を渡してrun()を呼び出し、プロジェクトのタイプに基づいてConfigurableApplicationContextを作成します。

public ConfigurableApplicationContext run(String... args) {
    // タイマーを開始
		StopWatch stopWatch = new StopWatch();
		stopWatch.start();
		ConfigurableApplicationContext context = null;
		Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();
		configureHeadlessProperty();
        // このものは複数のリスナーを管理するために使用されます。作成時に、META-INF/spring.factoriesから作成するリスナーの名前を取得し、インスタンスを作成します。
		SpringApplicationRunListeners listeners = getRunListeners(args);
        // リスナーを開始
		listeners.starting();
		try {
			ApplicationArguments applicationArguments = new DefaultApplicationArguments(
					args);
            // 実行引数を作成
			ConfigurableEnvironment environment = prepareEnvironment(listeners,
					applicationArguments);
			configureIgnoreBeanInfo(environment);
            // Spring Bootのバナーを出力
			Banner printedBanner = printBanner(environment);
            // アプリケーションコンテキストを作成
			context = createApplicationContext();
            // 例外レポート
			exceptionReporters = getSpringFactoriesInstances(
					SpringBootExceptionReporter.class,
					new Class[] { ConfigurableApplicationContext.class }, context);
            // コンテキストの準備
			prepareContext(context, environment, listeners, applicationArguments,
					printedBanner);
            // コンテキストをリフレッシュ
			refreshContext(context);
			afterRefresh(context, applicationArguments);
            // タイマーを停止
			stopWatch.stop();
			if (this.logStartupInfo) {
				new StartupInfoLogger(this.mainApplicationClass)
						.logStarted(getApplicationLog(), stopWatch);
			}
			listeners.started(context);
			callRunners(context, applicationArguments);
		}
		catch (Throwable ex) {
			handleRunFailure(context, ex, exceptionReporters, listeners);
			throw new IllegalStateException(ex);
		}

		try {
			listeners.running(context);
		}
		catch (Throwable ex) {
			handleRunFailure(context, ex, exceptionReporters, null);
			throw new IllegalStateException(ex);
		}
		return context;
	}

listeners は以下の名前を使用してこれらのものを作成します:

# Application Listeners
org.springframework.context.ApplicationListener=\
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

つまり、カスタムリスナーを作成し、対応するイベントをリッスンできます。ApplicationListenerを実装するだけです。

public class MyListener implements ApplicationListener {

    @Override
    public void onApplicationEvent(ApplicationEvent event) {
        // ApplicationStartingEventをリッスン
        if (event instanceof ApplicationStartedEvent) {
            System.out.println("ApplicationStartedEventをリッスンしました");
        }

        // ApplicationEnvironmentPreparedEventをリッスン
        else if (event instanceof ApplicationEnvironmentPreparedEvent) {
            System.out.println("ApplicationEnvironmentPreparedEventをリッスンしました");
        }

        // ApplicationPreparedEventをリッスン
        else if (event instanceof ApplicationPreparedEvent) {
            System.out.println("ApplicationPreparedEventをリッスンしました");
        }

        // ApplicationReadyEventをリッスン
        else if (event instanceof ApplicationReadyEvent) {
            System.out.println("ApplicationReadyEventをリッスンしました");
        }

        // ApplicationFailedEventをリッスン
        else if (event instanceof ApplicationFailedEvent) {
            System.out.println("ApplicationFailedEventをリッスンしました");
        }
    }
}

META-INF/spring.factoriesに追加します。

org.springframework.context.ApplicationListener=\
me.dqn.listener.MyListener

これで完了です。もちろん、手動で追加することもできます。

public static void main(String[] args) {
    SpringApplication application = new SpringApplication(App.class);
    application.addListeners(new MyListener());
    application.run(args);
}
読み込み中...
文章は、創作者によって署名され、ブロックチェーンに安全に保存されています。