モード注釈
アノテーションと呼ばれるステレオタイプアノテーションモード、Springノートにはコモンモード、、@Service
など@Repository
が@Controller
あり、@Component
コメントから「派生」します。すべての@Component
アノテーション付きクラスがSpringによってスキャンされてIOCコンテナーに含まれ、@Component
派生アノテーションによってアノテーションが付けられたクラスもIOCコンテナーにスキャンされることは誰もが知っています。以下では、主にカスタムモードアノテーションによる@Component
「派生」と「階層化」について理解します。
@Component "Derivative"
新しいSpringBootプロジェクトを作成します。SpringBootのバージョンは2.1.0です。RELEASE、artifactId
autoconfig、および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";
}
}
名前付きhello
Beanは、この構成クラスで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
。
TestEnableBootstap
mainメソッドを再度実行すると、出力が同じであることがわかります。
自動組立
Spring Bootの自動アセンブリ技術の最下層は、主に次の技術を使用しています。
-
スプリングモードアノテーションアセンブリ
-
Spring @ Enableモジュールアセンブリ
-
Spring条件付きアセンブリ(Springコンポーネント登録の詳細な調査で導入)
-
スプリングファクトリローディングメカニズム
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
最後に作成しEnableAutoConfigurationBootstrap
、HelloWorldAutoConfiguration
それが機能するかどうかをテストします。
@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
でアノテーションを使用し、HelloWorldAutoConfiguration
Springによってスキャンされて要件を満たしているかどうかが確認され、要件を満たしている場合はIOCコンテナに含まれます。
-
HelloWorldAutoConfiguration
@ConditionalOnProperty
上記のアノテーションの機能は次のとおりです。構成ファイルで構成されている場合helloworld=true
(この構成を追加したため、要件を満たしています)、このクラスはスキャンルールを満たしています。@EnableHelloWorld
アノテーションは、前の例のカスタムモジュール駆動型アノテーションです。hello Beanを導入するため、helloBeanはIOCコンテナーに存在します。 -
上記の手順により、コンテキストを介してhellobeanを取得できます。