Spring - 仅当值不为空时才设置属性
Posted
技术标签:
【中文标题】Spring - 仅当值不为空时才设置属性【英文标题】:Spring - set a property only if the value is not null 【发布时间】:2012-03-10 00:20:46 【问题描述】:在使用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);
我需要这个的原因是因为abc
有一个我不想用null
覆盖的默认值。
而且我正在创建的 Bean 不在我的源代码控制之下——所以我无法改变它的行为。 (另外,为此目的,abc
可能是一个原语,所以无论如何我都不能将它设置为 null。
编辑: 根据答案,我认为我的问题需要澄清。
我有 bean 我需要实例化并传递给我使用的第 3 方。这个 bean 有许多不同类型的属性(目前有 12 个)(int
、boolean
、String
等)
每个属性都有一个默认值——我不知道它是什么,除非它成为一个问题,否则我宁愿不需要知道。
我正在寻找的是来自 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
。
我一生中已经不止一次这样做了——所以为我需要的所有可能的类型(主要是原语和一些枚举)实现它并不是一个主要问题——但我希望存在一个更智能的解决方案。
【问题讨论】:
【参考方案1】:您可以将SpEL
与占位符和默认值一起用于占位符机制,如下所示:
<bean name="myBean" class="some.Type">
<property name="abc" value="$some.param:#null"/>
</bean>
【讨论】:
你已经回答过一次这个问题了 :) (也有点不同) 哦,是的,但更新的答案更简单:) 这是迄今为止所有答案中最好的解决方案,谢谢1 我在尝试这个时遇到错误 --After parsing a valid expression, there is still more data in the expression: 'colon(:)'
出于某种原因,我总是得到null
值,而不管这些值是否存在于属性文件中。【参考方案2】:
为了解决您的问题,您必须使用 SEL(Spring 表达式语言)。 通过此功能(在 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
【讨论】:
如果参数为空,它不会仍然传递一个空字符串吗? OP 不想传递任何东西:他想避免调用 setter。# $some.param != #null ? $some.param : #null
似乎更正确【参考方案3】:
您可以在 Spring 框架的属性配置器中使用默认值概念,如下所示:
<bean name="myBean" class="some.Type">
<property name="abc" value="$some.param : your-default-value"/>
</bean>
您可以通过这种方法设置默认值。通过此上下文配置,如果some.param
键存在,则其值设置在abc
属性中,如果不存在your-default-value
,则设置在abc
属性中。
注意:这种方法的另一个好处是:“在 POJO 编程模型中更好的方法是类的成员没有任何默认值,并且默认值是从类外注入的。”
【讨论】:
感谢您的提示-这在将来可能会有所帮助,但就我而言,我无法使用它-正如我所说,此 bean 不在我的源代码控制中-所以我没有知道它的默认值是什么(并且不想知道)。我希望得到以下内容:<property name="abc" cond="$some.param!=null" value="$some.param">
【参考方案4】:
您可以创建一个实用程序类,它将充当some.Type
的工厂类,并在其中包装逻辑
例如:
public class TypeFactory
public static Type craeteType(SomeType param)
Type t = new Type();
if(param!=null)
t.setParam(param);
并在 XML 上使用此工厂方法配置 bean 创建
<bean id="myBean" class="some.Type"
factory-method="craeteType">
<constructor-arg ref="param"/>
</bean>
【讨论】:
【参考方案5】:这看起来像是Java-based container configuration 的工作。您将能够执行您在 XML 配置中执行的操作,但使用 Java 的所有功能。
【讨论】:
【参考方案6】:我已经让它与以下 sn-p 一起工作:
<bean name="myBean" class="some.Type">
<property name="abc" value="#'$some.param'=='' ? null : '$some.param'" />
</bean>
【讨论】:
@Ronk - 你找到解决方案了吗?我需要这样做,但我找不到解决方案。 @dharag - 我最终实现了我自己的基于反射的解决方案,使用 FactoryBean 创建我想要的对象。我发现没有内置解决方案。以上是关于Spring - 仅当值不为空时才设置属性的主要内容,如果未能解决你的问题,请参考以下文章