您的位置:首页 > 编程语言 > Java开发

SpringBoot中配置文件优先级和有哪些方式获取配置文件中的信息

2019-07-30 15:33 1356 查看
版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。 本文链接:https://blog.csdn.net/weixin_41619848/article/details/97786359

SpringBoot中配置文件优先级和有哪些方式获取配置文件中的信息

一、SpringBoot中配置文件的优先级

1、file: ./config/ (./ 表示当前路径下 file表示是当前项目)

2、file: ./

3、classpath:config/

4、classpath:

从上到下,优先级依次递减!

各配置文件之间的特性:

①: 如果配置相同的东西 如:server.port ,高优先级的文件中的配置会覆盖低优先级的文件中的配置。

②: 各文件之间是互补配置的。

参考类: ConfigFileApplicationListener

二、有哪些方式获取配置文件中的信息?

1、获取application.properties(application.yml)中的配置信息

①:通过@ConfigurationProperties 注解来获取

接口定义:

@Target({ ElementType.TYPE, ElementType.METHOD })    // 可以作用在类和方法上
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ConfigurationProperties {
@AliasFor("prefix")
String value() default "";     // 表示前缀
@AliasFor("value")
String prefix() default "";    // 表示前缀

boolean ignoreInvalidFields() default false;
boolean ignoreUnknownFields() default true;

}

使用方式:

@ConfigurationProperties(prefix = "dog")  // 指定前缀
@Component
public class Dog {

private String name;  // 自动绑定

private int age;

// 需要 对应的 setter 方法
}

配置文件信息:

dog.name=dog

dog.age=11

②:通过@Value注解来获取(value可以通过${}获取环境变量中的属性,#{}SPEL)

接口定义:

@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.ANNOTATION_TYPE})   // 可以作用在   字段、方法、参数、注解 上
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Value {
String value();
}

使用方式:

@Component
public class Dog {
@Value("${dog.name}")
private String name;

@Value("${dog.age}")
private int age;
}

配置文件信息:

dog.name=dog

dog.age=11

2、获取自定义配置文件(properties文件)中的配置信息

2.1、想要获取自定义配置文件(properties文件)中的配置信息,我们必须先加载该配置文件,通过@PropertySource注解加载

接口定义:

@Target(ElementType.TYPE)      // 只能作用在类上
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Repeatable(PropertySources.class)
public @interface PropertySource {

String name() default "";  // 表明属性资源的名称

String[] value();   // 资源文件的路径  classpath:下

boolean ignoreResourceNotFound() default false; // 不 忽略没有找到的资源
String encoding() default "";
Class<? extends PropertySourceFactory> factory() default PropertySourceFactory.class;

}

@PropertySource注解的使用

@PropertySource(value={"classpath:cat.properties"})   // 加载classpath下的cat.properties

2.2、在加载配置文件过后

①: 通过@ConfigurationProperties 注解来获取

@Component
@ConfigurationProperties(prefix = "cat")       // 指明加载配置文件的前缀
@PropertySource(value={"classpath:cat.properties"})    // 加载自定义配置文件
public class Cat {

②: 通过@Value 注解获取

@Component
@PropertySource(value={"classpath:cat.properties"})
public class Cat {
@Value("${cat.name}")
private String name;
@Value("${cat.age}")
private int age;

注意:

1、当同时通过 @ConfigurationProperties 和 @Value 去获取配置信息时: @ConfigurationProperties 生效

2、当application.properties和自定义配置文件冲突时,application.properties 生效

3、无论是application.properties,还是自定义的配置文件,在加载后,都会存放到环境对象(Environment)中去,我们也可以从环境对象中获取配置信息

public class Cat implements EnvironmentAware{
private Environment environment;
/**
* 实现 EnvironmentAware 接口,可以在 IOC创建好该 Cat对象后,自动注入 Environment对象到该cat对象中
*     于是我们可以通过操作 Environment 获取信息
* @param environment
*/
@Override
public void setEnvironment(Environment environment) {
this.environment = environment;
}
}

4、@Value 底层不依赖 setter方法和构造器,而@ConfigurationProperties底层依赖setter方法(没有对应的setter方法会赋值失败)

特性: @Value获取值和@ConfigurationProperties获取值比较

@ConfigurationProperties @Value
功能 批量注入配置文件中的属性 一个个指定
松散绑定(松散语法) 支持 不支持
SpEL #{11*2} 不支持 支持
JSR303数据校验 @Validated 支持 不支持
复杂类型封装(对象,list,set,map,数组) 支持 不支持

3、可以通过@ImportResource导入xml配置文件

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)   // 作用在类上
@Documented
public @interface ImportResource {
@AliasFor("locations")
String[] value() default {};     // 指定本地的xml配置文件的路径

@AliasFor("value")
String[] locations() default {}; // 指定本地的xml配置文件的路径

Class<? extends BeanDefinitionReader> reader() default BeanDefinitionReader.class;

}

使用方式

@ImportResource(locations = {"classpath:bean.xml","classpath:spring.xml"})
public class Person {
}

4、针对于属性为 static 、static final 、 final 的配置

1: 针对于 static 修饰的属性

static 的作用

1、static可以修饰  属性(成员变量),方法,内部类,代码块(静态代码块),还可以 静态导入。

2、static修饰的属性和方法只有一份,是属于类的,而不是对象,可以通过类名直接调用。

3、对象严格意义上是不能调用 静态方法和 静态属性的。但是我们可以通过对象调用,但不推荐。

4、静态方法不存在继承这一说法。

5、静态属性在类加载的准备阶段分配空间,并赋予默认值(比如:int 默认为 0 ,boolean 默认为 false),然后在初始化阶段赋值(如:private static int a = 10,这里的赋值就会执行a=10这个操作)和执行静态代码块。

6、static方法 只能使用static属性,调用static方法;普通方法既可以使用static属性和普通属性又可以调用static方法和普通方法
通过@Value 给静态变量赋值
@Component
public class Pig {

//    @Value("pig.name")     直接这样会赋值失败
private static String name;

@Value("${pig.name}")   // 通过作用在方法的方式将值赋给 静态属性
public void setName(String name){
Pig.name = name;
}
}
通过@ConfigurationProperties 给静态变量赋值
@ConfigurationProperties(prefix = "pig")
@Component
public class Pig {
private static String name;

/**
*  因为 @ConfigurationProperties底层依赖属性的setter方法(非静态的,如果是静态的setter方法,就会 赋值失败)
*
*  我们可以定义如下方法,来绕开static 给我们的限制
*/
public void setName(String name){
Pig.name = name;
}
}

2: 针对于 final 修饰的属性

final 的作用
1、final 可以用来修饰 {属性(成员变量)、参数、局部变量}(不可改变,对于基本类型,值不能改变;对于引用类型,地址不能改变)、方法(不可被重写)、类(不可被继承)

2、final 修饰的属性
定义时就赋值
所有构造器中给该变量赋值
代码块中给变量赋值
无法通过@ConfigurationProperties给 final 修饰的变量 (常量) 赋值,因为 @ConfigurationProperties底层依赖setter方法,而常量不能通过setter方法设置值。
通过 @Value 给 常量 赋值 (这是一种取巧的方式)
// 通过构造器 给 类中的 常量赋值 --这是OK的
public class Tiger {

private final  String name;

public Tiger(String name){
this.name = name;
}
}

​ 自定义一个java配置类

@Configuration
public class MyConfig {

/**
* 通过@Value 作用在参数上(也可作用在方法上),去获取环境变量中的配置信息
* 显示的调用 Tiger 中的 有参构造器,
*/
@Bean
public Tiger tiger(@Value("${tiger.name}") String name){
return new Tiger(name);
}

}

3: 针对于 static final 修饰的属性

不能通过@ConfigurationProperties 和 @Value 赋值, static final 修饰的变量,只能 定义时赋值 和 静态代码块中赋值

5、如果同时出现 静态属性 、常量属性 和 普通属性,我们也可以通过@Value 或者 @Value+ @ConfigurationProperties 来获取资源并赋值

1、只通过@Value 的方法

类信息:

public class Lion {

private final String name;   // 常量属性

private static int age;     // 静态属性

private String email;       // 普通属性

public Lion(String name,int age,String email){
this.name =name;
this.email =email;
Lion.age = age;
}
}

配置信息:

@Configuration
public class MyConfig {

//  通过 @Value 去环境对象中获取 配置信息,并赋给形参
@Bean
public Lion lion(@Value("${lion.name}") String name,@Value("${lion.age}")int age,@Value("${lion.email}") String email){

return new Lion(name,age,email);
}
}
2、通过 @Value + @ConfigurationProperties 的方法

类信息:

@ConfigurationProperties(prefix = "lion")
public class Lion {

private final String name;   // 常量属性

private static int age;     // 静态属性

private String email;       // 普通属性

// 构造器  初始化 常量
public Lion(String name){
this.name = name;
}

// setter 方法
public void setAge(int age){
Lion.age = age;
}
public void setEmail(String email){
this.email = email;
}

配置信息:

@Configuration
public class MyConfig {

@Bean
public Lion lion(@Value("${lion.name}") String name){
return new Lion(name);
}

}

写本文,主要是方便自己以后查看,如果有错误,请大佬们指出来! 大家共同成长!

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: