【Springおでん】Spring容器にBeaビンを登録する3つの方法を検討します.
Springを容器に登録するBeanの3つの方法を検討します.
重点的に@Importの実現の3種の方式を理解します.
前提の概要
Spring容器にBeanを登録する3つの方法@ComponentScan、@Compnet を通じて@Bean方式で @Import方式で 直接配置類を導入する Import Selector実装クラス を導入する. ImportBeanDefiniteRegistar実装クラス を導入します.
3つの方式の違いと応用シーン
@Importと@Component、@Bean方式の違い
@Component、@Beanの違い:@ComponentScan、@Componenetはコンポーネント声明とスキャンの方式を通じてBeanを登録しています.最も一般的な方法の一つで、パケットスキャン、一括声明のコンポーネントを提供しています.スキャンされたすべてのコンポーネントをSpring容器に登録してもいいです.Componentは常にクラスを修飾して一つのコンポーネントにしています.一般的には本プロジェクトで自分で定義したクラスです.このように声明します.比較的簡単です. 、@Beanは通常、@Configration(@Componentと区別されていません)を組み合わせて使用していますが、@Component方式によって宣言されているクラスで修飾方法を提供し、単一Benの登録を提供し、通常は修飾方法を用いて、この方法の返却先をSpring容量に登録します.宣言するBeanのクラスが第三者Jarパケットで宣言されている場合、このような経路は一般的には@ComponentScanのスキャン範囲内にないので、@Componentは有効ではないです.この場合@Benまたは@ImportでSpring容器 に登録できます.
@Importと他の違い:@ImportはSpring 3.0以降に提供されたもので、一つのクラスをSpring容器に素早く登録することができます.実際の開発では、モジュールの組み立てに合わせて、第三者のコンポーネント、Spring Boot自動化組立などを登録します.しかし、我々はSpringのソースコードを読むとき、これは非常に一般的です. @Import 3種方式の違い(ポイント理解)
@Import方式には三つのシードがあります.直接配置類を導入する Import Selector実装クラス を導入する. ImportBeanDefiniteRegistar実装クラス を導入します.
違い:
最初の直接配置類を導入する方式は比較的直接的で、ある種類を直接容器に登録します.Spring 3.0から提供されます.
第二の方式と第三の方式は第一の方式よりもっと柔軟で、Spring 3.1以降に提供されます.
第二の方法は、Selector実装クラスにおいて、異なるコンポーネントを条件によって登録することができ、着信パラメータのよりも、異なるコンポーネントを登録することができる.これは最初の方法と違って、直接にコンポーネントを書き終えました.
第三の方式では、より柔軟に、手動登録ビーンをサポートして、ビーンDefinite段階でコンポーネントを登録して、プログラムが走る時にビーンを動的に登録してもいいです.ビーンDefiniteに基づいて動作するので、このコンポーネントを動的に代行して、結果をSpring容器に登録してもいいです.
すなわち、第一は直接導入であり、第二は条件によって異なるビーンを登録することができ、第三は条件によって異なるビーンを登録するだけでなく、ビーンメタデータを修正して動的な修正ビーンに到達させ、修正されたビーンを容器に登録することができる.
シーン:の第一の実現は、直接的な導入プロファイルは、Springソース- を体現することができます.の第二の実施形態では、Import Selectorは、SpringBootの を表現することができる.第3の実施形態では、ImportBeanDefiniteRegistarは、Spring Cloudの を体現することができる.
三つの方式の実現
@ComponentScan、@Compnetで登録します.
パッケージスキャンとコンポーネントを通して注釈を宣言する方式は、私達が開発する中で最も一般的なビーン登録の方式です.は、一般的に、ある種類がBeaBenであることを宣言し、Spring容器に登録するために使用される . SpringBoot中@ComponentScanは、ブートクラス@Spring BootAppleの注釈において、 と宣言されています.の効果はXMLプロファイルの と同等です.
原理とは:まず、@Compnetを通じてコンポーネント類 を注釈します.その後、@ComponentScan注釈を設定し、登録が必要なコンポーネント をスキャンする.
一般的な属性名
タイプ
説明
include Filters
Filter[]
スキャン導入タイプのフィルタルールを指定します.
exclude Filters
Filter[]
スキャン排除タイプのフィルタルールを指定します.
普通は
これらの注釈はすべて@Componentコンポーネントの派生にすぎないので、名称が違う@Componentだけです.名前は標識的な役割を果たしています.本当に効果があるのは@Componentの注釈です.
@Bean方式で登録する
@Bean方式でBeanを登録するのも私達の開発でよく使われている開発方式です.@Beanは、修飾方法および注釈のために使用されてもよい. は、一般的に、@Bean修飾の方法を、このBeanを生成するためのソースと見なしている .通常、私たちも@Configrationで修飾された構成クラスの中で声明します. の効果はXMLプロファイルの と同等です.
最も一般的な使い方は:は方法でマークされ、方法の戻り値をSpring容器に登録し、種類は戻り値タイプであり、bean_idはデフォルトでは方法名 である.
たとえば
@Import方式で登録する
@Import方式の使用も頻繁で、もっと多い場合、Springフレームのソースコードを読む時に出会うことができます.にはメンバー属性が一つしかありません.クラス型変数 @Import可修飾類、注釈等… コメントから分かるように、valueは通常3つの選択肢があります.は直接に1つの構成クラス(たとえば@Configration) を指します.は、1つの を直接指す.は、 を直接指す.
リボン:@Importは、クラスや注釈などを修飾することができます. @Importは、Spring容器に直接登録される1つ以上のクラスを指定できます.これらのクラスは、他の注釈の修飾を必要としないことができます.例えば、@Configration @Importで指定されたvalue属性は大きく三つの種類に分けられます.普通の配置類、Import Selector実現類、ImportBenDefinitionRegistar実現類、後の二つはSpring 3.1後に提供されるオプション方式で、前者はSpring 3.0であり、後者は前者より柔軟な です.
@Import直接Benを導入する
第1ステップ、カスタム注釈
Import Selectorインターフェースを実現し、Beanクラス名配列に戻ります.
第1ステップ、カスタム注釈
ImportBeanDefinitionRegistarインターフェースを実現し、カスタムBean登録します.
第一歩、声明の注釈、@Importは私達のImportBeanDifinitionRegistar実現類を実行します.
私たちが知っているように、@EnbaleFeign Clients注釈はこのように実現されます.私が予想しているのは、@Feign ClientがAPIを宣言し、@EnbaleFeign Clientsが指定したregisterは@Feign Clienntのクラスを探しています.このようなBeanメタデータを修正して、動的エージェントのような感じがします.これらのアプリはシェル仕様なので、レギターはhttpを実現するために要求する機能です.
結び目の詳細は、私たちは設定クラスではありません.Import Selector実装クラス、ImportBenDefinitionRegistar実装クラスで声明@Configration、@Comppenentなどのパターンの注釈がありません. 参考資料 SpringBoot-容器に登録するBeaビンの様々な方法-著者:東京の冷えやすい ダイナミック登録bean、Spring公式コース:ImportBenDefinitionRegistar-著者:李佳明 を使用します. ImportBenDefinitionRegistarインターフェースを介してbeanの動的注入を実現する-著者:Top_Beaer
重点的に@Importの実現の3種の方式を理解します.
前提の概要
Spring容器にBeanを登録する3つの方法
3つの方式の違いと応用シーン
@Importと@Component、@Bean方式の違い
@Component、@Beanの違い:
@Importと他の違い:
@Import方式には三つのシードがあります.
違い:
最初の直接配置類を導入する方式は比較的直接的で、ある種類を直接容器に登録します.Spring 3.0から提供されます.
第二の方式と第三の方式は第一の方式よりもっと柔軟で、Spring 3.1以降に提供されます.
第二の方法は、Selector実装クラスにおいて、異なるコンポーネントを条件によって登録することができ、着信パラメータのよりも、異なるコンポーネントを登録することができる.これは最初の方法と違って、直接にコンポーネントを書き終えました.
第三の方式では、より柔軟に、手動登録ビーンをサポートして、ビーンDefinite段階でコンポーネントを登録して、プログラムが走る時にビーンを動的に登録してもいいです.ビーンDefiniteに基づいて動作するので、このコンポーネントを動的に代行して、結果をSpring容器に登録してもいいです.
すなわち、第一は直接導入であり、第二は条件によって異なるビーンを登録することができ、第三は条件によって異なるビーンを登録するだけでなく、ビーンメタデータを修正して動的な修正ビーンに到達させ、修正されたビーンを容器に登録することができる.
シーン:
@EnableWebMvc
の注釈で@EnableAutoConfiguration
注釈に@EnableFeignClients
注釈において三つの方式の実現
@ComponentScan、@Compnetで登録します.
パッケージスキャンとコンポーネントを通して注釈を宣言する方式は、私達が開発する中で最も一般的なビーン登録の方式です.
原理とは:
一般的な属性名
タイプ
説明
include Filters
Filter[]
スキャン導入タイプのフィルタルールを指定します.
exclude Filters
Filter[]
スキャン排除タイプのフィルタルールを指定します.
普通は
@Service,@Configuration,@Controller
などのモードの注釈を使っていますが、これらもこのような方式で登録されていますか?これらの注釈はすべて@Componentコンポーネントの派生にすぎないので、名称が違う@Componentだけです.名前は標識的な役割を果たしています.本当に効果があるのは@Componentの注釈です.
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Configuration {
}
例えば@Configrationのコメントを見ることができます.中には@Componeのコメントがあります.そして、特別なものはありません.@Bean方式で登録する
@Bean方式でBeanを登録するのも私達の開発でよく使われている開発方式です.
最も一般的な使い方は:
たとえば
@Configuration
public class MyConfig(){
@Bean
public String hello(){
return "hello world";
}
}
ここでは、オブジェクトはBeanとして宣言され、Spring容器に登録されたIDがハローワールドのStringオブジェクトとして生成されます.@Import方式で登録する
@Import方式の使用も頻繁で、もっと多い場合、Springフレームのソースコードを読む時に出会うことができます.
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Import {
/**
* {@link Configuration}, {@link ImportSelector}, {@link ImportBeanDefinitionRegistrar}
* or regular component classes to import.
*/
Class<?>[] value();
}
ソースから見られます.value
ImportSelector
インターフェース実装クラスImportBeanDefinitionRegistrar
実装クラスリボン:
@Import直接Benを導入する
第1ステップ、カスタム注釈
EnableHello
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(MyConfiguration.class)
public @interface EnableHello{
}
第二ステップ、カスタム設定クラスpublic class MyConfig{
}
第三ステップ、コメントを発表します.@EnableHello
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
SpringBootブートガイドのようなコンポーネントで@EnbaleHelloコメントをすることで、MyConfigの一般的な構成クラスがSpring容器に直接登録されます.Import Selectorインターフェースを実現し、Beanクラス名配列に戻ります.
第1ステップ、カスタム注釈
EnableHello
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(MyConfiguration.class)
public @interface EnableHello{
}
第二ステップ、カスタム設定クラスpublic class MyConfig{
}
第三段階、カスタムxSelector実現類public class HelloImportSelector implements ImportSelector {
@Override
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
return new String[]{
MyConfig.class.getName()};
// , com.example.demo.config.MyConfig
}
}
第三ステップ、コメントを発表します.@EnableHello
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
ここでは条件によって異なるビーンを登録していませんが、ユーザー定義の注釈には1つのvalueが定義されています.selectImports()の方法では、注釈のメタデータを取得してvalueとは何かを得ることができます.このvalueによって登録するビーンの名前配列に対応して返送することができます.ImportBeanDefinitionRegistarインターフェースを実現し、カスタムBean登録します.
第一歩、声明の注釈、@Importは私達のImportBeanDifinitionRegistar実現類を実行します.
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(MyImportBeanDefinitionRegistrar .class)
public @interface EnableHello{
}
二番目のステップは、Beanとしてのクラスを宣言しますが、登録されていません.属性nameはデフォルトでは値がありません.@Data
public class Hello {
private String name;
}
第三ステップ、カスタムImportBenDifinitionRegistar実現クラスpublic class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
// Hello BeanDefinition
BeanDefinition beanDefinition = new RootBeanDefinition(Hello.class);
// Hello
PropertyValues propertyValues = beanDefinition.getPropertyValues();
// name ,
((MutablePropertyValues) propertyValues).add("name","snailmann");
// Bean BeanDefinitionRegistry
registry.registerBeanDefinition("hello",beanDefinition);
}
}
第四ステップ、クラス宣言を起動して、ユーザー定義の注釈を付ける.@EnableHello
@SpringBootApplication
public class Demo4Application {
public static void main(String[] args) {
ApplicationContext context = SpringApplication.run(Demo4Application.class, args);
Hello hello = (Hello) context.getBean("hello");
System.out.println(hello);
}
}
出力結果は:Hello(name=jerry)
ここから、ImportBeanDifinitionRegistarの機能は最も強力であり、Selectorの機能を実現するだけでなく、運行中にBenのメタデータを動的に修正して、Beanを動的に登録することができます.私たちが知っているように、@EnbaleFeign Clients注釈はこのように実現されます.私が予想しているのは、@Feign ClientがAPIを宣言し、@EnbaleFeign Clientsが指定したregisterは@Feign Clienntのクラスを探しています.このようなBeanメタデータを修正して、動的エージェントのような感じがします.これらのアプリはシェル仕様なので、レギターはhttpを実現するために要求する機能です.
結び目