2017-08-10 4 views
0
class ProfileCondition implements Condition { 
    @Override 
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { 
    MultiValueMap<String, Object> attrs = metadata.getAllAnnotationAttributes(Profile.class.getName()); 
    if (attrs != null) { 
     for (Object value : attrs.get("value")) { 
      if (context.getEnvironment().acceptsProfiles((String[]) value)){ 
       return true; 
      } 
     } 
     return false; 
    } 
    return true; 
} 

あなたが見ることができるように、ProfileConditionは、すべての注釈がAnnotationTypeMetadataから@Profile注釈の属性を取得します。プロファイルクラスでは、値はString[] value();と定義されています。したがって、for (Object value : attrs.get("value")は値がStringパラメータであることを意味しますが、String []型にキャストされるのはなぜですか?なぜSpringのProfileCondition.matchesメソッドが値(Object)をString []型にキャストするのですか?

+0

'value' *は' String [] 'でなければなりません。そうでなければ' ClassCastException'がスローされます。 –

答えて

0

ここで重要なのは、照会しているデータ構造を見ることです。 attrsMultiValueMapであり、キー(この場合はString)をいくつかの値(この場合はそれぞれObject)にマッピングするデータ構造です。 attrs.getは、特定のキーがマップされている値のセットを返します。したがって、attrs.getは、オブジェクトのリスト、List<Object>を返します。 "values"を照会しているので、返されるリストは単一のObjectで構成され、実際にはString[]となります。ただし、MultiValueMapには複数の異なる型の値が格納されているため、マップの値の型は共通の祖先クラス(Object)である必要があります。

要約すると、attrs.getは複数の結果を返す可能性があり、したがって繰り返し可能です。 "values"のキーの場合、戻りタイプは(効果的に)List<String[]>です。 iterableを反復処理し、forループの繰り返しごとにvalueString[]であり、そのようにダウンキャストされています。

+0

ありがとう、私は 'MultiValueMap 'の 'Object'を最初に混乱させました。今、私は 'Object'が' String [] 'ではなく" muti map value "であることを認識しました。しかし、私はまだ 'getAllAnnotationAttributes'メソッドがいくつかのキーがmuti値をマップするマップを返す理由を混乱させました。確かに、 'Profile'アノテーションクラスに" value "という名前のフィールドが複数あるとは限りません。 – cassia

+0

ドキュメントから: "この亜種は属性の上書きを考慮に入れていないことに注意してください。"したがって、オーバーライドを考慮して単一の属性を返す代わりに、属性のすべての定義を返します。 – colavitam

関連する問題