web-dev-qa-db-ja.com

Springの@Valueアノテーションで複数のプロパティ名を指定できますか?

私はすでに、Springの_@Value_アノテーションの基本動作に精通しており、次のようにフィールドをプロジェクトプロパティの値に設定しています。

プロジェクトのプロパティファイル

_foo.bar=value
_

プロジェクトの構成クラス

_@Configuration
public class MyConfig {
    @Value("${foo.bar}")
    private String myValue;
}
_

ただし、条件付き構成でSpringBootスタータープロジェクトを作成しようとしています。プロパティ名を「com.mycompany.propertygroup.propertyname」などの便利なものに標準化したいのですが、移行を容易にし、採用を促進するために、昔の古いプロパティ名も同じで、複数のプロパティ名が同じフィールドを設定できるようにする方法があるかどうか疑問に思っていましたか?例えば:

私の理論的なスターターの構成

_@Configuration
public class MyConfig {
    @Value("${com.mycompany.propertygroup.propertyname}" || "${oldconvention.property}")
    private String myValue;
}
_

プロジェクトAのプロパティ

_oldconvention.property=value
_

プロジェクトBのプロパティ

_com.mycompany.propertygroup.propertyname=value
_

ドキュメントが見つからないようであるか、SO答えが可能かどうか、および可能である場合はそれをどのように達成するかについての回答がありません。それで、可能かどうか、またはそうではありません、同じ効果を達成するために使用できる_@Value_アノテーションの代替はありますか?

明確にするために編集:複数の値を追跡したくないので、複数の値を取得する方法についての指示は必要ありません...目的は複数の名前を持つ可能性のあるSINGLE VALUEに統合します。実際には、スターターを使用するプロジェクトごとに名前値は1つしかありません...まれに、古いプロパティを削除し忘れた場合にのみ、各プロパティ名が使用されます(そして、とにかく同じ値になるでしょう) )。そのような場合、新しい規約の名前と値は[〜#〜]のみ[〜#〜]1つ使用されます。

更新

提供されたSpEL式の回答は両方のプロパティが存在する場合に機能しますが、プロパティ名の1つしか存在しない場合、アプリケーションコンテキストをロードできません。例:

更新された構成クラス

_@Value("#{'${com.mycompany.propertygroup.propertyname}' != null ? '${com.mycompany.propertygroup.propertyname}' : '${oldconvention.propertyname}'}"
private String myProperty;
_

更新されたプロパティファイル

_com.mycompany.propertygroup.propertyname=somevalue
_

エラー

_Caused by: Java.lang.IllegalArgumentException: 
Could not resolve placeholder 'oldconvention.propertyname' in value
"#{'${com.mycompany.propertygroup.propertyname}' != null ? '${com.mycompany.propertygroup.propertyname}' : '${oldconvention.propertyname}'}"
_

両方のプロパティ名の存在を要求することは目的を達成できません。これは、実装プロジェクトが古い規則OR新しい規則を使用してこのスターターを構成できるようにすることです...

別の更新...

SpEL式を少しいじってみましたが、プロパティが存在する場合と存在しない場合に条件チェックが機能しましたが、事後、プロパティの解決に問題があります。問題は、プロパティのデフォルトと複雑なSpEL式が、Niceと一緒に機能しないためだと思います。

_@Value("#{${com.mycompany.propertygroup.propertyname:null} != null ? '${com.mycompany.propertygroup.propertyname}' : '${oldconvention.propertyname}'}")
private String myProperty;
_

SpELが上記のように記述されていると、解決できないプロパティプレースホルダー例外が発生します。つまり、SpEL式を評価するには、両方のプロパティが存在する必要があります。だから私は、オプションのプロパティを解決するために見たデフォルトのプロパティ構文を使用できると考えました:@Value("${myoptionalproperty:defaultValue}")

以下は、デフォルトのプロパティ解決とSpEL式を組み合わせる私の試みです。

_@Value("#{${com.mycompany.propertygroup.propertyname:null} != null ? '${com.mycompany.propertygroup.propertyname:}' : '${oldconvention.propertyname:}'}")
private String myProperty;
_

デフォルトのプロパティ表記を使用すると、次のエラーが発生します。

_org.springframework.expression.spel.SpelParseException: 
EL1041E: After parsing a valid expression, there is still more data in the expression: 'colon(:)'
_

そして、私がそのエラーをグーグル検索したときの一般的な答えは、プロパティは文字列に評価されるように一重引用符で囲む必要があるというものでした...しかし、それらはすでにラップされています(最初のものを除いて..。私はそれをnullチェックのためにリテラルnullに評価したかったのです)。だから私はそれらがスペル式にラップされているとき、デフォルトはプロパティで使用できないと考えています。実際、_@Value_アノテーションが純粋なプロパティホルダーだけで設定されている場合にのみデフォルトプロパティセットが表示され、SpEL式で使用されているすべてのプロパティにデフォルトセットが設定されることはありません。

9
AEvans

次の@Valueアノテーションを使用できます。

@Configuration
public class MyConfig {

    @Value("#{'${com.mycompany.propertygroup.propertyname:${oldconvention.propertyname:}}'}")
    private String myValue;
}

この@Valueアノテーションは、提供されている場合はcom.mycompany.propertygroup.propertynameを使用し、oldconvention.propertyが提供されていない場合はデフォルトでcom.mycompany.propertygroup.propertynameを使用します。どちらも指定されていない場合、プロパティはnullに設定されます。 nullを別の必要な値に置き換えることにより、このデフォルトを別の値に設定できます。

詳細については、以下を参照してください。


別の方法として、両方の値をキャプチャして、値を返す前に選択を行うことができます。

@Configuration
public class MyConfig {

    @Value("${com.mycompany.propertygroup.propertyname:}")
    private String newValue;

    @Value("${oldconvention.propertyname:}")
    private String oldValue;

    public String getValue() {

        if (newValue != null && !newValue.isEmpty()) {
            // New value is provided
            System.out.println("New Value: " + newValue);
            return newValue;
        }
        else {
            // Default to the old value
            return oldValue;
       }
    }
}
7
Justin Albano

これを解決するには、SPELを使用するのが最良の方法です。これはうまくいくはずです

@Value("#{'${com.mycompany.propertygroup.propertyname}' != null ? '${com.mycompany.propertygroup.propertyname}' : '${oldconvention.property}'}")
private String myValue;
5
pvpkiran