1 @Value使用简介
1.1 简单入门
比如有下面一个类,可以利用@Value给其进行赋值
package com.nrsc.springstudy.c09_Value.beans;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import org.springframework.beans.factory.annotation.Value;
@Getter
@Setter
@ToString
public class Dog {
@Value("李四")
private String name;
@Value("#{20-2}") //SpringEl表达式
private Integer age;
private String color;
}
程序启动可以发现该对象的name和age已经被附上值了:
1.2 利用@Value读取配置文件中的值并赋值给类的属性
(1)首先建立一个配置文件
(2)在配置类中读取配置文件
package com.nrsc.springstudy.c09_Value.config;
import com.nrsc.springstudy.c09_Value.beans.Cup;
import com.nrsc.springstudy.c09_Value.beans.Dog;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
@PropertySource(value = {"classpath:/Test09Value.properties"}) //读取配置文件
@Configuration
public class C09Config {
@Bean
public Dog dog() {
return new Dog();
}
@Bean
public Cup cup() {
return new Cup();
}
}
(3)写测试类
package com.nrsc.springstudy.c09_Value.beans;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import org.springframework.beans.factory.annotation.Value;
/**
* @author : Sun Chuan
* @date : 2019/11/24 19:56
* Description:
*/
@Setter
@Getter
@ToString
public class Cup {
/***
* 直接从配置文件里读取配置内容赋值给当前属性
*/
@Value("${cup.name}")
private String name;
/***
* 通过SpringEl表达式获取dog的age值赋值给当前属性
*/
@Value("#{dog.age}")
private Integer size;
/***
* 通过SpringEl表达式获取dog的color值赋值给当前属性,如果color的值为空,则将white赋值给当前属性
*/
@Value("#{dog.color?:'white'}")
private String color;
}
测试结果如下,可以看到Cup中已经被设置了正确的值。
(1)@Value注解的作用时机在
populateBean(beanName, mbd, instanceWrapper)
方法内;
(2)处理该注解的后置处理器(BeanPostProcessor)为AutowiredAnnotationBeanPostProcessor
。了解了上面两条之后,就可以将《【bean的生命周期】— 构造方法、@Autowired、BeanPostProcessor、InitializingBean等的执行顺序解析》那篇文章里所展示的构造方法、@Autowired、BeanPostProcessor、InitializingBean等的执行顺序图,加上@Value之后画成下面的样子:
(3)@Value注解不止可以放在属性字段上,还可以放在方法、参数和注解中,其源码如下:
@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Value {
/**
* The actual value expression: e.g. "#{systemProperties.myProp}".
*/
String value();
}
(4)实际开发中可能会很少用这个注解,我现在已经要求我们项目里全部使用我之前介绍的一种方式 — 《springboot项目真实开发中如何通过yml或properties文件向项目中传值》来处理配置信息。
(5)properties被加载到了哪里??? —> 答案为环境变量里,下面做一个简单的测试
- 测试代码
import com.nrsc.springstudy.c09_Value.beans.Cup;
import com.nrsc.springstudy.c09_Value.beans.Dog;
import com.nrsc.springstudy.c09_Value.config.C09Config;
import org.junit.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.core.env.ConfigurableEnvironment;
/**
* @author : Sun Chuan
* @date : 2019/11/24 19:51
* Description:
*/
public class Test09_Value {
@Test
public void test01() {
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(C09Config.class);
Dog dog = (Dog) ac.getBean("dog");
Cup cup = (Cup) ac.getBean("cup");
System.err.println("====dog====" + dog);
System.err.println("====cup====" + cup);
//简单测试properties文件被加载到了哪里
ConfigurableEnvironment environment = ac.getEnvironment();
System.err.println("environment===" + environment.getProperty("cup.name"));
System.out.println("IOC容器创建完成........");
}
}
- 测试结果如下,可以发现从环境变量里获取到了我配置的cup.name的值 —> BigCup