点击上方“Java知音”,选择“置顶公众号”
技术文章第一时间送达!
关于注入数据说明
1.不通过配置文件注入数据
通过@Value将外部的值动态注入到Bean中,使用的情况有:
辅助代码
package com.hannpang.model;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component(value = "st")//对student进行实例化操作
public class Student {
@Value("悟空")
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
测试@Value的代码
package com.hannpang.model;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.Resource;
import org.springframework.stereotype.Component;
@Component
public class SimpleObject {
@Value("注入普通字符串")
private String normal;
//关于属性的KEY可以查看System类说明
@Value("#{systemProperties['java.version']}")//--使用了SpEL表达式
private String systemPropertiesName; // 注入操作系统属性
@Value("#{T(java.lang.Math).random()*80}")//获取随机数
private double randomNumber; //注入表达式结果
@Value("#{1+2}")
private double sum; //注入表达式结果 1+2的求和
@Value("classpath:os.yaml")
private Resource resourceFile; // 注入文件资源
@Value("http://www.baidu.com")
private Resource testUrl; // 注入URL资源
@Value("#{st.name}")
private String studentName;
//省略getter和setter方法
@Override
public String toString() {
return "SimpleObject{" +
"normal='" + normal + ''' +
", systemPropertiesName='" + systemPropertiesName + ''' +
", randomNumber=" + randomNumber +
", sum=" + sum +
", resourceFile=" + resourceFile +
", testUrl=" + testUrl +
", studentName='" + studentName + ''' +
'}';
}
}
Spring的测试代码
package com.hannpang;
import com.hannpang.model.SimpleObject;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@SpringBootTest
public class Demo04BootApplicationTests {
@Autowired
private SimpleObject so;
@Test
public void contextLoads() {
System.out.println(so);
}
}
运行结果为:SimpleObject{normal=’注入普通字符串’, systemPropertiesName=’1.8.0_172’, randomNumber=56.631954541947266, sum=3.0, resourceFile=class path resource [os.yaml], testUrl=URL [http://www.baidu.com], studentName=’悟空’}
2.通过配置文件注入数据
通过@Value将外部配置文件的值动态注入到Bean中。配置文件主要有两类:
application.properties、application.yaml application.properties在spring boot启动时默认加载此文件
自定义属性文件。自定义属性文件通过@PropertySource加载。@PropertySource可以同时加载多个文件,也可以加载单个文件。如果相同第一个属性文件和第二属性文件存在相同key,则最后一个属性文件里的key起作用。加载文件的路径也可以配置变量,如下文的
${anotherfile.configinject}
,此值定义在第一个属性文件config.properties
在application.properties中加入如下测试代码
app.name=一步教育
在resources下面新建第一个属性文件config.properties内容如下
book.name=西游记
anotherfile.configinject=system
在resources下面新建第二个属性文件config_system.properties内容如下
我的目的是想system的值使用第一个属性文件中定义的值
book.name.author=吴承恩
下面通过
@Value(“${app.name}”)
语法将属性文件的值注入bean属性值,详细代码见:
package com.hannpang.test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;
@Component
@PropertySource(value = {"classpath:config.properties","classpath:config_${anotherfile.configinject}.properties"})
public class LoadPropsTest {
@Value("${app.name}")
private String appName; // 这里的值来自application.properties,spring boot启动时默认加载此文件
@Value("${book.name}")
private String bookName; // 注入第一个配置外部文件属性
@Value("${book.name.author}")
private String author; // 注入第二个配置外部文件属性
@Autowired
private Environment env; // 注入环境变量对象,存储注入的属性值
//省略getter和setter方法
public void setAuthor(String author) {
this.author = author;
}
@Override
public String toString(){
StringBuilder sb = new StringBuilder();
sb.append("bookName=").append(bookName).append("rn")
.append("author=").append(author).append("rn")
.append("appName=").append(appName).append("rn")
.append("env=").append(env).append("rn")
// 从eniroment中获取属性值
.append("env=").append(env.getProperty("book.name.author")).append("rn");
return sb.toString();
}
}
测试代码
package com.hannpang;
import com.hannpang.model.SimpleObject;
import com.hannpang.test.LoadPropsTest;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@SpringBootTest
public class Demo04BootApplicationTests {
@Autowired
private LoadPropsTest lpt;
@Test
public void loadPropertiesTest() {
System.out.println(lpt);
}
}
运行结果为: bookName=西游记 author=吴承恩 appName=一步教育 env=StandardEnvironment {activeProfiles=[], defaultProfiles=[default], propertySources=[ConfigurationPropertySourcesPropertySource {name='configurationProperties'}, MapPropertySource {name='Inlined Test Properties'}, MapPropertySource {name='systemProperties'}, OriginAwareSystemEnvironmentPropertySource {name='systemEnvironment'}, RandomValuePropertySource {name='random'}, OriginTrackedMapPropertySource {name='applicationConfig: [classpath:/application.properties]'}, ResourcePropertySource {name='class path resource [config_system.properties]'}, ResourcePropertySource {name='class path resource [config.properties]'}]} env=吴承恩
3. #{…}和${…}的区别演示
A.${…}的用法
{}里面的内容必须符合SpEL表达式,通过
@Value(“${app.name}”)
可以获取属性文件中对应的值,但是如果属性文件中没有这个属性,则会报错。可以通过赋予默认值解决这个问题,如
@Value("${app.name:胖先森}")
部分代码
// 如果属性文件没有app.name,则会报错
// @Value("${app.name}")
// private String name;
// 使用app.name设置值,如果不存在则使用默认值
@Value("${app.name:胖先森}")
private String name;
B.#{…}的用法
部分代码直接演示
// SpEL:调用字符串Hello World的concat方法
@Value("#{'Hello World'.concat('!')}")
private String helloWorld;
// SpEL: 调用字符串的getBytes方法,然后调用length属性
@Value("#{'Hello World'.bytes.length}")
private String helloWorldbytes;
C.#{…}和${…}混合使用
${...}
和
#{...}
可以混合使用,如下文代码执行顺序:通过
${server.name}
从属性文件中获取值并进行替换,然后就变成了 执行SpEL表达式
{‘server1,server2,server3’.split(‘,’)}
。
// SpEL: 传入一个字符串,根据","切分后插入列表中, #{}和${}配置使用(注意单引号,注意不能反过来${}在外面,#{}在里面)
@Value("#{'${server.name}'.split(',')}")
private ListString servers;
在上文中在
#{}
外面,
${}
在里面可以执行成功,那么反过来是否可以呢
${}
在外面,
#{}
在里面,如代码
```
// SpEL: 注意不能反过来${}在外面,#{}在里面,这个会执行失败
@Value(“$