SpringBootスタートアップの基本原則の分析

pom.xml

父方の依存

親プロジェクトは主に親プロジェクトに依存しており、主にプロジェクトのリソースフィルタリングとプラグインを管理します。

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.2.5.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>

クリックして、別の親の依存関係があることを確認します


<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-dependencies</artifactId>
    <version>2.2.5.RELEASE</version>
    <relativePath>../../spring-boot-dependencies</relativePath>
</parent>

これは、SpringBootのバージョン管理センターであるSpringBootアプリケーションのすべての依存バージョンを真に管理する場所です。

将来的には、バージョンを書き込まずにデフォルトで依存関係をインポートしますが、インポートされたパッケージが依存関係で管理されていない場合は、バージョンを手動で構成する必要があります。

ランチャー


<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

springboot-boot-starter-xxx:はspring-bootのシーンスターターです

spring-boot-starter-web:通常の操作でWebモジュールが依存するコンポーネントをインポートするのを手伝ってください。

SpringBootは、すべての機能シナリオを1つのスターター(スターター)に抽出します。これらのスターターをプロジェクトに導入するだけで、関連するすべての依存関係がインポートされ、使用する関数の種類がインポートされます。シーンスターターで十分です。また、将来的には自分でスターターをカスタマイズします。

メインスタートクラス

//@SpringBootApplication 来标注一个主程序类
//说明这是一个Spring Boot应用
@SpringBootApplication
public class SpringbootApplication {
    
    

   public static void main(String[] args) {
    
    
     //以为是启动了一个方法,没想到启动了一个服务
      SpringApplication.run(SpringbootApplication.class, args);
   }

}

@SpringBootApplication

機能:特定のクラスに注釈を付けて、このクラスがSpringBootのメイン構成クラスであることを示します。SpringBootはこのクラスのmainメソッドを実行して、SpringBootアプリケーションを起動する必要があります。


@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(
    excludeFilters = {
    
    @Filter(
    type = FilterType.CUSTOM,
    classes = {
    
    TypeExcludeFilter.class}
), @Filter(
    type = FilterType.CUSTOM,
    classes = {
    
    AutoConfigurationExcludeFilter.class}
)}
)
public @interface SpringBootApplication {
    
    
    // ......
}

@ComponentScan

jは、XML構成の要素に対応します。

機能:修飾されたコンポーネントまたはBeanを自動的にスキャンしてロードし、このBean定義をIOCコンテナーにロードします

@SpringBootConfiguration

機能:特定のクラスでマークされたSpringBootの構成クラスは、これがSpringBootの構成クラスであることを示します。

引き続きこの注釈を表示して表示します

// 点进去得到下面的 @Component
@Configuration
public @interface SpringBootConfiguration {
    
    }

@Component
public @interface Configuration {
    
    }

ここでの@Configurationは、これが構成クラスであり、構成クラスがSpringに対応するxml構成ファイルであることを意味します

内部の@Componentは、スタートアップクラス自体がSpringの単なるコンポーネントであり、アプリケーションの起動を担当することを意味します

@EnableAutoConfiguration

@EnableAutoConfigurationは、自動構成機能をオンにして自動構成を有効にするようにSpringBootに指示します。
@ AutoConfigurationPackage:自動構成パッケージ

@Import({
    
    Registrar.class})
public @interface AutoConfigurationPackage {
    
    
}

@import:スプリングボトムアノテーション@import、コンポーネントをコンテナにインポートします

Registrar.class関数:メインのスタートアップクラスが配置されているパッケージ内のすべてのコンポーネントと、パッケージの下にあるすべてのサブパッケージをSpringコンテナにスキャンします。

この分析が終わったら、前のステップに戻って読み続けてください

@Import({AutoConfigurationImportSelector.class}):コンポーネントをコンテナにインポートします。

AutoConfigurationImportSelector:インポートセレクターを自動的に構成します。どのコンポーネントセレクターをインポートしますか?クリックしてこのカテゴリに移動し、ソースコードを確認します。

// 获得候选的配置
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
    
    
    //这里的getSpringFactoriesLoaderFactoryClass()方法
    //返回的就是我们最开始看的启动自动导入配置文件的注解类;EnableAutoConfiguration
    List<String> configurations = SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.getBeanClassLoader());
    Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you are using a custom packaging, make sure that file is correct.");
    return configurations;
}

メソッドが呼び出されます(SpringFactoriesLoaderクラスの静的メソッド)

SpringFactoriesLoaderクラスloadFactoryNames()メソッド

public static List<String> loadFactoryNames(Class<?> factoryClass, @Nullable ClassLoader classLoader) {
    
    
    String factoryClassName = factoryClass.getName();
    //这里它又调用了 loadSpringFactories 方法
    return (List)loadSpringFactories(classLoader).getOrDefault(factoryClassName, Collections.emptyList());
}

loadSpringFactories方法

private static Map<String, List<String>> loadSpringFactories(@Nullable ClassLoader classLoader) {
    
    
    //获得classLoader , 我们返回可以看到这里得到的就是EnableAutoConfiguration标注的类本身
    MultiValueMap<String, String> result = (MultiValueMap)cache.get(classLoader);
    if (result != null) {
    
    
        return result;
    } else {
    
    
        try {
    
    
            //去获取一个资源 "META-INF/spring.factories"
            Enumeration<URL> urls = classLoader != null ? classLoader.getResources("META-INF/spring.factories") : ClassLoader.getSystemResources("META-INF/spring.factories");
            LinkedMultiValueMap result = new LinkedMultiValueMap();

            //将读取到的资源遍历,封装成为一个Properties
            while(urls.hasMoreElements()) {
    
    
                URL url = (URL)urls.nextElement();
                UrlResource resource = new UrlResource(url);
                Properties properties = PropertiesLoaderUtils.loadProperties(resource);
                Iterator var6 = properties.entrySet().iterator();

                while(var6.hasNext()) {
    
    
                    Entry<?, ?> entry = (Entry)var6.next();
                    String factoryClassName = ((String)entry.getKey()).trim();
                    String[] var9 = StringUtils.commaDelimitedListToStringArray((String)entry.getValue());
                    int var10 = var9.length;

                    for(int var11 = 0; var11 < var10; ++var11) {
    
    
                        String factoryName = var9[var11];
                        result.add(factoryClassName, factoryName.trim());
                    }
                }
            }

            cache.put(classLoader, result);
            return result;
        } catch (IOException var13) {
    
    
            throw new IllegalArgumentException("Unable to load factories from location [META-INF/spring.factories]", var13);
        }
    }
}

複数回出現したファイルが見つかりました:sp​​ring.factories

spring.factories

spring.factoriesを開いて、多くの自動構成ファイルを確認してください。これが自動構成のルートです。

したがって、自動構成の実際の実装は、クラスパスからすべてのMETA-INF / spring.factories構成ファイルを検索し、対応するorg.springframework.boot.autoconfigure。パッケージの下の構成アイテムをリフレクションを通じて対応するアノテーションにインスタンス化することです。 @Configuration JavaConfigの形式のIOCコンテナー構成クラス。これは、インスタンスに集約され、IOCコンテナーにロードされます。

総括する

  1. SpringBootが起動すると、クラスパスの下のMETA-INF /spring.factoriesからEnableAutoConfigurationで指定された値を取得します。

  2. これらの値を自動構成クラスとしてコンテナーにインポートすると、自動構成クラスが有効になり、自動構成作業に役立ちます。

  3. J2EEの全体的なソリューションと自動構成は、springboot-autoconfigureのjarパッケージに含まれています。

  4. 多くの自動構成クラス(xxxAutoConfiguration)をコンテナーにインポートします。つまり、このシナリオに必要なすべてのコンポーネントをコンテナーにインポートし、これらのコンポーネントを構成します。

自動構成クラスを使用すると、構成インジェクション機能コンポーネントを手動で作成する作業を回避できます。

SpringApplicationクラス


@SpringBootApplication
public class SpringbootApplication {
    
    
    public static void main(String[] args) {
    
    
        SpringApplication.run(SpringbootApplication.class, args);
    }
}

SpringApplication.run分析

このメソッドの分析は、主に2つの部分に分かれています。1つはSpringApplicationのインスタンス化であり、もう1つはrunメソッドの実行です。

このクラスは主に次の4つのことを行います。

1.アプリケーションのタイプが通常のプロジェクトであるかWebプロジェクトであるかを推測します

2.使用可能なすべての初期化子を見つけてロードし、それらを初期化子プロパティに設定します

3.すべてのアプリケーションリスナーを見つけて、それらをlistenersプロパティに設定します

4. mainメソッドの定義クラスを推測して設定し、実行されるメインクラスを見つけます

1.コンストラクターを表示します。

public SpringApplication(ResourceLoader resourceLoader, Class... primarySources) {
    
    
    // ......
    this.webApplicationType = WebApplicationType.deduceFromClasspath();
    this.setInitializers(this.getSpringFactoriesInstances();
    this.setListeners(this.getSpringFactoriesInstances(ApplicationListener.class));
    this.mainApplicationClass = this.deduceMainApplicationClass();
}

2.メソッドプロセス分析を実行します

ここに画像の説明を挿入します

おすすめ

転載: blog.csdn.net/david2000999/article/details/114479288