您现在的位置是:首页 >技术交流 >用@Value注解为bean的属性赋值网站首页技术交流
用@Value注解为bean的属性赋值
1.@Value注解
@Value注解的源码,如下所示
@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Value {
String value();
}
从@Value注解的源码中可以看出,@Value注解可以标注在字段、方法、参数以及注解上,而且在程序运行期间生效
2.@Value注解的用法
2.1.不通过配置文件注入属性的情况
通过@Value注解将外部的值动态注入到bean的属性中,一般有如下这几种情况
- 注入普通字符串
@Value("liqb") private String name; // 注入普通字符串
- 注入操作系统属性
@Value("#{systemProperties['os.name']}") private String systemPropertiesName; // 注入操作系统属性
- 注入SpEL表达式结果
@Value("#{ T(java.lang.Math).random() * 100.0 }") private double randomNumber; //注入SpEL表达式结果
- 注入其他bean中属性的值
@Value("#{person.name}") private String username; // 注入其他bean中属性的值,即注入person对象的name属性中的值
- 注入文件资源
@Value("classpath:/config.properties") private Resource resourceFile; // 注入文件资源
- 注入URL资源
@Value("http://www.baidu.com") private Resource url; // 注入URL资源
2.2.通过配置文件注入属性的情况
在项目的src/main/resources目录下新建一个属性文件,例如person.properties,其内容如下:
person.nickName=liqb
新建MainConfigOfPropertyValues配置类,在该类上使用@PropertySource注解读取外部配置文件中的key/value并保存到运行的环境变量中
package com.tianxia.springannotation.config;
import com.tianxia.springannotation.entity.Person;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
/**
* 配置类
* @author liqb
* @date 2023-05-04 11:28
**/
@Configuration
@PropertySource(value={"classpath:/person.properties"})
public class MainConfigOfPropertyValues {
@Bean
public Person person() {
return new Person();
}
}
加载完外部的配置文件以后,就可以使用${key}取出配置文件中key所对应的值,并将其注入到bean的属性中了
package com.tianxia.springannotation.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import java.io.Serializable;
/**
* Person类
* @author liqb
* @date 2023-04-21 16:00
**/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Person implements Serializable {
/**
* 姓名
*/
private String name;
/**
* 年龄
*/
private Integer age;
/**
* 昵称
*/
@Value("${person.nickName}")
private String nickName;
public Person(String name, Integer age) {
this.name = name;
this.age = age;
}
}
2.3.@Value中#{···}和${···}的区别
提供一个测试属性文件,advance_value_inject.properties,内容如下所示
server.name=server1,server2,server3
author.name=liqb
新建AdvanceValueInject类,并在该类上使用@PropertySource注解读取外部属性文件中的key/value并保存到运行的环境变量中,即加载外部的advance_value_inject.properties属性文件。
package com.tianxia.springannotation.config;
import com.tianxia.springannotation.entity.Person;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
/**
* 配置类
* @author liqb
* @date 2023-05-04 11:28
**/
@Configuration
@PropertySource(value={"classpath:/person.properties"})
public class MainConfigOfPropertyValues {
@Bean
public Person person() {
return new Person();
}
}
2.3.1.${···}的用法
{}里面的内容必须符合SpEL表达式,通过@Value(“${spelDefault.value}”)我们可以获取属性文件中对应的值,但是如果属性文件中没有这个属性,那么就会报错。不过,我们可以通过赋予默认值来解决这个问题,如下所示。
@Value("${author.name:liqb}")
private String name;
表示向bean的属性中注入属性文件中的author.name属性所对应的值,如果属性文件中没有author.name这个属性,那么便向bean的属性中注入默认值liqb。
2.3.2.#{···}的用法
{}里面的内容同样也是必须符合SpEL表达式。例如,
// SpEL:调用字符串Hello World的concat方法
@Value("#{'Hello World'.concat('!')}")
private String helloWorld;
// SpEL:调用字符串的getBytes方法,然后再调用其length属性
@Value("#{'Hello World'.bytes.length}")
private String helloWorldBytes;
2.3.3.${···}和#{···}的混合使用
${···}和#{···}可以混合使用,例如:
// SpEL:传入一个字符串,根据","切分后插入列表中, #{}和${}配合使用时,注意不能反过来${}在外面,而#{}在里面
@Value("#{'${server.name}'.split(',')}")
private List<String> severs;
上面片段的代码的执行顺序:通过**${server.name}从属性文件中获取值并进行替换,然后就变成了执行SpEL表达式{‘server1,server2,server3’.split(‘,’)}**。
2.3.4.小结
- #{···}:用于执行SpEl表达式,并将内容赋值给属性
- ${···}:主要用于加载外部属性文件中的值
- ${···}和#{···}可以混合使用,但是必须#{}在外面