1.曖昧自動組立は何ですか?
春には、装着豆は、次の3つの方法があります。
- 自動組立
- Java設定
- XML設定
これら三つのうち、自動組立が大幅に我々は、手動で豆を組み立てるために必要なコードの量を減らし、私たちに大きな利便性をもたらしました。
しかし、自動アセンブリは、万能薬ではない唯一のビーン整合条件があるため、複数のビーン整合条件が発生した場合、スプリング自動アセンブリは、達成することができ、春は、Beanが組み立てすべきか分からないであろう、スローorg.springframework.beans.factory.NoUniqueBeanDefinitionException
例外は、あります自動組立曖昧。
理解を容易にするために、我々は具体的な例を与えます。
まず、我々はインターフェイスのデザートを作成し、このインターフェイスは、唯一の方法showName()であります
package chapter03.ambiguity;
public interface Dessert {
void showName();
}
:3はインタフェースの実装クラスケーキ、クッキー、アイスクリームを定義します
package chapter03.ambiguity;
import org.springframework.stereotype.Component;
@Component
public class Cake implements Dessert {
@Override
public void showName() {
System.out.println("蛋糕");
}
}
package chapter03.ambiguity;
import org.springframework.stereotype.Component;
@Component
public class Cookies implements Dessert {
@Override
public void showName() {
System.out.println("饼干");
}
}
package chapter03.ambiguity;
import org.springframework.stereotype.Component;
@Component
public class IceCream implements Dessert {
@Override
public void showName() {
System.out.println("冰激凌");
}
}
次に、新しいクラスのデザートDessertShopを格納、クラスsetDessert()メソッドは、実施例1デザートBeanのアセンブリを必要とします。
package chapter03.ambiguity;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class DessertShop {
private Dessert dessert;
public Dessert getDessert() {
return dessert;
}
@Autowired
public void setDessert(Dessert dessert) {
this.dessert = dessert;
}
public void showDessertName() {
this.dessert.showName();
}
}
しかし、今のアセンブリの条件に沿って3つの豆、彼らの豆ID(デフォルトはクラス名の最初の文字を小文字で)それぞれこれを自動的に行い、ケーキ、クッキー、アイスクリーム、春のアセンブリを持っていますか?
この質問では、我々は最初に、新しい構成クラスAmbiguityConfigを作成します。
package chapter03.ambiguity;
import org.springframework.context.annotation.ComponentScan;
@ComponentScan
public class AmbiguityConfig {
}
このクラスの鍵は、追加することで@ComponentScan
、コメントを春には、自動的にBeanを定義されているスキャンします。
最後に、新しいクラスのメインは、そのmain()メソッドでは、次のテストコードを追加します。
package chapter03.ambiguity;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class Main {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AmbiguityConfig.class);
DessertShop dessertShop = context.getBean(DessertShop.class);
dessertShop.showDessertName();
context.close();
}
}
投げたコードを実行しorg.springframework.beans.factory.NoUniqueBeanDefinitionException
、次のように、例外を:
だから、どのようにそれの自動組立の曖昧さを解決するには?春には、次の2つのシナリオが用意されています。
- 豆の最初の選択肢をマーキング
- 修飾子
2.マークの選択の豆
今豆3一致基準があることを、我々はできる@Primary
、好適なBeanを選択します春は豆1一致基準以上のものを見つけたときように、その下に、好ましい豆であるマークに注釈を付けます。
例えば、デザートの3種類が、私はクッキーを食べるのが好き、私はクッキー好適Beanとしてマークされます:
package chapter03.ambiguity;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;
@Component
@Primary
public class Cookies implements Dessert {
@Override
public void showName() {
System.out.println("饼干");
}
}
次のように再実行するテストコード、出力結果は以下のとおりです。
ビスケット
満足なあいまいさの問題に対する解決策が、ある日、アイスクリームに誤って同僚に追加@Primary
コメントを:
package chapter03.ambiguity;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;
@Component
@Primary
public class IceCream implements Dessert {
@Override
public void showName() {
System.out.println("冰激凌");
}
}
すべてが通常のコンパイルので、注意を払っていなかったが、リリース後に実行している場合、それは次の例外がスローされます。
意味は、Beanの複数の選択肢で発見され、春にはこの時点では知らないの選択は、つまり、新しい曖昧さを持っているので、それは例外スローポットをスローします。
3.修飾子
3.1豆ID修飾子に基づいて、
春にはまた別のコメントを提供して@Qualifier
自動組立を解決するためにあいまいさの注釈を、それがであることができ@Autowired
、または@Inject
あなたは、注射時に注射したい豆を指定するために一緒に使用します。
たとえば、私たちはアイスクリームが間setDessert()メソッドのパラメータに注入入れます:
@Autowired
@Qualifier("iceCream")
public void setDessert(Dessert dessert) {
this.dessert = dessert;
}
本明細書にアイスクリームアイスクリームデフォルトクラス生成ビーンIDの転送を指します。
次のように再実行するテストコード、出力結果は以下のとおりです。
アイスクリーム
私たちは、使用することを見ることができ@Qualifier
、我々はマークの前のコメントは、@Primary
コメントは無視され、それは、と言うことです@Qualifier
より注釈付き優先順位@Primary
の高い優先順位の注釈を。
デフォルトの修飾子が問題を解決するが、いくつかの問題を導入することができる使用します。例えば、Iコード、ジェラートに変更アイスクリームクラス名をリファクタリング。
package chapter03.ambiguity;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;
@Component
@Primary
public class Gelato implements Dessert {
@Override
public void showName() {
System.out.println("冰激凌");
}
}
このとき、スローコードが示す実行しorg.springframework.beans.factory.NoSuchBeanDefinitionException
、次のように、例外を:
アイスクリームは、ジェラート、ジェラートにアイスクリームによる豆のIDの後に名前が変更されたためですが、私たちは地元のコードはまだ見つかっていない豆整合条件につながる、アイスクリームにこのBeanのIDを使用して注入します。
デフォルトの修飾子を使用して、この制限を考えると、我々はこの問題を解決するために、カスタム修飾子を使用することができます。
バッククラスのアイスクリームジェラートにコードを変更した後、テスト結果に影響を与えないでください。
予選特性に基づいて3.2
自動組立の失敗の結果として、クラス名を変更し、次のような問題を回避するために、我々は、@Qualifierとき@Componentまたは@Bean注釈文の豆にコメントを追加することができます。
package chapter03.ambiguity;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
@Component
@Qualifier("cold")
public class IceCream implements Dessert {
@Override
public void showName() {
System.out.println("冰激凌");
}
}
そして、所定の位置に注入され、もはやデフォルトで生成されたBeanのIDを使用していないが、ちょうど指定された冷たい修飾子を使用しました:
@Autowired
@Qualifier("cold")
public void setDessert(Dessert dessert) {
this.dessert = dessert;
}
テストコードを実行し、入力結果を以下に示します。
アイスクリーム
クラスアイスクリームはジェラートの名前を変更し、この時点では、コードが正常に実行することができ、影響を受けません。
そしてある日、誰かが新しいクラスポプシクルを開発しました、クラスも冷たい修飾子を使用しています。
package chapter03.ambiguity;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
@Component
@Qualifier("cold")
public class Popsicle implements Dessert {
@Override
public void showName() {
System.out.println("棒冰");
}
}
スローされます春は選択し、コードを実行する方法を知りませんでしたので、この場合も、あいまいさの新たな問題をもたらしorg.springframework.beans.factory.NoUniqueBeanDefinitionException
、次のように、例外を:
この時点で、我々は、カスタム修飾子を使用する必要があります。
3.3カスタム修飾子のアノテーション
まず、我々は、以下の3つのノートを作成します。
package chapter03.ambiguity;
import org.springframework.beans.factory.annotation.Qualifier;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.CONSTRUCTOR, ElementType.FIELD, ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Qualifier
public @interface Cold {
}
package chapter03.ambiguity;
import org.springframework.beans.factory.annotation.Qualifier;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.CONSTRUCTOR, ElementType.FIELD, ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Qualifier
public @interface Creamy {
}
package chapter03.ambiguity;
import org.springframework.beans.factory.annotation.Qualifier;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.CONSTRUCTOR, ElementType.FIELD, ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Qualifier
public @interface Fruity {
}
@Qualifierノートを定義する際にこれらの三つのノートが追加されているので、彼らは@Qualifier注釈機能があります。注意してください
次のように続いてアイスクリームのクラスが改正します:
package chapter03.ambiguity;
import org.springframework.stereotype.Component;
@Component
@Cold
@Creamy
public class IceCream implements Dessert {
@Override
public void showName() {
System.out.println("冰激凌");
}
}
次のようにポプシクルクラスが改正します:
package chapter03.ambiguity;
import org.springframework.stereotype.Component;
@Component
@Cold
@Fruity
public class Popsicle implements Dessert {
@Override
public void showName() {
System.out.println("棒冰");
}
}
それが唯一の条件を満たすために、Beanのいずれかに一致させることができるように、次のように最後に、注入の場所で、コードを変更するには:
@Autowired
@Cold
@Creamy
public void setDessert(Dessert dessert) {
this.dessert = dessert;
}
次のようにテストコードを実行し、出力結果は以下のとおりです。
アイスクリーム
したがって、我々はまた、比較は、次の2つの利点@Qualifierカスタム注釈やメモを見つけることができます。
- あなたは、同時に複数のカスタムノートを使用することができますが、一つだけ@Qualifierアノテーションを使用することができます
- 使用するカスタム注釈タイプは@Qualifierコメントよりも安全です
前記基準源と
ソースアドレス:https://github.com/zwwhnly/spring-action.git、ダウンロードして歓迎。
クレイグ・ウォルス「春の戦闘(第4版)」
5.最後に
少し宣伝を再生し、マイクロチャンネルスキャンコード番号の公衆に焦点を歓迎:私たちは一緒に進行するように、Javaテクノロジ乾燥品を共有するために定期的に「上海は見知らぬ人です」。