背景

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();
    }
}

目录结构

springvalidate 正整数校验 spring value_spring

运行结果

我是个普通字符串
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标签把当前要注入的配置注册一下才可以使用