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

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

image.png

@[toc]

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

SpringBoot读取配置文件的几种方式

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

总结

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

准备工作

配置文件目录
image.png

application.properties

server.port=8080
spring.profiles.active=dev

application-dev.properties

spring.redis.host=localhost
logging.level.root = info

application-prod.properties

spring.redis.port=6379
logging.level.root = warn

my.properties

demo.name=cat

案例说明

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

注意点说明:

注意点1:
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; } }

> 结果打印:

image.png

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

> 结果打印

image.png


## 3)测试方式3:通过@ConfigurationProperties注解读取配置信息
### 注意点说明:
注意点1:
@ConfigurationProperties注解用于指定前缀,下方的属性名称必须和要获取的配置信息名称一致,比如必须叫port,否则获取值为null
使用@ConfigurationProperties首先建立配置文件与对象的映射关系,然后在控制器方法中使用@Autowired注解将对象注入.

注意点2:
配置生效的两种方式:
方式1:配置@Component
方式2:启动类添加@EnableConfigurationProperties(ReadProperties.class)

总结:注解@Component和注解@EnableConfigurationProperties(ReadProperties.class)是等价的,写一个就行。 注意点3:
@ConfigurationProperties也可以和@Value和@Bean一起使用,只不过我没写案例。

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

注意点5:

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

答案:当我们引用第三方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()); } }

> 结果打印

image.png


## 4)测试方式4:通过@PropertySource+@Value注解读取配置信息
### 注意点说明:
注意点1:
@PropertySource注解加载指定的属性文件(*.properties)到 Spring 的 Environment 中。可以配合 @Value 和@ConfigurationProperties 和@Bean使用。

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

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

注意点4:(最容易出错)

讲解一个大坑

补充说明:application-dev.properties中设置logging.level.root = info,而application-prod.properties中设置logging.level.root = warn

案例说明: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

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

实际真实项目解决方案是:

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

image.png

如图2

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

ReadProperties2

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

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

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

结果打印

image.png

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

ReadProperties3

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

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

结果打印

image.png

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

Controller

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

结果打印

image.png

目录
相关文章
|
6月前
|
Java Spring
Spring Boot配置的优先级?
在Spring Boot项目中,配置可通过配置文件和外部配置实现。支持的配置文件包括application.properties、application.yml和application.yaml,优先级依次降低。外部配置常用方式有Java系统属性(如-Dserver.port=9001)和命令行参数(如--server.port=10010),其中命令行参数优先级高于系统属性。整体优先级顺序为:命令行参数 &gt; Java系统属性 &gt; application.properties &gt; application.yml &gt; application.yaml。
1097 0
|
3月前
|
JavaScript Java Maven
【SpringBoot(二)】带你认识Yaml配置文件类型、SpringMVC的资源访问路径 和 静态资源配置的原理!
SpringBoot专栏第二章,从本章开始正式进入SpringBoot的WEB阶段开发,本章先带你认识yaml配置文件和资源的路径配置原理,以方便在后面的文章中打下基础
407 3
|
4月前
|
缓存 Java 应用服务中间件
Spring Boot配置优化:Tomcat+数据库+缓存+日志,全场景教程
本文详解Spring Boot十大核心配置优化技巧,涵盖Tomcat连接池、数据库连接池、Jackson时区、日志管理、缓存策略、异步线程池等关键配置,结合代码示例与通俗解释,助你轻松掌握高并发场景下的性能调优方法,适用于实际项目落地。
735 5
|
4月前
|
传感器 Java 数据库
探索Spring Boot的@Conditional注解的上下文配置
Spring Boot 的 `@Conditional` 注解可根据不同条件动态控制 Bean 的加载,提升应用的灵活性与可配置性。本文深入解析其用法与优势,并结合实例展示如何通过自定义条件类实现环境适配的智能配置。
241 0
探索Spring Boot的@Conditional注解的上下文配置
|
10月前
|
缓存 Java API
微服务——SpringBoot使用归纳——Spring Boot集成 Swagger2 展现在线接口文档——Swagger2 的配置
本文介绍了在Spring Boot中配置Swagger2的方法。通过创建一个配置类,添加`@Configuration`和`@EnableSwagger2`注解,使用Docket对象定义API文档的详细信息,包括标题、描述、版本和包路径等。配置完成后,访问`localhost:8080/swagger-ui.html`即可查看接口文档。文中还提示了可能因浏览器缓存导致的问题及解决方法。
1148 0
微服务——SpringBoot使用归纳——Spring Boot集成 Swagger2 展现在线接口文档——Swagger2 的配置
|
5月前
|
安全 算法 Java
在Spring Boot中应用Jasypt以加密配置信息。
通过以上步骤,可以在Spring Boot应用中有效地利用Jasypt对配置信息进行加密,这样即使配置文件被泄露,其中的敏感信息也不会直接暴露给攻击者。这是一种在不牺牲操作复杂度的情况下提升应用安全性的简便方法。
1162 10
|
10月前
|
Java 关系型数据库 数据库
微服务——SpringBoot使用归纳——Spring Boot事务配置管理——Spring Boot 事务配置
本文介绍了 Spring Boot 中的事务配置与使用方法。首先需要导入 MySQL 依赖,Spring Boot 会自动注入 `DataSourceTransactionManager`,无需额外配置即可通过 `@Transactional` 注解实现事务管理。接着通过创建一个用户插入功能的示例,展示了如何在 Service 层手动抛出异常以测试事务回滚机制。测试结果表明,数据库中未新增记录,证明事务已成功回滚。此过程简单高效,适合日常开发需求。
1396 0
|
6月前
|
人工智能 安全 Java
Spring Boot yml 配置敏感信息加密
本文介绍了如何在 Spring Boot 项目中使用 Jasypt 实现配置文件加密,包含添加依赖、配置密钥、生成加密值、在配置中使用加密值及验证步骤,并提供了注意事项,确保敏感信息的安全管理。
1330 1
|
10月前
|
Java 数据库连接 数据库
微服务——SpringBoot使用归纳——Spring Boot集成MyBatis——MyBatis 介绍和配置
本文介绍了Spring Boot集成MyBatis的方法,重点讲解基于注解的方式。首先简述MyBatis作为持久层框架的特点,接着说明集成时的依赖导入,包括`mybatis-spring-boot-starter`和MySQL连接器。随后详细展示了`properties.yml`配置文件的内容,涵盖数据库连接、驼峰命名规范及Mapper文件路径等关键设置,帮助开发者快速上手Spring Boot与MyBatis的整合开发。
1552 0
|
10月前
|
缓存 Java 应用服务中间件
微服务——SpringBoot使用归纳——Spring Boot集成Thymeleaf模板引擎——依赖导入和Thymeleaf相关配置
在Spring Boot中使用Thymeleaf模板,需引入依赖`spring-boot-starter-thymeleaf`,并在HTML页面标签中声明`xmlns:th=&quot;http://www.thymeleaf.org&quot;`。此外,Thymeleaf默认开启页面缓存,开发时建议关闭缓存以实时查看更新效果,配置方式为`spring.thymeleaf.cache: false`。这可避免因缓存导致页面未及时刷新的问题。
414 0