天天看点

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

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注解的使用

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

}
           

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

继续阅读