Spring Boot系列五 Spring @Value 属性注入使用总结二

本文深入探讨了Spring框架中@Value注解的高级用法,包括#{...}

1. @Value注入二

在上一篇文章中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 #{…}和${…}

${…}用法
{}里面的内容必须符合SpEL表达式,详细的语法,以后可以专门开新的文章介绍, 通过@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:调用字符串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表达式,并将内容赋值给属性
  • ${…} 主要用于加载外部属性文件中的值
  • #{…} 和${…} 可以混合使用,但是必须#{}外面,${}在里面

2. 代码

上文代码见Github

Spring Boot 项目中,可以通过 Maven 资源过滤(Resource Filtering)机制将 `pom.xml` 中定义的属性注入到应用程序中,并使用 `@Value` 注解进行读取。该方法利用了 Maven 在构建过程中将 `pom.xml` 中的属性值替换到配置文件中的能力。 ### 配置步骤 #### 1. 在 `pom.xml` 中定义属性 可以在 `pom.xml` 的 `<properties>` 部分定义自定义属性,例如: ```xml <properties> <my.custom.property>my-group-id</my.custom.property> </properties> ``` 该属性可以是任意自定义值,也可以引用已有的 `groupId`,例如: ```xml <properties> <my.group.id>${project.groupId}</my.group.id> </properties> ``` #### 2. 启用资源过滤 在 `pom.xml` 的 `build` 配置中启用资源过滤功能,确保构建过程中将属性替换到配置文件中: ```xml <build> <resources> <resource> <directory>src/main/resources</directory> <filtering>true</filtering> </resource> </resources> </build> ``` #### 3. 在 `application.properties` 中引用属性 在 `application.properties` 文件使用 `${property.name}` 语法引用 `pom.xml` 中定义的属性: ```properties app.groupId=${my.group.id} ``` #### 4. 使用 `@Value` 注解读取属性Spring Boot 应用中通过 `@Value` 注解注入属性值: ```java import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; @Component public class ProjectProperties { @Value("${app.groupId}") private String groupId; public String getGroupId() { return groupId; } } ``` 通过上述配置,Spring Boot 应用在启动时会将 `pom.xml` 中定义的属性注入到对应的字段中,从而实现对项目元信息的动态读取[^1]。 ### 示例整合 结合上述步骤,一个完整的 Spring Boot 组件可以如下所示: ```java import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; @Component public class PomPropertyInjector { @Value("${app.groupId}") private String groupId; public void printGroupId() { System.out.println("Project Group ID: " + groupId); } } ``` 在 Spring Boot 启动类中调用该组件的方法即可输出 `pom.xml` 中的 `groupId`。 ###
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值