赞
踩
本文介绍了@Value各种使用方法。
可以通过@Value注解在字段上给字段赋值,@Value与bean标签中的value配置作用一致,因此用法也一致。
示例:
@Component public class Person { /** * 1. @Value类似于bean标签中的value配置; * <bean id = "person" class="xxxxx"> * <property name="address" value="xxx"></property> * </bean> * 2. bean中的value可以配置:字面量;${key}获取环境变量、配置文件中的key值,#{SpEl}spring的EL表达式; * 因此@Value也可以配置上面的三种值。 * 3. @Value获取配置信息,可以不写get/set方法。 */ @Value("小明") private String name; @Value("#{11*2}") private int age; @Value("${person.address}") private String address; private List<Object> like; private Map<String, Object> maps; private Dog dog; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } public List<Object> getLike() { return like; } public void setLike(List<Object> like) { this.like = like; } public Map<String, Object> getMaps() { return maps; } public void setMaps(Map<String, Object> maps) { this.maps = maps; } public Dog getDog() { return dog; } public void setDog(Dog dog) { this.dog = dog; } @Override public String toString() { return "Person{" + "name='" + name + '\'' + ", age=" + age + ", address='" + address + '\'' + ", like=" + like + ", maps=" + maps + ", dog=" + dog + '}'; } }
@Value在注解模式下读取配置文件注入属性值
示例:
@Value("${name}")
private String name;
但是,如果配置文件中没有设置name的值,spring在启动的时候会报错。这时需要给name配置默认值,代码如下:
@Value("${name:bob}")
private String name;
除了String类型外,其他类型也可配置默认值:
@Value("${age:18}")
private int age;
可以使用split()方法在一行中注入“列表”。
配置如下:
config.properties
server.name=hydra,zeus
server.id=100,102,103
AppConfigTest.java
package com.mkyong.analyzer.test; import java.util.List; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.PropertySource; import org.springframework.context.support.PropertySourcesPlaceholderConfigurer; @Configuration @PropertySource(value="classpath:config.properties") public class AppConfigTest { @Value("#{'${server.name}'.split(',')}") private List<String> servers; @Value("#{'${server.id}'.split(',')}") private List<Integer> serverId; //To resolve ${} in @Value @Bean public static PropertySourcesPlaceholderConfigurer propertyConfigInDev() { return new PropertySourcesPlaceholderConfigurer(); } }
可以指定默认值,下面的3种写法Spring都是支持的。
@Value("#{'${server.id:127.0.0.1,192.168.1.18}'.split(',')}")
private List<String> serverId;
@Value("${server.id:127.0.0.1,192.168.1.18}")
private List<String> serverId;
@Value("${server.id:127.0.0.1,192.168.1.18}")
private String[] serverId;
@Value("${fastdfs.cache.redis.expireTime:86400}")
public static int EXPIRE_TIME;
可以看到结果为0,没有赋值成功。
/**
* 缓存过期时间,单位秒
*/
public static int EXPIRE_TIME;
/**
*
* @param expireTime 过期时间
*/
@Value("${fastdfs.cache.redis.expireTime:86400}")
public void setExpireTime(int expireTime) {
EXPIRE_TIME = expireTime;
}
测试结果,赋值成功。
@Value("#{systemProperties['os.name']}")
private String systemPropertiesName; // 注入操作系统属性
@Value("#{person.name}")
private String username; // 注入其他bean中属性的值,即注入person对象的name属性中的值
@Value("classpath:/config.properties")
private Resource resourceFile; // 注入文件资源
@Value("http://www.baidu.com")
private Resource url; // 注入URL资源
@ConfigurationProperties | @Value | |
---|---|---|
功能 | 可以批量注入配置文件中的属性 | 只能一个个的指定 |
松散语法绑定(对象中的小驼峰命名与配置文件中-命令相互转换,比如:字段:lastName,可以在配置文件中写出last-name/last_name) | 支持 | 不支持 |
SPEL表达式(Spring 表达式) | 不支持 | 支持 |
JSR303数据校验(Java Specification Requests,JSR-303 是JAVA EE 6 中的一项子规范,叫做Bean Validation,Hibernate Validator 是 Bean Validation 的参考实现 . Hibernate Validator 提供了 JSR 303 规范中所有内置 constraint 的实现,除此之外还有一些附加的 constraint。) | 支持 | 不支持 |
复杂类型获取(对象、Map、数组) | 支持 | 不支持 |
配置文件yaml或者properties格式都行。
如果说,我们只是在某个业务逻辑中需要获取一下配置文件中的某项值,使用@Value;
如果说,我们专门编写了一个javaBean来和配置文件进行映射,我们就直接使用@ConfigurationProperties;
首先,我们可以在项目的src/main/resources目录下新建一个属性文件,例如person.properties,其内容如下:
person.nickName=美美侠
新建MainConfigOfPropertyValues配置类,并在该类上使用@PropertySource注解读取外部配置文件中的key/value并保存到运行环境时环境变量中。
package com.meimeixia.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.PropertySource; import com.meimeixia.bean.Person; @PropertySource(value={"classpath:/person.properties"}) @Configuration public class MainConfigOfPropertyValues { @Bean public Person person() { return new Person(); } }
加载完配置文件后,我们就可以使用${key}取出配置文件中key所对应的值,并将其注入到bean的属性中。
package com.meimeixia.bean; import org.springframework.beans.factory.annotation.Value; public class Person { @Value("李阿昀") private String name; @Value("#{20-2}") private Integer age; @Value("${person.nickName}") private String nickName; // 昵称 public String getNickName() { return nickName; } public void setNickName(String nickName) { this.nickName = nickName; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public Person(String name, Integer age) { super(); this.name = name; this.age = age; } public Person() { super(); // TODO Auto-generated constructor stub } @Override public String toString() { return "Person [name=" + name + ", age=" + age + ", nickName=" + nickName + "]"; } }
我们在这里提供一个测试属性文件,例如advance_value_inject.properties,大致的内容如下所示。
server.name=server1,server2,server3
author.name=liayun
然后,新建一个AdvanceValueInject类,并在该类上使用@PropertySource注解读取外部属性文件中的key/value并保存到运行的环境变量中,即加载外部的advance_value_inject.properties属性文件。
package com.meimeixia.bean;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;
@Component
@PropertySource(value={"classpath:/advance_value_inject.properties"})
public class AdvanceValueInject {
// ···
}
以上准备工作做好之后,下面我们就来看看${···}的用法。
{}里面的内容必须符合SpEL表达式,通过@Value(“${spelDefault.value}”),我们可以获取属性文件中对应的值,但是如果属性文件中没有这个属性,就会报错。不过,我们可以通过赋予默认值来解决这个问题。
@Value("${author.name:meimeixia}")
private String name;
上述代码的含义是表示向bean的属性中注入属性文件中的author.name属性所对应的值,如果属性文件中没有author.name这个属性,那么便向bean的属性中注入默认值meimeixia。
{}里面的内容同样也必须是符合SpEL表达式。
// SpEL:调用字符串Hello World的concat方法
@Value("#{'Hello World'.concat('!')}")
private String helloWorld;
// SpEL:调用字符串的getBytes方法,然后再调用其length属性
@Value("#{'Hello World'.bytes.length}")
private String helloWorldBytes;
${…}和#{…}可以混合使用,例如:
// SpEL:传入一个字符串,根据","切分后插入列表中, #{}和${}配合使用时,注意不能反过来${}在外面,而#{}在里面
@Value("#{'${server.name}'.split(',')}")
private List<String> severs;
上面片段的代码执行顺序:通过KaTeX parse error: Expected 'EOF', got '#' at position 88: …lit(',')}。 在上文中#̲{}在外面,{}在里面可以执行成功,那么反过来是否可以呢?
// SpEL:注意不能反过来,${}在外面,而#{}在里面,因为这样会执行失败
@Value("${#{'HelloWorld'.concat('_')}}")
private List<String> severs2;
答案是不能。因为Spring执行KaTeX parse error: Expected 'EOF', got '#' at position 9: {}的时机要早于#̲{},当Spring执行外层的{}时,内部的#{}为空,所以会执行失败!
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。