@Value("${}") 与@Value("#{}") 区别

起因

一直的用法是 @Value("${jdbc.driverClass}") 这样,但在Spring官方文档里又看到 @Value("#{a.b}")的用法。

于是研究了下。

结论

@Value的值有两类:

① ${ property : default_value }

② #{ obj.property? : default_value }

就是说,第一个注入的是外部参数对应的property,第二个则是SpEL表达式对应的内容。

那个 default_value,就是前面的值为空时的默认值。注意二者的不同。

例子

1、使用STS 新建一个Spring Boot项目,依赖部分留空。

2、在application.properties 文件中添加如下内容:

1 jdbc.driverClass=com.mysql
2 jdbc.url=3306@local
3 jdbc.user=admin
4 jdbc.pwd=pwd

3、新建类ValueDemo,内容如下:

复制代码
 1 package cn.larry.spring;
 2 
 3 import javax.annotation.PostConstruct;
 4 
 5 import org.springframework.beans.factory.annotation.Value;
 6 import org.springframework.stereotype.Component;
 7 
 8 @Component
 9 public class ValueDemo {
10     @Value("${jdbc.driverClass}")
11     private String driver;
12     
13     @PostConstruct
14     public void run(){
15         System.out.println(driver);
16     }
17 
18 }
复制代码

这就是常用的 ${ properties },很简单。继续。

4、再新建一个类AnotherObj,内容如下:

 1 package cn.larry.spring;
 2 
 3 import org.springframework.beans.factory.annotation.Value;
 4 import org.springframework.stereotype.Component;
 5 
 6 @Component
 7 public class AnotherObj {
 8     @Value("${jdbc.user}")
 9     private String name;
10     @Value("${jdbc.pwd}")
11     private String pwd;
12 
13     public String getName() {
14         return name;
15     }
16 
17     public void setName(String name) {
18         this.name = name;
19     }
20 
21     public String getPwd() {
22         return pwd;
23     }
24 
25     public void setPwd(String pwd) {
26         this.pwd = pwd;
27     }
28 
29 }
复制代码

5、修改ValueDemo,如下:

复制代码
 1 package cn.larry.spring;
 2 
 3 import javax.annotation.PostConstruct;
 4 
 5 import org.springframework.beans.factory.annotation.Value;
 6 import org.springframework.stereotype.Component;
 7 
 8 @Component
 9 public class ValueDemo {
10     @Value("${jdbc.driverClass}")
11     private String driver;
12     
13     @Value("#{anotherObj.name}")
14     private String name;
15     
16     @PostConstruct
17     public void run(){
18         System.out.println(driver);
19         System.out.println(name);
20     }
21     
22 }
复制代码


这里展示的是 #{ SpEL }的效果。

6、有意思的是,二者可以结合使用,如:#{ '${}' } ,注意单引号,注意不能反过来,测试如下。

application.properties文件中添加一行:media=jdbc.url

ValueDemo类修改如下:

复制代码
 1 package cn.larry.spring;
 2 
 3 import javax.annotation.PostConstruct;
 4 
 5 import org.springframework.beans.factory.annotation.Value;
 6 import org.springframework.stereotype.Component;
 7 
 8 @Component
 9 public class ValueDemo {
10     @Value("${jdbc.driverClass}")
11     private String driver;
12     
13     @Value("#{anotherObj.name}")
14     private String name;
15     
16 //    @Value("${ '#{anotherObj.media}' }") //这个不支持。
17     @Value("#{ '${media}' }")
18     private String media;
19     
20     @PostConstruct
21     public void run(){
22         System.out.println(driver);
23         System.out.println(name);
24         System.out.println(media);
25     }
26     
27 }
复制代码

转自:http://www.cnblogs.com/larryzeal/p/5910149.html

### 正确使用 @Value#$ 的组合方式 在编程中,`@Value` 注解主要用于 Spring 框架中的依赖注入,而 `#` 和 `$` 则分别在 SpEL(Spring Expression Language)和动态 SQL(如 MyBatis)中有特定的用途。以下是它们的详细用法和注意事项: #### 1. 使用 `@Value` 注入集合数组 `@Value` 注解可以用于注入基本类型、集合类型以及数组类型的属性值。通过逗号分隔的方式指定多个值,并结合 Spring 表达式语言(SpEL)实现复杂逻辑。 ```java @Value("${list.values}") private List<String> listValues; @Value("${array.values}") private String[] arrayValues; ``` 这里的 `${}` 是占位符语法,表示从配置文件(如 `application.properties` 或 `application.yml`)中读取对应的值[^1]。 #### 2. 在 SpEL 中使用 `#` `#` 是 SpEL 的标识符,用于引用方法参数或上下文中的变量。以下是一个示例,展示如何结合 `@Value` 和 `#` 使用: ```java @Value("#{T(java.lang.Math).random() * 100}") private double randomValue; ``` 上述代码通过 SpEL 调用了 `Math.random()` 方法,并将其结果乘以 100 后注入到 `randomValue` 属性中[^1]。 #### 3. 在 MyBatis 中使用 `$` `$` 在 MyBatis 动态 SQL 中直接替换为对应的值,不进行预编译。这使得它适用于需要拼接字符串的场景,例如 `order by` 子句。 ```sql <select id="selectStudents" resultType="Student"> SELECT * FROM students ORDER BY ${sortColumn}; </select> ``` 如果使用 `#{}`,则会导致字段名被包裹在引号中,从而引发语法错误[^2]。 #### 4. 组合使用示例 以下是一个综合示例,展示如何在 Spring 和 MyBatis 中组合使用 `@Value`、`#` 和 `$`: ##### Spring 配置 ```java @Component public class ConfigBean { @Value("#{${app.config.base} + T(java.lang.System).currentTimeMillis()}") private long dynamicTimestamp; @Value("${db.columns}") private List<String> dbColumns; } ``` - `${app.config.base}` 从配置文件中读取基础值。 - `T(java.lang.System).currentTimeMillis()` 调用系统方法生成时间戳。 - `dbColumns` 是一个从配置文件中读取的列名列表[^1]。 ##### MyBatis 查询 ```xml <select id="findRecords" resultType="Record"> SELECT ${columns} FROM records WHERE status = #{status} ORDER BY ${orderBy} </select> ``` - `${columns}` 直接替换为查询字段列表。 - `#{status}` 是预编译占位符,防止 SQL 注入。 - `${orderBy}` 替换为排序字段名[^2]。 ### 注意事项 - 使用 `$` 时需格外小心,因为它会直接将值插入 SQL 中,可能导致 SQL 注入风险。 - `#` 更安全,适用于大多数场景,尤其是需要预编译的参数。 - `@Value` 支持 SpEL,但其表达式的复杂度应适度,避免过度嵌套导致可读性下降。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值