Spring @Primary の役割と実装原理

導入

今日はSpringの@Primaryアノテーションをシェアしたいと思います.Primaryとはメインのことです.Springを使うと必然的に同じ型のbeanが複数定義されてしまいます.ここで何かしらの対策をしないとbeanが使えなくなります.普通に使えます。

実は、私がSpringを使い始めた当初は、ある概念がよくわからなかったので、ネットでいろいろ調べてもよくわからず、中途半端なことが多かったです。 as 種類と名前に応じて bean を取得する この種類について、最初は少しわかりませんでした。

タイプまたは名前で Bean を取得する

Bean を名前で取得する方法は簡単に理解できます. Spring では Bean を定義する方法がたくさんあります. 違いは通常 @Component アノテーションと Bean を登録する @Bean アノテーションです. @Component を使用する場合は、名前を指定できます.指定なしの場合はクラス名の名前ですが、最初の文字は小文字です @Bean を使用する場合は指定も可能です 指定しない場合はメソッド名ですが、型に応じて取得します I以前はあまりよく理解していませんでした. 実際には, 型はインターフェースです. 私たちは知っています. インターフェースは一般に実装を実装しません. 実装クラスは特定のロジックを実装します. 複数の実装クラスが存在する場合があります. たとえば, UserServiceインターフェイスには UserServiceImpl1 と UserServiceImpl2 の 2 つの実装クラスがあります. すると UserServiceImpl1 と UserServiceImpl2 の型は UserService と言えます. Spring ではこの 2 つの実装クラスを Bean として定義すると Spring IOC コンテナに登録されます.入手する際の問題。

名前で

名前通りに取得できれば問題ありませんが、IOCコンテナに登録する際に名前の異なる2つのBeanが登録されているため、名前の通り1つのBeanしか取得できないため、正常に取得できます。

タイプ別

型通りに取得すると2つのbeanが登録されていますが、型は同じなので、この時型通りに直接取得すると2つのbeanが取得され、Springはそれを返すことができないので、例外がスローされます。

No qualifying bean of type 'io.steakliu.spring.ioc.annotation.primary.PrimaryService' available: expected single matching bean but found 2: primaryServiceImpl1,primaryServiceImpl2
复制代码

解決

複数の種類の Bean がある場合は、@Qualifierアノテーションを使用して名前を指定できます。また、Bean を注入するときに特定の Bean 名を指定することもできますが、これは非常にねじれたものになるため、使用する方が合理的で標準化されています。もちろん@Qualifier、また @Primary を使用することもできますが、実際には @Primary が解決できる問題は、Bean を取得するときにエラーが報告されないように、デフォルト値を与えることだけです. 同じタイプの他の Bean を注入する必要がある場合は、名前を指定する必要があります。

実現原理

@Component または @Bean アノテーションを使用して Bean を登録すると、Spring の開始後、プロジェクト パスの下のパッケージがスキャンされ、対応するクラスが検出され、対応する Bean が解析されます。以下に示すように、primary 属性が true に設定され、BeanDefinition が BeanFactory に登録されます。

Bean を取得するときは、最初にそのタイプのすべての Bean を取得し、次に Bean 名に従って BeanDefination を取得し、最後に primary 属性が true である Bean を選択して返します (同じタイプの Bean にすべて @Primary アノテーションが付けられている場合)の場合、get はエラーを報告します。

上記は @Primary のソースコードの簡単な分析です. 実際には比較的単純です. Primary は Bean 定義情報の属性です. Spring がこのアノテーションでマークされたアノテーションをスキャンすると、BeanDefinition のプライマリが設定されます. true を取得し、bean が取得できたら再度 Beandefinition を取り出し、primary 属性を判定し、取得した候補 Bean から primary が true のものを選択します。

今日の共有は以上です。ご覧いただきありがとうございます。また次回お会いしましょう!

おすすめ

転載: juejin.im/post/7219899306946150458