问题
When using Spring, is it possible to set a property only if the value passed is not null?
Example:
<bean name="myBean" class="some.Type">
<property name="abc" value="${some.param}"/>
</bean>
The behavior I'm looking for is:
some.Type myBean = new some.Type();
if (${some.param} != null) myBean.setAbc(${some.param});
The reason I need this is since abc has a default value which I don't want to override with a null.
And the Bean I am creating is not under my source control - so I cannot change its behavior. (Also, abc for this purpose might be a primitive, so I can't set it with a null anyway.
EDIT:
According to the answers I think my question requires clarification.
I have bean I need to instantiate and pass to 3rd party I use. This bean has many properties (12 currently) of various types (int, boolean, String, etc.)
Each property has a default value - I don't know what it is and would prefer not needing to know unless it becomes an issue.
What I'm looking for is a generic solution that comes from Spring's abilities - currently the only solution I have is a reflection based.
Configuration
<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>
Code
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))
{
...
}
...
}
}
The real "difficulty" is in implementing convertToValue for all possible value types.
I have done this more than once in my life - so it is not a major issue to implement it for all possible types that I need (mostly primitives and a few enums) - but I hoped a more intelligent solution existed.
回答1:
You can use SpEL and placeholder and default value for placeholder mechanisms together as following:
<bean name="myBean" class="some.Type">
<property name="abc" value="${some.param:#{null}}"/>
</bean>
回答2:
For solve your problem, you have to use SEL(Spring Expression Language). By this feature (added in SPring 3.0) you can such as other dynamic language writing your condition. For your context, answer is:
<bean name="myBean" class="some.Type">
<property name="abc" value="#(if(${some.param} != null) ${some.param})"/>
</bean>
for more information see(this tutorial says what use SEL in context file): http://static.springsource.org/spring/docs/3.0.5.RELEASE/reference/expressions.html
回答3:
You can use default value concept in property configurer in Spring framework as following:
<bean name="myBean" class="some.Type">
<property name="abc" value="${some.param : your-default-value}"/>
</bean>
you can set default value by this approach. By this context config if some.param key exist so its value set in abc property and if don't exist your-default-value set in abc property.
Note: Another benefit of this approah is:"In POJO programming model better approzh is member of class don't have any default value,and default value injected from out of class."
回答4:
You can create a Utility class that will act as a Factory class for some.Type, and wrap the logic there
For Example :
public class TypeFactory {
public static Type craeteType(SomeType param){
Type t = new Type();
if(param!=null)
t.setParam(param);
}
}
and on XML configure the bean creation using this Factory method
<bean id="myBean" class="some.Type"
factory-method="craeteType">
<constructor-arg ref="param"/>
</bean>
回答5:
This looks like a job for Java-based container configuration. You'll be able to do what you do in your XML config, but with all the power of Java.
回答6:
I've got it working with following snippet:
<bean name="myBean" class="some.Type">
<property name="abc" value="#{'${some.param}'=='' ? null : '${some.param}'}" />
</bean>
来源:https://stackoverflow.com/questions/9347929/spring-set-a-property-only-if-the-value-is-not-null