​​​​​​ Springboot @Value 属性注入使用总结1:

 1、不通过配置文件的注入属性的情况

通过@Value将外部的值动态注入到Bean中,使用的情况有:

  • 注入普通字符串,配合@component注解
  • 注入操作系统属性
  • 注入表达式结果
  • 注入其他Bean属性:注入beanInject对象的属性another 通过 #{}
  • 注入文件资源
  • 注入URL资源

    详细代码见:

    @Value("normal")
    private String normal; // 注入普通字符串

    @Value("#{systemProperties['os.name']}")   #就是spel表达式的使用
    private String systemPropertiesName; // 注入操作系统属性

    @Value("#{ T(java.lang.Math).random() * 100.0 }")
    private double randomNumber; //注入表达式结果

    @Value("#{beanInject.another}")
    private String fromAnotherBean; // 注入其他Bean属性:注入beanInject对象的属性another,类具体定义见下面

    @Value("classpath:com/hry/spring/configinject/config.txt")
    private Resource resourceFile; // 注入文件资源

    @Value("http://www.baidu.com")
    private Resource testUrl; // 注入URL资源

注入其他Bean属性:注入beanInject对象的属性another

@Component
public class BeanInject {
    @Value("其他Bean的属性")
    private String another;

    public String getAnother() {
        return another;
    }

    public void setAnother(String another) {
        this.another = another;
    }
}

注入文件资源:com/hry/spring/configinject/config.txt

test configuration file

测试类:

@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

@RunWith(SpringRunner.class)
@SpringBootTest(classes=Application.class)
public class ConfiginjectApplicationTest {
    @Autowired
    private BaseValueInject baseValueInject;

    @Test
    public void baseValueInject(){
        System.out.println(baseValueInject.toString());
    }
}

运行测试类

normal=normal
systemPropertiesName=Windows 10
randomNumber=35.10603794922444
fromAnotherBean=其他Bean的属性
resourceFile=test configuration file
testUrl=<html>...<title>百度一下,你就知道</title>...略</html>




2、通过配置文件的注入属性的情况

通过@Value将外部配置文件的值动态注入到Bean中。配置文件主要有两类:

  • 1:application.properties。Spring Boot启动时默认加载application.properties文件(注意:经过测试发现springboot启动时也会加载application.yml文件,可以通过@Value("${xxx}")获取yml配置文件中的值)
  • 2:自定义属性文件。自定义属性文件通过@PropertySource加载。@PropertySource可以同时加载多个文件,也可以加载单个文件。如果相同第一个属性文件和第二属性文件存在相同key,则最后一个属性文件里的key启作用。加载文件的路径也可以配置变量,如下文的${anotherfile.configinject},此值定义在第一个属性文件config.properties

第一个属性文件config.properties内容如下:
${anotherfile.configinject}作为第二个属性文件加载路径的变量值

book.name=bookName
anotherfile.configinject=placeholder

第二个属性文件config_placeholder.properties内容如下:

book.name.placeholder=bookNamePlaceholder

下面通过@Value(“${app.name}”)语法将属性文件的值注入bean属性值,详细代码见:

@Component
// 引入外部配置文件组:${app.configinject}的值来自config.properties。
// 如果相同
@PropertySource({"classpath:com/hry/spring/configinject/config.properties",
    "classpath:com/hry/spring/configinject/config_${anotherfile.configinject}.properties"})
public class ConfigurationFileInject{
    @Value("${app.name}")
    private String appName; // 这里的值来自application.properties,
                            // spring boot启动时默认加载application.properties文件

    @Value("${book.name}")
    private String bookName; // 注入第一个配置外部文件属性

    @Value("${book.name.placeholder}")
    private String bookNamePlaceholder; // 注入第二个配置外部文件属性

    @Autowired
    private Environment env;  // 注入环境变量对象,存储注入的属性值

    public String toString(){
        StringBuilder sb = new StringBuilder();
        sb.append("bookName=").append(bookName).append("\r\n")
        .append("bookNamePlaceholder=").append(bookNamePlaceholder).append("\r\n")
        .append("appName=").append(appName).append("\r\n")
        .append("env=").append(env).append("\r\n")
        // 从eniroment中获取属性值
        .append("env=").append(env.getProperty("book.name.placeholder")).append("\r\n");
        return sb.toString();
    }   
}

测试代码:
Application.java同上文


@RunWith(SpringRunner.class)
@SpringBootTest(classes=Application.class)
public class ConfiginjectApplicationTest {
    @Autowired
    private ConfigurationFileInject configurationFileInject;

    @Test
    public void configurationFileInject(){
        System.out.println(configurationFileInject.toString());
    }
}

测试运行结果:

bookName=bookName
bookNamePlaceholder=bookNamePlaceholder
appName=appName
env=StandardEnvironment {activeProfiles=[], defaultProfiles=[default], propertySources=[Inlined Test Properties,systemProperties,systemEnvironment,random,applicationConfig: [classpath:/application.properties],class path resource [com/hry/spring/configinject/config_placeholder.properties],class path resource [com/hry/spring/configinject/config.properties]]}
env=bookNamePlaceholder

在SpringBoot项目中怎样引入.yml文件中的设置

Springboot @Value 属性注入使用总结2

在上一篇文章中Spring @Value 属性注入使用总结一我们介绍了@Value的常用方式。看完文章你可能迷惑#{..}和${}有什么区别以及如何使用。这篇文章,我们尝试解决这个问题

1.1 前提

测试属性文件:advance_value_inject.properties

server.name=server1,server2,server3
#spelDefault.value=notdefault
HelloWorld_=sss

测试类AdvanceValueInject:引入advance_value_inject.properties文件,作为属性的注入

@Component
@PropertySource({"classpath:com/hry/spring/configinject/advance_value_inject.properties"})
public class AdvanceValueInject {
...
}

1.2 #{…}和${…}

${…}用法
通过@Value(“${spelDefault.value}”)可以获取属性文件中对应的值,但是如果属性文件中没有这个属性,则会报错。可以通过赋予默认值解决这个问题,
@Value("${spelDefault.value:127.0.0.1}")

详细代码如下:

    // 如果属性文件没有spelDefault.value,则会报错
    //  @Value("${spelDefault.value}")
    //  private String spelDefault2;

    // 使用default.value设置值,如果不存在则使用默认值
    @Value("${spelDefault.value:127.0.0.1}")
    private String spelDefault;

#{…}用法
{}里面的内容必须符合SpEL表达式,详细的语法,以后可以专门开新的文章介绍,这里只演示简单用法:

    // SpEL:调用字符串Hello World的concat方法
    @Value("#{'Hello World'.concat('!')}")
    private String helloWorld;

    // SpEL: 调用字符串的getBytes方法,然后调用length属性
    @Value("#{'Hello World'.bytes.length}")
    private String helloWorldbytes;

${…}和#{…}混合使用
${...}和#{...}可以混合使用,如下文代码执行顺序:通过${server.name}从属性文件中获取值并进行替换,然后就变成了 执行SpEL表达式{‘server1,server2,server3’.split(‘,’)}。

    // SpEL: 传入一个字符串,根据","切分后插入列表中, #{}和${}配置使用(注意单引号,注意不能反过来${}在外面,#{}在里面)
    @Value("#{'${server.name}'.split(',')}")
    private List<String> servers;

在上文中在#{}外面,${}在里面可以执行成功,那么反过来是否可以呢${}在外面,#{}在里面,如代码

    // SpEL: 注意不能反过来${}在外面,#{}在里面,这个会执行失败
    @Value("${#{'HelloWorld'.concat('_')}}")
    private List<String> servers2;

答案是不能。因为spring执行${}是时机要早于#{}。在本例中,Spring会尝试从属性中查找#{‘HelloWorld’.concat(‘_’)},那么肯定找到,由上文已知如果找不到,然后报错。所以${}在外面,#{}在里面是非法操作

小结

  • #{…} 用于执行SpEl表达式,并将内容赋值给属性

  • ${…} 主要用于加载外部属性文件中的值

  • #{…} 和${…} 可以混合使用,但是必须#{}外面,${}在里面

SpringMVC @Value 属性注入使用总结3

SpringMVC时,我们使用@Value("${}") 获取配置文件的内容

通过@Value("${}") 可以获取对应属性文件中定义的属性值。假如我有一个sys.properties文件 里面规定了一组值: web.view.prefix =/WEB-INF/views/

在springMvc.xml文件中引入下面的代码既即以在 该容器内通过@Value("${web.view.prefix}")获取这个字符串。需要指出的是,如果只在springMvc.xml引入下面代码,只能在springMvc.xml文件中扫描或者注册的bean中才能通过@Value("${web.view.prefix}")获取这个字符串,其他未在springMvc.xml扫描和定义的bean必须在相应的xml文件中引入下面代码才能使用@Value("${}”)表达式

<!-- 加载配置属性文件 -->
	<context:property-placeholder
		ignore-unresolvable="true" location="classpath:sys.properties" />

然后再controller文件中通过下面代码即可获取“”/WEB-INF/views/“”这个字符串

	@Value("${web.view.prefix}")
	private String prefix; 

---------------------------------------------------------------------------------------------------------

我的博客中有下面这种用法:因为springmvc中会加载spring.xml配置文件,spring.xml中会配置properties,所以会读取到配置的proerties,可以直接这样使用:${};在springboot中就需要使用@ConfigurationProperties了。

 

springMVC_狂神_03_SSM整合(spring+springmvc+mybatis)_keep one's resolveY的博客-CSDN博客

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐