曖昧自動組立:春のエントリー(8)

1.曖昧自動組立は何ですか?

春には、装着豆は、次の3つの方法があります。

  1. 自動組立
  2. Java設定
  3. 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つのシナリオが用意されています。

  1. 豆の最初の選択肢をマーキング
  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カスタム注釈やメモを見つけることができます。

  1. あなたは、同時に複数のカスタムノートを使用することができますが、一つだけ@Qualifierアノテーションを使用することができます
  2. 使用するカスタム注釈タイプは@Qualifierコメントよりも安全です

前記基準源と

ソースアドレス:https://github.com/zwwhnly/spring-action.git、ダウンロードして歓迎。

クレイグ・ウォルス「春の戦闘(第4版)」

5.最後に

少し宣伝を再生し、マイクロチャンネルスキャンコード番号の公衆に焦点を歓迎:私たちは一緒に進行するように、Javaテクノロジ乾燥品を共有するために定期的に「上海は見知らぬ人です」。

おすすめ

転載: www.cnblogs.com/zwwhnly/p/11355879.html