在@Value注解中为String类型的字段设置null值

在Spring中可以使用@Valuefieldmethodmethod/constructor的参数设置缺省值。
但是,如果如何为一个字符串类型的字段设置null值呢?
下面的方法统统不对:

1
2
3
4
5
6
7
8
@Value("${app.name1:}")
private String name1;
@Value("${app.name2:''}")
private String name2;
@Value("${app.name3:null}")
private String name3;

@Value

我们先来看看@Value注解的使用方法。它主要用来为 字段 或者 方法/构造函数的参数 注入值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public static class FieldValueTestBean
@Value("#{ systemProperties[''user.region''] ?: 'zh_CN'" }")
private String defaultLocale;
@Value("${user.name}")
private String userName;
public void setDefaultLocale(String defaultLocale) {
this.defaultLocale = defaultLocale;
}
public String getDefaultLocale() {
return this.defaultLocale;
}
}

还可以放在方法上:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public static class PropertyValueTestBean
private String defaultLocale;
@Value("#{ systemProperties[''user.region''] }")
public void setDefaultLocale(String defaultLocale) {
this.defaultLocale = defaultLocale;
}
public String getDefaultLocale() {
return this.defaultLocale;
}
}

甚至构造函数上:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class MovieRecommender {
private String defaultLocale;
private CustomerPreferenceDao customerPreferenceDao;
@Autowired
public MovieRecommender(CustomerPreferenceDao customerPreferenceDao,
@Value("#{systemProperties[''user.country'']}") String defaultLocale) {
this.customerPreferenceDao = customerPreferenceDao;
this.defaultLocale = defaultLocale;
}
// ...
}

它支持两种表达方式:

  • PlaceHolder方式。 默认使用 ${...}方式,大括号内的placeholder。
  • Spring Expression Language方式。 格式为#{...}, 括号内的Spring EL表达式。 具体参考可以查看 Spring Language Reference

缺省值

如果没有placeholder或者表达式为空,我们可以提供一个缺省值。

  1. PlaceHolder方式
1
${property:default value}

例如

1
2
3
4
5
6
7
8
@Value("${mongodb.url:127.0.0.1}")
private String mongodbUrl;
@Value("#{'${mongodb.url:172.0.0.1}'}") //混合模式
private String mongodbUrl;
@Value("#{config['mongodb.url']?:'127.0.0.1'}") //混合模式+缺省值
private String mongodbUrl;

本例子摘自: mkyong

  1. Spring EL方式
1
#{expression?:default value}

例如

1
2
3
4
5
6
7
8
@Value("#{systemProperties['zookeeper.url'] ?: localhost:2181}")
private String zookeeperUrl;
@Value("#{config['mongodb.url'] ?: '127.0.0.1:27017'}")
private String mongodbUrl;
@Value("#{user.age ?: 18}")
private int age;

字符串null

如果配置的属性,我们希望设置一个null的缺省值,改怎么做呢?
两种方式:

  1. Spring EL方式
1
2
@Value("${app.name:#{null}}")
private String name;
  1. PlaceHolder方式
    这种方式需要为PlaceholderConfigurerSupport或它的子类设置属性nullValue, 比如:
1
placeholderConfigurer.setNullValue("@null");

这样字符串@null就代表null对象。
你可以

1
2
@Value("${app.name:@null}")
private String name;

也可以在属性文件中设置:

1
app.name=@null

完整的测试代码

  • App.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package com.colobu.spring;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class App {
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext("application.xml");
HelloService service = (HelloService)ctx.getBean("helloService");
service.test();
}
}
  • AppConfig.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package com.colobu.spring;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
@PropertySource("classpath:/application.properties")
@Configuration
public class AppConfig {
@Bean
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() throws Exception {
PropertySourcesPlaceholderConfigurer placeholderConfigurer = new PropertySourcesPlaceholderConfigurer();
placeholderConfigurer.setNullValue("@null");
return placeholderConfigurer;
}
}
  • HelloService.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
package com.colobu.spring;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
@Service
public class HelloService {
@Value("${app.count}")
private int num;
@Value("${app.name1:abcd}")
private String name1;
@Value("${app.name2:`abcd`}")
private String name2;
@Value("${app.name3}")
private String name3;
@Value("${app.enable}")
private boolean appEnable;
@Value("${app.name4:}")
private String name4;
@Value("${app.name5:''}")
private String name5;
@Value("${app.name6:@null}")
private String name6;
@Value("${app.name7:#{null}}")
private String name7;
@PostConstruct
public void start() {
System.out.println("start");
}
public void test(){
System.out.println("num=" + num);
System.out.println("appEnable=" + appEnable);
System.out.println("name1=" + name1);
System.out.println("name2=" + name2);
System.out.println("name3 =" + name3);
System.out.println("name4 =" + name4);
System.out.println("name5 = " + name5);
System.out.println("name6 = " + name6);
System.out.println("name7 = " + name7);
}
@PreDestroy
public void stop(){
System.out.println("stop");
}
}
  • application.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.2.xsd"
default-autowire="byType">
<context:annotation-config />
<context:component-scan base-package="com.colobu.spring"/>
<util:properties id="configProperties" location="classpath:application.properties"/>
<context:property-placeholder properties-ref="configProperties" ignore-resource-not-found="true"/>
</beans>
  • application.properties
1
2
3
app.count=0
app.name3=@null
app.enable=false