SpringBoot起動プロセスの浅い分析

SpringBoot起動プロセスの浅い分析

1.スタートアップクラス

1.@SpringBootApplicationアノテーション

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
		@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
复制代码

画像-20220327122913567

自動構成プロセスについては、このブログ投稿を読むことができます

[Spring Boot]SpringBootの自動構成概略図はテキストでいっぱいです-AutumnSunsetBlog-CSDN Blog

2.メインメソッド

   public static void main(String[] args) {
        SpringApplication.run(AppTest.class, args);
    }
复制代码

ファローアップ

画像-20220327123111967

最初にメソッド宣言を見てください。静的メソッドはConfigurableApplicationContextインターフェイス実装クラスオブジェクトを返します

画像-20220327123422047

画像-20220327123612064

実装クラスとサブインターフェイスがたくさんあることがわかります。実装クラスオブジェクトをどのように選択しますか?この質問でソースコードを続けてください。

画像-20220327123733436

primarySources   //主启动类的class对象  
args   //main方法的启动参数
复制代码

ここで、新しいSpringApplicationインスタンスが作成され、runメソッドが呼び出されます。

新しいSpringApplication()

新しいSpringApplication(primarySources)メソッドでフォローアップします

public SpringApplication(Class<?>... primarySources) {
		this(null, primarySources);
	}
复制代码

新しいSpringApplicationインスタンスを作成します。アプリケーションコンテキストは、指定されたプライマリソースからBeanをロードします

工法のフォローアップを続ける

画像-20220327124335545

resourceLoader  //资源加载器   此时为null 

this.resourceLoader = resourceLoader;
复制代码
primarySources  //容器中bean的来源   此时为主启动类的字节码对象
复制代码

これは、primarySourcesをnullにすることはできない、または例外がスローされることを表明します

Assert.notNull(primarySources, "PrimarySources must not be null");
复制代码

メソッドパラメーターのprimarySourcesは可変パラメーターであり、primarySourcesはLinkedHashSetに変換されます

this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));
复制代码

LinkedHashSetセットコレクション要素は、基になるレイヤーを繰り返さないリンクリストであり、整然としたストレージを確保します

次に、このコード行を実行します

this.webApplicationType = WebApplicationType.deduceFromClasspath();
复制代码

このwebApplicationTypeとは何ですか?クリックすると、3つの列挙アイテムを含む列挙であることがわかります。

	/**
	 * The application should not run as a web application and should not start an
	 * embedded web server.
	 该应用程序不应作为 Web 应用程序运行,也不应启动嵌入式 Web 服务器。
	 */
	NONE,

	/**
	 * The application should run as a servlet-based web application and should start an
	 * embedded servlet web server.
	 应用程序应作为基于 servlet 的 Web 应用程序运行,并应启动嵌入式 servlet Web 服务器
	 */
	SERVLET,

	/**
	 * The application should run as a reactive web application and should start an
	 * embedded reactive web server.
	 该应用程序应作为响应式 Web 应用程序运行,并应启动嵌入式响应式 Web 服务器
	 */
	REACTIVE;
复制代码

画像-20220327125229813

ここで現在のプロジェクトタイプを判断すると、WebApplicationType.SERVLETが返されます。つまり、現在のSpringApplicationのタイプはWebアプリケーション、組み込みサーブレットWebサーバーです。

次にリスナーを設定します

setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
复制代码

次に、プログラムエントリを設定します

this.mainApplicationClass = deduceMainApplicationClass()
复制代码

Springコンテナがクラスオブジェクトのインスタンス化を開始します

SpringApplication.run()

次に、runメソッドが何をするか見てみましょう

画像-20220327125749885

StopWatch stopWatch = new StopWatch();   //计时器
stopWatch.start();  //开始计时
复制代码

java.awt.headlessというシステムプロパティが設定されています

configureHeadlessProperty()
复制代码

Springアプリケーションコンテキストブートストラップクラスのリスナーを取得し、

SpringApplicationRunListeners listeners = getRunListeners(args)
复制代码

フォローアップして、ApplicationStartingEventイベントを見つけて公開します

listeners.starting();
复制代码

画像-20220327131941245

SpringApplicationブートクラスに必要なパラメータをカプセル化します

ApplicationArguments applicationArguments = new DefaultApplicationArguments(args)
复制代码

環境を整える

ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);
复制代码

現在の環境に基づいて不要なBeanを無視する

configureIgnoreBeanInfo(environment);
复制代码

画像-20220327132203736

バナーを印刷

Banner printedBanner = printBanner(environment)
复制代码

ApplicationContextコンテキストを作成する前に、webApplicationTypeのタイプがSERVLETであることを確認してください。

context = createApplicationContext()
复制代码

image-20220327133346608

image-20220327133705760AnnotationConfigServletWebServerApplicationContextバイトコードオブジェクトを返し、BeanUtils.instantiateClassを呼び出してインスタンス化します

class AnnotationConfigServletWebServerApplicationContext extends ServletWebServerApplicationContext
		implements AnnotationConfigRegistry 
复制代码

ServletWebServerApplicationContextから継承されます

コンテキストを更新すると、最終的にSpringのrefreshcontainerメソッドが再利用されます

refreshContext(context);
复制代码

ConfigurableApplicationContext.refresh()メソッドを呼び出します

再调用org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext#refresh

最後に、org.springframework.context.support.AbstractApplicationContext#refreshを呼び出します

コンテナを更新する12の方法このブログ投稿をチェックしてください

[春]SpringIOCコンテナの起動プロセスと循環依存問題のソースコード分析-AutumnSunsetブログ-CSDNブログ

image-20220327132839716

image-20220327132925712

最後に、タイマーを停止してログを印刷します

        stopWatch.stop();

        if (this.logStartupInfo) {
            new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), stopWatch);
        }


复制代码

おすすめ

転載: juejin.im/post/7079651741762846733