背景
Spring开发过程中经常遇到需要把特殊的值注入到成员变量里,比如普通值、文件、网址、配置信息、系统 变量等等。Spring主要使用注解@Value把对应的值注入到变量中。
常用的注入类型有以下几种:
1. 注入普通字符串。
2. 注入操作系统属性。
3. 注入表达式运算结果。
4. 注入其他bean的属性。
5. 注入文件内容。
6. 注入网址信息。
7. 注入属性文件。
示例
准备
由于例子需要读取文件和网页内容,为了方便读取,我们引入一个IO包:
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>
在rescoures下面建立一个文件夹,名称为ch2.value。
在文件夹下面建立一个test.text,内容随意,我们的内容是”测试文件”。
在文件夹下面再建立一个test.properties,内容为:
book.author = feige
book.name = spring
测试bean
新建一个用来测试的类,声明成一个bean。
@Service
public class DemoService {
@Value("我是其他属性")
private String anotherValue;
public String getAnotherValue() {
return anotherValue;
}
public void setAnotherValue(String anotherValue) {
this.anotherValue = anotherValue;
}
}
配置类
@Configuration
@ComponentScan("ch2.value")
@PropertySource("classpath:ch2/value/test.properties")
public class Config {
@Value("我是个普通字符串")
private String nornal;
@Value("#{systemEnvironment['os.name']}")
private String osName;
@Value("#{T(java.lang.Math).random()*1000.0}")
private double randomNumber;
@Value("#{demoService.anotherValue}")
private String anotherValue;
@Value("classpath:ch2/value/test.txt")
private Resource testFile;
@Value("http://www.baidu.com")
private Resource testUrl;
@Value("${book.name}")
private String bookName;
@Autowired
private Environment environment;
public void outSource(){
System.out.println(nornal);
System.out.println(osName);
System.out.println(randomNumber);
System.out.println(anotherValue);
try {
System.out.println(IOUtils.toString(testFile.getInputStream()));
System.out.println(IOUtils.toString(testUrl.getInputStream()));
}catch (Exception e){
e.printStackTrace();
}
System.out.println(bookName);
System.out.println(environment.getProperty("book.author"));
}
}
运行示例
public class Main {
public static void main(String []args){
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Config.class);
Config config = context.getBean(Config.class);
config.outSource();
}
}
目录结构
运行结果
我是个普通字符串
null
47.47599424058235
我是其他属性
测试文件
spring
14:11:10.719 [main] DEBUG org.springframework.core.env.PropertySourcesPropertyResolver - Found key 'book.author' in [class path resource [ch2/value/test.properties]] with type [String]
feige
知识点总结
@Configuration
由Configuration的注解声明的类,就相当于Spring的一个xml配置文件,通过实例化一个AnnotationConfigApplicationContext对象,引入这个配置类:
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Config.class);
AnnotationConfigApplicationContext构造方法是否可以传入多个由Configuration声明的类呢?答案是肯定的。
本示例使用的AnnotationConfigApplicationContext的构造方法如下:
public AnnotationConfigApplicationContext(Class... annotatedClasses) {
this();
this.register(annotatedClasses);
this.refresh();
}
@ComponentScan
ComponentScan注解可以传入一个包名代表扫码此包名下的所有类,把有注解声明的类加载到Spring容器中,示例@ComponentScan(“ch2.value”)会扫描包ch2.value下所有的类,把注解声明的类都加载到Spring容器中。
@PropertySource
PropertySource注解可以传入一个文件或者文件夹,此注解加载文件或者文件夹下所有的.properties文件内容到Spring的配置项里,供Value注解使用。
@Value
普通字符串
@Value("我是个普通字符串")
private String nornal;
操作系统属性
@Value("#{systemEnvironment['os.name']}")
private String osName;
操作系统的属性是静态全局变量systemEnvironment存入,可通过它获取到操作系统的属性。
表达式值
@Value("#{T(java.lang.Math).random()*1000.0}")
private double randomNumber;
表达式的对象必须是通过T()包起来,才能执行。
其他Bean的属性
@Value("#{demoService.anotherValue}")
private String anotherValue;
demoService是一个Bean对象,anotherValue是它的一个属性,可以通过@Value(“#{demoService.anotherValue}”)将这个bean的属性注入@Value声明的属性里。
注入文件资源
@Value("classpath:ch2/value/test.txt")
private Resource testFile;
通过Resource接收这个文件。
注入网页资源
@Value("http://www.baidu.com")
private Resource testUrl;
通过Resource接收这个资源。
注入配置属性
@Value("${book.name}")
private String bookName;
通过${}注入配置属性,注意不是#号,这个是和其他的不一样,另外在Spring 4中需要用property-placeholder标签把当前要注入的配置注册一下才可以使用