springboot在获取配置文件内容上有两个重要的注解
- @ConfigurationProperties
- @Value
一,@ConfigurationProperties
源码
//方法和类级别上的注解
@Target({ElementType.TYPE, ElementType.METHOD})
//运行级别保留,编译后的class文件中存在,在jvm运行时保留,可以被反射调用。
@Retention(RetentionPolicy.RUNTIME)
//指明修饰的注解,可以被例如javadoc此类的工具文档化,只负责标记,没有成员取值。
@Documented
public @interface ConfigurationProperties {
// 指定前缀
@AliasFor("prefix")
String value() default "";
// 值
@AliasFor("value")
String prefix() default "";
// 是否忽略非法的属性,通常指类型不匹配,无法绑定数据到成员
boolean ignoreInvalidFields() default false;
// 是否忽略未知的属性
boolean ignoreUnknownFields() default true;
}
使用注解
//配置文件的配置项的前缀
@ConfigurationProperties(prefix = "student")
@Component
public class Student {
//相当于配置文件中的 student.stuName
private String stuName;
//相当于配置文件中的 student.stuAge
private int stuAge;
public String getStuName() {
return stuName;
}
public void setStuName(String stuName) {
this.stuName = stuName;
}
public int getStuAge() {
return stuAge;
}
public void setStuAge(int stuAge) {
this.stuAge = stuAge;
}
@Override
public String toString() {
return "Student{" +
"stuName='" + stuName + '\'' +
", stuAge=" + stuAge +
'}';
}
}
配置文件
student.stuName="kevin"
student.stuAge=18
测试类
@RunWith(SpringRunner.class)
@SpringBootTest
public class Config12019223ApplicationTests {
@Autowired
Student student;
@Test
public void contextLoads() {
System.out.println(student);
}
}
结果
注意:
- @ConfigurationProperties注解还支持松绑语法
属性名匹配原则:
@ConfigurationProperties注解支持上边三种语法取值,不严格
2.@ConfigurationProperties注解支持JSR 303配置文件数据校验,并且支持复杂数据类型(比如map)的封装取值
//配置文件的配置项的前缀
@ConfigurationProperties(prefix = "student")
@Component
//@Validated添加该注解支持数据校验
@Validated
public class Student {
//相当于配置文件中的 student.stuName
@Email //此时的stuName应该是邮件形式
private String stuName;
结果:
2.@Value
@Value也是获取配置文件值得一个注解,但是需要在要获取的属性上加上注解才能获取到值,是一个一个指定获取,不同于@ConfigurationProperties的批量获取
用法:
//配置文件的配置项的前缀
//@ConfigurationProperties(prefix = "student")
@Component
//@Validated添加该注解支持数据校验
//@Validated
public class Student {
//相当于配置文件中的 student.stuName
@Value("${student.stuName}")
private String stuName;
//相当于配置文件中的 student.stuAge
@Value("${student.stuAge}")
private int stuAge;
public String getStuName() {
return stuName;
}
public void setStuName(String stuName) {
this.stuName = stuName;
}
public int getStuAge() {
return stuAge;
}
public void setStuAge(int stuAge) {
this.stuAge = stuAge;
}
@Override
public String toString() {
return "Student{" +
"stuName='" + stuName + '\'' +
", stuAge=" + stuAge +
'}';
}
}
结果:
注意:
@Value注解 支持spel表达式:
//相当于配置文件中的 student.stuAge
@Value("#{11*2}")//还支持spel表达式
private int stuAge;
结果:
但是不支持类似@ConfigurationProperties的数据校验,也不能做复杂数据类型(比如map)的封装取值比较下两个注解的不同:
前面两个注解默认是从springboot的全局配置文件中加载的,有时候一旦配置文件多了,可能需要分开多个配置文件单独配置,这时候就需要下边两个注解来结合上边两个注解使用
@PropertySource (只用于.properties文件)读取指定配置文件
@ConfigurationProperties(prefix = "student")
@Component
@PropertySource(value = {"classpath:student.properties"})
public class Student {
private String stuName;
private int stuAge;
新建了一个配置文件:student.properties
student.stuName="cai"
student.stuAge=18
结果:
@ImportResource 导入spring的配置文件,让其生效
原因:springboot没有spring的配置文件,也不会自动识别spring的配置文件
新建一个spring的配置文件:beans.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean class="com.example.config1_2019_2_23.pojo.Manager" id="manager">
</bean>
</beans>
测试下看当前ioc容器中有没有该bean
@Autowired
ApplicationContext ioc;
@Test
public void contextLoads() {
Boolean f = ioc.containsBean("manager");
System.out.println(f);
}
结果:
加入注解后:
@ImportResource(value = {"classpath:beans.xml"})
@SpringBootApplication
public class Config12019223Application {
public static void main(String[] args) {
SpringApplication.run(Config12019223Application.class, args);
}
}
但是在springboot项目中不推荐使用这种方式,最佳方式是使用@Configuration来声明配置类