SpringBoot自動アセンブリの詳細な調査

モード注釈

アノテーションと呼ばれるステレオタイプアノテーションモード、Springノートにはコモンモード、、@Serviceなど@Repository@Controllerあり、@Componentコメントから「派生」します。すべての@Componentアノテーション付きクラスがSpringによってスキャンされてIOCコンテナーに含まれ、@Component派生アノテーションによってアノテーションが付けられたクラスもIOCコンテナーにスキャンされることは誰もが知っています。以下では、主にカスタムモードアノテーションによる@Component「派生」と「階層化」について理解ます

@Component "Derivative"

新しいSpringBootプロジェクトを作成します。SpringBootのバージョンは2.1.0です。RELEASE、artifactIdautoconfig、およびspring-boot-starter-web依存関係が導入されています。プロジェクトの構成は次のとおりです。

com.example.demo新しいケースannotationパッケージした後、作成しFirstLevelServiceたコメントを。

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Service
public @interface FirstLevelService {
    String value() default "";
}

この注釈は注釈によって定義されており、ソースコード@Serviceを表示@Serviceすると@Component注釈付けられていることがわかります。したがって、それらの階層関係は次のとおりです。

└─@コンポーネント
     └─@サービス
          └─@ FirstLevelService

これ@FirstLevelService@Component注釈モードから派生したものであり、クラスがIOCコンテナにスキャンできることをマークしたかどうかをテストする必要があります。

[com.example.demo新規]serviceパッケージの下でTestServiceクラスを作成します

@SecondLevelService
public class TestService {
}

ではcom.example.demo、新しいbootstrapパッケージ、その後、作成ServiceBootStrapテストレジスタのためのクラスをTestServiceし、IOCの容器からそれを入手します。

@ComponentScan("com.example.demo.service")
public class ServiceBootstrap {

    public static void main(String[] args) {
        ConfigurableApplicationContext context = new SpringApplicationBuilder(ServiceBootstrap.class)
                .web(WebApplicationType.NONE)
                .run(args);
        TestService testService = context.getBean("testService", TestService.class);
        System.out.println("TestService Bean: " + testService);
        context.close();
    }
}

このクラスのmainメソッドを実行すると、コンソール出力は次のようになります。

@Component "hierarchical"

com.example.demo.annotationパスの下に別のSecondLevelService注釈定義作成します。注釈は上記で@FirstLevelServiceマークされています

現時点では、階層関係は次のとおりです。

└─@コンポーネント
     └─@サービス
           └─@
                 FirstLevelService└─@ SecondLevelService

TestService上記のアノテーションをmainメソッドに置き換えて@SecondLevelServiceから再度実行するServiceBootStrapと、出力は次のようになります。

結果も成功していることがわかります。

ここで注意すべきことの1つは、@Componentアノテーションには1つの値属性定義しか含まれないため、その「派生」アノテーションには1つの値属性定義しか含めることができないということです。

@モジュールドライバーを有効にする

@Enableモジュールドライバーは、Spring Framework3.1以降でサポートされています。一般に、ここでのモジュールは、特定の機能を実現するためのコンポーネントのコレクションです。@Enableモジュールドライバを介して、対応するモジュール機能をオンにすることができます。

@Enableモジュールドライブは、「アノテーションドライブ」と「インターフェースプログラミング」の2つの実装モードに分けることができます。以下は、1つずつのデモです。

アノテーションドリブン

Springでは、注釈駆動型の例を@EnableWebMvcソースコードから表示できます。

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
@Documented
@Import({DelegatingWebMvcConfiguration.class})
public @interface EnableWebMvc {
}

このアノテーションは@Import、構成クラスをインポートすることによって行われますDelegatingWebMvcConfiguration

この構成クラスはWebMvcConfigurationSupport、いくつかのBean宣言を定義するそれから継承されます

したがって、アノテーション駆動型@Enableモジュールドライバは、実際に@Import構成クラスをインポートして、対応するモジュールのコンポーネント登録を実現します。これらのコンポーネントがIOCコンテナに登録されると、このモジュールの対応する機能を使用できます。

アノテーション@Enable駆動型に基づいてモジュールドライバーを定義しましょう

[com.example.demo新規]configurationパッケージの下でHelloWorldConfiguration構成クラスを作成します。

@Configuration
public class HelloWorldConfiguration {

    @Bean
    public String hello() {
        return "hello world";
    }
}

名前付きhelloBeanは、この構成クラスでcontentを使用して定義されますhello world

ではcom.example.demo.annotation次の作成EnableHelloWorldのアノテーションの定義を:

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(HelloWorldConfiguration.class)
public @interface EnableHelloWorld {
}

このアノテーション@Importクラスで作成た構成クラスインポートしました。

次に、アノテーションをテストcom.example.demo.bootstrapするための次のTestEnableBootstapスタートアップクラスを作成すると、次のよう@EnableHelloWorldになります。

@EnableHelloWorld
public class TestEnableBootstap {
    public static void main(String[] args) {
        ConfigurableApplicationContext context = new SpringApplicationBuilder(TestEnableBootstap.class)
                .web(WebApplicationType.NONE)
                .run(args);
        String hello = context.getBean("hello", String.class);
        System.out.println("hello Bean: " + hello);
        context.close();
    }
}

このクラスのmainメソッドを実行すると、コンソール出力は次のようになります。

カスタムアノテーション駆動型@EnableHelloWorldが実現可能であることを説明します

インターフェースプログラミング

上記の方法を使用することに加えて、インターフェースプログラミングによって@Enableモジュールドライブを実装することもできますSpringには、インターフェースプログラミング@EnableCaching基づく注釈があります。ソースコードを確認してください。

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import({CachingConfigurationSelector.class})
public @interface EnableCaching {
    boolean proxyTargetClass() default false;

    AdviceMode mode() default AdviceMode.PROXY;

    int order() default 2147483647;
}

EnableCachingアノテーションは、インターフェースを間接的に実装@ImportするCachingConfigurationSelectorクラスをインポートImportSelectorます。Spring コンポーネント登録の詳細な調査では 、ImportSelectorコンポーネント登録はを介して実現できることを紹介しました

したがって@Enableインターフェイスプログラミングを介してモジュール駆動を実装することの本質は、対応するモジュールの対応するコンポーネントの登録を実現するために、IOCコンテナに登録する必要があるコンポーネントを定義できる@ImportインターフェイスImportSelector実装クラスをインポートすることです。

次に、私たちはこの考えに従ってそれを再び実現するようになります:

com.example.demo新しいselectorパケットに新しいパスHelloWorldImportSelectorに実装ImportSelectorされたインタフェース:

public class HelloWorldImportSelector implements ImportSelector {
    @Override
    public String[] selectImports(AnnotationMetadata importingClassMetadata) {
        return new String[]{HelloWorldConfiguration.class.getName()};
    }
}

上記のコードの意味がわからない場合は、Springコンポーネント登録の詳細な学習に関する記事を読むことができます

次に、変更しEnableHelloWorldます。

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(HelloWorldImportSelector.class)
public @interface EnableHelloWorld {
}

上記のインポートはHelloWorldImportSelector、でありませんHelloWorldConfiguration

TestEnableBootstapmainメソッドを再度実行すると、出力が同じであることがわかります。

自動組立

Spring Bootの自動アセンブリ技術の最下層は、主に次の技術を使用しています。

  1. スプリングモードアノテーションアセンブリ

  2. Spring @ Enableモジュールアセンブリ

  3. Spring条件付きアセンブリ(Springコンポーネント登録の詳細な調査で導入

  4. スプリングファクトリローディングメカニズム

Springファクトリロードメカニズムの実装クラスはSpringFactoriesLoader次のとおりです。ソースコードを確認してください。

このクラスのメソッドは、META-INFディレクトリの下にあるspring.factories構成ファイルを読み取ります。spring-boot-autoconfigure-2.1.0.RELEASE.jarの下にあるファイルを確認します。

スタートアップクラスが@EnableAutoConfigurationマークされると、上のスクリーンショットのすべてのクラスがSpringによってスキャンされ、管理用のIOCコンテナーに含めることができるかどうかが確認されます。

たとえばorg.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration私たちが見たソースコード:

このカテゴリには、@Configurationモードアノテーション、@EnableConfigurationPropertiesモジュールアセンブリテクノロジ、ConditionalOnClass条件付きアセンブリテクノロジなどいくつかのアノテーションがマークされていることがわかります。これは、上記のSpring Boot自動アセンブリの主要な基盤技術と一致しているため、このアイデアに基づいて自動アセンブリの実装をカスタマイズできます。

新しい構成クラスを作成しますHelloWorldAutoConfiguration

@Configuration
@EnableHelloWorld
@ConditionalOnProperty(name = "helloworld", havingValue = "true")
public class HelloWorldAutoConfiguration {
}

次に、resourcesディレクトリの下に新しいMETA-INFディレクトリを作成し、spring.factoriesファイルを作成します。

#自動構成
org.springframework.boot.autoconfigure.EnableAutoConfiguration = \ 
com.example.demo.configuration.HelloWorldAutoConfiguration

次に、構成ファイルapplication.propertiesに構成を追加しhelloworld=trueます

helloworld = true

最後に作成しEnableAutoConfigurationBootstrapHelloWorldAutoConfigurationそれが機能するかどうかをテストします。

@EnableAutoConfiguration
public class EnableAutoConfigurationBootstrap {

    public static void main(String[] args) {
        ConfigurableApplicationContext context = new SpringApplicationBuilder(EnableAutoConfigurationBootstrap.class)
                .web(WebApplicationType.NONE)
                .run(args);
        String hello = context.getBean("hello", String.class);
        System.out.println("hello Bean: " + hello);
        context.close();
    }
}

mainメソッドを実行すると、コンソール出力は次のようになります。

これは、カスタマイズされた自動アセンブリが成功したことを示しています。

以下は、コードの実行ロジックの簡単な分析です。

  • Springのファクトリロードメカニズムは、META-INFディレクトリにあるspring.factoriesファイルの内容を自動的に読み取ります。

  • spring.factoriesで定義しました:
org.springframework.boot.autoconfigure.EnableAutoConfiguration = \ 
com.example.demo.configuration.HelloWorldAutoConfiguration

テストクラス@EnableAutoConfigurationでアノテーションを使用し、HelloWorldAutoConfigurationSpringによってスキャンされて要件を満たしているかどうかが確認され、要件を満たしている場合はIOCコンテナに含まれます。

  • HelloWorldAutoConfiguration@ConditionalOnProperty上記のアノテーションの機能は次のとおりです。構成ファイルで構成されている場合helloworld=true(この構成を追加したため、要件を満たしています)、このクラスはスキャンルールを満たしています。@EnableHelloWorldアノテーションは、前の例のカスタムモジュール駆動型アノテーションです。hello Beanを導入するため、helloBeanはIOCコンテナーに存在します。

  • 上記の手順により、コンテキストを介してhellobeanを取得できます。

 

おすすめ

転載: blog.csdn.net/u014225733/article/details/100836544