前往小程序,Get更优阅读体验!
立即前往
发布
社区首页 >专栏 >SpringBoot读取配置文件的6种方式,包括:通过Environment、@PropertySource、@ConfigurationProperties、

SpringBoot读取配置文件的6种方式,包括:通过Environment、@PropertySource、@ConfigurationProperties、

原创
作者头像
刘大猫
发布2024-11-05 22:24:16
发布2024-11-05 22:24:16
8570
举报
文章被收录于专栏:Spring及SpringBoot相关

@toc

概述:本文从读取默认配置文件即自定义配置文件入手,去整理了解几种加载方案的区别SpringBoot读取配置文件的几种方式

  1. 测试方式1:通过Environment读取配置信息
  2. 测试方式2:通过@Value注解读取配置信息(推荐使用)
  3. 测试方式3:通过@ConfigurationProperties注解读取配置信息
  4. 测试方式4:通过@PropertySource+@Value注解读取配置信息
  5. 测试方式5:通过@PropertySource+@ConfigurationProperties注解读取配置信息
  6. 测试方式6:通过Properties读取配置信息

总结

结论:无论什么场景都推荐使用@Value注解准备错;其他了解即可。

准备工作

配置文件目录

application.properties

代码语言:java
复制
server.port=8080
spring.profiles.active=dev

application-dev.properties

代码语言:java
复制
spring.redis.host=localhost
logging.level.root = info

application-prod.properties

代码语言:java
复制
spring.redis.port=6379
logging.level.root = warn

my.properties

代码语言:java
复制
demo.name=cat

案例说明

1)测试方式1:通过Environment读取配置信息

注意点说明:

<font color='red'>注意点1:</font>

Environment是用来读取应用程序运行时的环境变量的类,可以通过key-value的方式读取application.properties和系统环境变量,命令行输入参数,系统属性等.

Controller

代码语言:java
复制
import com.example.demo.config.ReadProperties;
import com.example.demo.config.ReadProperties2;
import com.example.demo.config.ReadProperties3;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.env.Environment;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PropertiesLoaderUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

/**
 * 测试读取配置文件的几种方式:
 * @Author 211145187
 * @Date 2022/7/20 14:02
 **/
@RestController
public class ReadApplicationProperties {
    @Autowired
    private Environment environment;
    
	//测试方式1:通过Environment读取配置信息
    @GetMapping("/readApplicationProperties1")
    public Map<String,Object> readApplicationProperties1(){
        Map<String,Object> map = new HashMap<>();
        map.put("port",environment.getProperty("server.port"));
        System.out.println("通过Environment读取配置信息:" + environment.getProperty("server.port"));
        return  map;
    }
}

结果打印:

2)测试方式2:通过@Value注解读取配置信息(推荐使用)

Controller

代码语言:java
复制
import com.example.demo.config.ReadProperties;
import com.example.demo.config.ReadProperties2;
import com.example.demo.config.ReadProperties3;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.env.Environment;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PropertiesLoaderUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

/**
 * 测试读取配置文件的几种方式:
 * @Author 211145187
 * @Date 2022/7/20 14:02
 **/
@RestController
public class ReadApplicationProperties {
    @Value("${server.port}")
    private Integer serverPort;

	//测试方式2:通过@Value注解读取配置信息
    @GetMapping("/readApplicationProperties2")
    public void readApplicationProperties2(){
        System.out.println("通过@Value注解读取配置信息:" + serverPort);
    }
}

结果打印

3)测试方式3:通过@ConfigurationProperties注解读取配置信息

注意点说明:

<font color='red'>注意点1:</font>

<font color='red'>@ConfigurationProperties注解用于指定前缀,下方的属性名称必须和要获取的配置信息名称一致,比如必须叫port,否则获取值为null</font>

使用@ConfigurationProperties首先建立配置文件与对象的映射关系,然后在控制器方法中使用@Autowired注解将对象注入.

<font color='red'>注意点2:</font>

<font color='red'>配置生效的两种方式:</font>

<font color='red'>方式1:</font>配置@Component

<font color='red'>方式2:</font>启动类添加@EnableConfigurationProperties(ReadProperties.class)

<font color='red'>总结:注解@Component和注解@EnableConfigurationProperties(ReadProperties.class)是等价的,写一个就行。</font>

<font color='red'>注意点3:</font>

@ConfigurationProperties也可以和@Value和@Bean一起使用,只不过我没写案例。

<font color='red'>注意点4:</font>

@ConfigurationProperties只能加载以application为前缀开头的配置文件,比如application-dev.properties,加载自定义名称配置文件内容无效。

<font color='red'>注意点5:</font>

问题:从上面的示例中,我们可以看到在属性绑定中@EnableConfigurationProperties和@Component的效果一样,那么为啥springboot还要使用这个注解呢?

<font color='red'>答案:</font>当我们引用第三方jar包时,@Component标注的类是无法注入到spring容器中的,这时我们可以用@EnableConfigurationProperties来代替@Component

ReadProperties

代码语言:java
复制
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

/**
 * 1)注解@ConfigurationProperties中的prefix用于设置前缀
 * 2)下方的属性名称必须和要获取的配置信息名称一致,比如必须叫port,否则获取值为null
 */
@ConfigurationProperties(prefix = "server")//这个注解是用找到类
@Component  //生效的两种方式:方式1:配置@Component,方式2:启动类添加@EnableConfigurationProperties(ReadProperties.class)
@Data
public class ReadProperties {
    private Integer port;
}

Controller

代码语言:java
复制
import com.example.demo.config.ReadProperties;
import com.example.demo.config.ReadProperties2;
import com.example.demo.config.ReadProperties3;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.env.Environment;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PropertiesLoaderUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

/**
 * 测试读取配置文件的几种方式:
 * @Author 211145187
 * @Date 2022/7/20 14:02
 **/
@RestController
public class ReadApplicationProperties {
    @Autowired
    private ReadProperties readProperties;

	//测试方式3:通过@ConfigurationProperties注解读取配置信息
    @GetMapping("/readApplicationProperties3")
    public void readApplicationProperties3(){
        System.out.println("通过@ConfigurationProperties注解读取配置信息:" + readProperties.getPort());
    }
}

结果打印

4)测试方式4:通过@PropertySource+@Value注解读取配置信息

注意点说明:

<font color='red'>注意点1:</font>

@PropertySource注解加载指定的属性文件(*.properties)到 Spring 的 Environment 中。可以配合 @Value 和@ConfigurationProperties 和@Bean使用。

<font color='red'>注意点2:</font>

@PropertySource注解可以配合 @Value 和@ConfigurationProperties 和@Bean一起使用,只不过我没写案例。

<font color='red'>注意点3:</font>

使用@PropertySource注解推荐只加载自定义名称的配置文件,不要加载以application为前缀开头的配置文件,比如application-dev.properties,因为重名的key值会被覆盖,这点会在注意点4中着重说明。

<font color='red'>注意点4:(最容易出错)</font>

讲解一个大坑

<font color='red'>补充说明:</font>application-dev.properties中设置logging.level.root = info,而application-prod.properties中设置logging.level.root = warn

<font color='red'>案例说明:</font>application.properties配置文件设置内置spring.profiles.active=dev,用于关联application-dev.properties配置文件,正常代码运行会把application.properties和application-dev.properties配置文件都加载到内存中,但是现在我想创建一个config或者bean,通过@PropertySource注解去注入并打印application-prod.properties中的这个内容:logging.level.root = warn,正确打印logging.level.root的结果应该是warn,因为它是最后加载的,但实际打印结果logging.level.root的值是info,

问题:为什么?为什么打印info,而我想打印的是prod中的值warn

<font color='red'>答案:</font>如图1,你看红色框中你感觉prod在info下载加载,你会觉得prod相同的key会覆盖dev中的值,实际答案真不是这样,详情请看如图2这个人的回答。正常来说生产项目中application-dev.properties和application-prod.properties只会允许使用一个,才不会混用。

<font color='red'>实际真实项目解决方案是:

  • <font color='red'>第1种方案:</font>启动类中配置环境变量也会通过指定dev还是prod生效,所以该案例只是自己的一个想法,实际没太大作用且实际项目也不会允许同时加载dev和prod配置文件。
  • <font color='red'>第2种方案:</font>为了避免重名key被覆盖,我们会让application.properties和application-dev.properties不会存放相同的key内容,即application.properties有一个key,那么application-dev.properties和application-prod.properties中绝不会有这个相同的key内容。
  • <font color='red'>第3种方案:</font>如果非要使用@PropertySource注解注入一个配置文件,那么一定指向自定义名称配置文件,千万不要指向以application-为前缀的配置文件。

<center><font color='red'>如图1</font></center>

<center><font color='red'>如图2</font></center>

<font color='red'>注意点5:</font>

配置文件加载的优先级 > @PropertySource注解注入

ReadProperties2

代码语言:java
复制
import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;

/**
 * @Author 211145187
 * @Date 2022/7/20 15:47
 **/
@PropertySource(value = {"application.properties"})
@Component
@Data
public class ReadProperties2 {
    @Value("${server.port}")
    private Integer port;
}

ReadProperties4

代码语言:java
复制
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;

/**
 * @Author 211145187
 * @Date 2022/7/20 15:51
 **/
@ConfigurationProperties(prefix = "spring.redis")//这个注解是用找到类    注意:@ConfigurationProperties无法加载自定义配置问价内容,必须和@PropertySource配合使用才能获取
@Component  //生效的两种方式:方式1:配置@Component,方式2:启动类添加@EnableConfigurationProperties(ReadProperties.class)
@PropertySource(value = {"classpath:application-prod.properties"})
@Data
public class ReadProperties4 {
    private String port;
}

Controller

代码语言:java
复制
import com.example.demo.config.ReadProperties;
import com.example.demo.config.ReadProperties2;
import com.example.demo.config.ReadProperties3;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.env.Environment;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PropertiesLoaderUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

/**
 * 测试读取配置文件的几种方式:
 * @Author 211145187
 * @Date 2022/7/20 14:02
 **/
@RestController
public class ReadApplicationProperties {
    @Autowired
    private ReadProperties2 readProperties2;

	//测试方式4:通过@PropertySource+@Value注解读取配置信息
    @GetMapping("/readApplicationProperties4")
    public void readApplicationProperties4(){
        System.out.println("通过@PropertySource注解读取配置信息:" + readProperties2.getPort());
    }
}

结果打印

5)测试方式5:通过@PropertySource+@ConfigurationProperties注解读取配置信息

ReadProperties3

代码语言:java
复制
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;

/**
 * @Author 211145187
 * @Date 2022/7/20 15:51
 **/
@ConfigurationProperties(prefix = "demo")//这个注解是用找到类    注意:@ConfigurationProperties无法加载自定义配置问价内容,必须和@PropertySource配合使用才能获取
@Component  //生效的两种方式:方式1:配置@Component,方式2:启动类添加@EnableConfigurationProperties(ReadProperties.class)
@PropertySource(value = {"classpath:my.properties"})
@Data
public class ReadProperties3 {
    private String name;
}

Controller

代码语言:java
复制
import com.example.demo.config.ReadProperties;
import com.example.demo.config.ReadProperties2;
import com.example.demo.config.ReadProperties3;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.env.Environment;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PropertiesLoaderUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

/**
 * 测试读取配置文件的几种方式:
 * @Author 211145187
 * @Date 2022/7/20 14:02
 **/
@RestController
public class ReadApplicationProperties {
    @Autowired
    private ReadProperties3 readProperties3;

	//测试方式5:通过@PropertySource+@ConfigurationProperties注解读取配置信息
    @GetMapping("/readApplicationProperties5")
    public void readApplicationProperties5(){
        System.out.println("通过@PropertySource+@ConfigurationProperties注解读取配置信息:" + readProperties3);
    }
}

结果打印

6)测试方式6:通过Properties读取配置信息

Controller

代码语言:java
复制
import com.example.demo.config.ReadProperties;
import com.example.demo.config.ReadProperties2;
import com.example.demo.config.ReadProperties3;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.env.Environment;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PropertiesLoaderUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

/**
 * 测试读取配置文件的几种方式:
 * @Author 211145187
 * @Date 2022/7/20 14:02
 **/
@RestController
public class ReadApplicationProperties {
    //测试方式6:通过Properties读取配置信息
    @GetMapping("/readApplicationProperties6")
    public void readApplicationProperties6() throws IOException {
        Resource resource = new ClassPathResource("application-prod.properties");
        Properties properties = PropertiesLoaderUtils.loadProperties(resource);
        String root = properties.getProperty("logging.level.root");
        System.out.println("通过xProperties读取配置信息:" + root);
    }
}

结果打印

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 总结
  • 准备工作
  • 案例说明
    • 1)测试方式1:通过Environment读取配置信息
      • 注意点说明:
    • 2)测试方式2:通过@Value注解读取配置信息(推荐使用)
    • 3)测试方式3:通过@ConfigurationProperties注解读取配置信息
      • 注意点说明:
    • 4)测试方式4:通过@PropertySource+@Value注解读取配置信息
      • 注意点说明:
    • 5)测试方式5:通过@PropertySource+@ConfigurationProperties注解读取配置信息
    • 6)测试方式6:通过Properties读取配置信息
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档