web-dev-qa-db-ja.com

Spring-値がnullでない場合にのみプロパティを設定します

Springを使用する場合、渡された値がnullでない場合にのみプロパティを設定することは可能ですか?

例:

<bean name="myBean" class="some.Type">
   <property name="abc" value="${some.param}"/>
</bean>

私が探している行動は:

some.Type myBean = new some.Type();
if (${some.param} != null) myBean.setAbc(${some.param});

これが必要な理由は、abcnullで上書きしたくないデフォルト値があるためです。また、私が作成しているBeanはソース管理下にないため、その動作を変更することはできません。 (また、この目的のためのabcはプリミティブである可能性があるため、とにかくnullを設定することはできません。

編集:
回答によれば、私の質問には説明が必要だと思います。

インスタンス化して、使用するサードパーティに渡す必要があるBeanがあります。このBeanには、さまざまなタイプ(intbooleanStringなど)の多くのプロパティ(現在12個)があります。
各プロパティにはデフォルト値があります-私はそれが何であるかを知りません、そしてそれが問題にならない限り知る必要がないことを望みます。私が探しているのは、Springの能力に基づく一般的なソリューションです。現在、私が持っている唯一のソリューションは、リフレクションベースです。

構成

<bean id="myBean" class="some.TypeWrapper">
   <property name="properties">
     <map>
         <entry key="abc" value="${some.value}"/>
         <entry key="xyz" value="${some.other.value}"/>
         ...
      </map>
   </property>
</bean>

コード

public class TypeWrapper
{
    private Type innerBean;

    public TypeWrapper()
    {
        this.innerBean = new Type();
    }

    public void setProperties(Map<String,String> properties)
    {
        if (properties != null)
        {
            for (Entry<String, Object> entry : properties.entrySet())
            {
                String propertyName = entry.getKey();
                Object propertyValue = entry.getValue();

                setValue(propertyName, propertyValue);
            }
        }
    }

    private void setValue(String propertyName, Object propertyValue)
    {
        if (propertyValue != null)
        {
           Method method = getSetter(propertyName);
           Object value = convertToValue(propertyValue, method.getParameterTypes()[0]);
           method.invoke(innerBean, value);
        }
    }

    private Method getSetter(String propertyName)
    {
      // Assume a valid bean, add a "set" at the beginning and toUpper the 1st character.
      // Scan the list of methods for a method with the same name, assume it is a "valid setter" (i.e. single argument)
      ... 
    }

    private Object convertToValue(String valueAsString, Class type)
    {
        // Check the type for all supported types and convert accordingly
        if (type.equals(Integer.TYPE))
        {
          ...
        }
        else if (type.equals(Integer.TYPE))
        {
          ...
        }
        ...
    }
}

本当の「難しさ」は、可能なすべての値タイプに対してconvertToValueを実装することです。私はこれを人生で2回以上行ったので、必要なすべての可能なタイプ(主にプリミティブといくつかの列挙型)に実装することは大きな問題ではありませんが、よりインテリジェントなソリューションが存在することを望みました。

24
RonK

次のように、SpELとプレースホルダーおよびプレースホルダーメカニズムのデフォルト値を一緒に使用できます。

<bean name="myBean" class="some.Type">
    <property name="abc" value="${some.param:#{null}}"/>
</bean>
34
Sam

問題を解決するには、SEL(Spring Expression Language)を使用する必要があります。この機能(SPring 3.0で追加)により、他の動的言語で条件を書き込むことができます。あなたの文脈では、答えは:

<bean name="myBean" class="some.Type">
   <property name="abc" value="#(if(${some.param} != null) ${some.param})"/>
</bean>

詳細については、(このチュートリアルではコンテキストファイルでSELを使用する方法を説明しています)を参照してください。 http://static.springsource.org/spring/docs/3.0.5.RELEASE/reference/expressions.html

5
Sam

次のように、Springフレームワークのプロパティ構成でデフォルト値の概念を使用できます。

<bean name="myBean" class="some.Type">
   <property name="abc" value="${some.param : your-default-value}"/>
</bean>

この方法でデフォルト値を設定できます。このコンテキスト構成の場合、some.paramキーが存在するため、その値はabcプロパティに設定され、存在しない場合はyour-default-valueabcプロパティに設定します。

注:このアプローチのもう1つの利点は、「POJOプログラミングモデルでは、クラスのメンバーがデフォルト値を持たず、デフォルト値がクラスの外部から挿入されたほうがよい」です。

3
Sam

some.Typeのファクトリクラスとして機能するユーティリティクラスを作成し、そこにロジックをラップすることができます

例えば ​​:

public class TypeFactory {
    public static Type craeteType(SomeType param){
        Type t = new Type();
        if(param!=null)
            t.setParam(param);
    }
}

xMLで、このFactoryメソッドを使用してBeanの作成を構成します

<bean id="myBean" class="some.Type"
      factory-method="craeteType">
    <constructor-arg ref="param"/>  
</bean>
1
Jigar Joshi

私はそれを次のスニペットで動作させています:

<bean name="myBean" class="some.Type">
    <property name="abc" value="#{'${some.param}'=='' ? null : '${some.param}'}" />
</bean>
0
volkovs

これは Javaベースのコンテナー構成 のジョブのように見えます。 XML構成で行うことを実行できますが、Javaのすべての機能を使用できます。

0
JB Nizet