我们在SpringBoot框架进行项目开发中该如何优雅的读取配置呢?或者说对于一些List或者Map应该如何配置呢?

本篇主要解决如下几个问题:

1、Spring Boot有哪些常用的读取配置文件方式?

1)使用 @Value 读取配置文件

2) 使用 @ConfigurationProperties 读取配置文件

3)使用 Environment 读取配置文件

2、一些复杂的数据结构,如List、Map,如何配置?如何读取呢?

前言

Spring Boot默认的配置文件有两种格式: application.propertiesapplication.yml。 查找顺序是首先从application.properties 查找,

如果找不到,再查找 application.yml。优先级:application.properties > application.yml。

以yml中rabbitmq的配置为例,配置文件如下:

rabbitmq:
host: 127.0.0.1
password: root
port: 5672
username: root

一、使用 @Value 读取配置文件

这种方法适用于对象的参数比较少的情况

我们可以直接在对象的属性上使用 @Value 注解,同时以 ${} 的形式传入配置文件中对应的属性。同时需要在该类的上方使用 @Configuration 注解,将该类作为配置

文件加入,在启动项目的时候实现注入。

@Configuration
public class RabbitmqProperties { @Value("${rabbitmq.host}")
private String rabbitmqHost;
@Value("${rabbitmq.port}")
private String rabbitmqPort;
@Value("${rabbitmq.username}")
private String rabbitmqUsername;
@Value("${rabbitmq.password}")
private String rabbitmqPassword;
}

如果哪里需要用到,通过 @Autowired 注入进去就可以获取属性值了

@Component
public class PropertiesTest { @Autowired
private RabbitmqProperties rabbitmqProperties;
}

二、使用 @ConfigurationProperties 读取配置文件

如果对象的参数比较多情况下,推荐使用 @ConfigurationProperties 会更简单一些,不需要在每一个字段的上面的使用@Value注解。

@ConfigurationProperties注解声明当前类为配置读取类

prefix="rabbitmq" 表示读取前缀为rabbitmq的属性

示例如下:

@ConfigurationProperties(prefix = "rabbitmq")
public class RabbitmqProperties {
private String host;
private String port;
private String username;
private String password;
}

这里有一点需要注意: 必须保证属性名称和字段一模一样,且类需要提供字段的setter方法

注意 如果仅仅只是使用了 @ConfigurationProperties 注解是没有效果的,它并不会将这个配置注入容器中,它还需要和注入容器的注解一起使用。

这里有两种方法实现将它注入到容器中

1、类上添加@Configuration注解

除了@Configuration,也可以是@Controller、@RestController、@Service、@Componet等注解,加入到Ioc容器里。

@Setter
@Configuration
@ConfigurationProperties(prefix = "rabbitmq")
public class RabbitmqProperties {
private String host;
private String port;
private String username;
private String password;
}

同样哪里需要用到,通过 @Autowired 注入进去就可以获取属性值了

2、使用@EnableConfigurationProperties注解

通过 @EnableConfigurationProperties 注解可以将指定的配置读取类的对象加载到Spring容器,也就是说,在其他配置类上使用一个@EnableConfigurationProperties注解,

来将配置文件的参数和RabbitmqProperties类的属性绑定。这样就不需要在RabbitmqProperties类上使用@Configuration注解了

@Configuration
@EnableConfigurationProperties(RabbitmqProperties.class)
public class RabbitmqConfig { @Autowired
private RabbitmqProperties prop; @Bean
public Rabbitmq rabbitmq() {
Rabbitmq mq = new Rabbitmq();
mq.setHost(prop.getHost());
mq.setPort(prop.getPort());
mq.setUsername(prop.getUsername());
mq.setPassword(prop.getPassword());
return mq;
}
}

3、使用@ConfigurationPropertiesScan扫描

在 Spring Boot 2.2.0.RELEASE 中提供了一个扫描注解@ConfigurationPropertiesScan。它可以扫描特定包下所有的被@ConfigurationProperties标记的配置类,

并将它们进行IoC注入。

@ConfigurationPropertiesScan
@SpringBootApplication
public class MainApplication { public static void main(String[] args) {
SpringApplication.run(MainApplication.class, args);
}
}

三、使用 Environment 读取配置文件

Environment 是 SpringCore 中的一个用于读取配置文件的类,将此类使用 @Autowired 注入到类中就可以使用它的getProperty方法来获取某个配置项的值。

如下代码所示:

@SpringBootApplication
public class MainApplication implements InitializingBean { @Autowired
private Environment environment; public static void main(String[] args) {
SpringApplication.run(MainApplication.class, args);
} @Override
public void afterPropertiesSet() {
String username = environment.getProperty("rabbitmq.username");
System.out.println("rabbitmq当前用户名为: " + username);
}
}

四、常用的几种数据结构配置读取

比如我们常见的字符串、整数、List、Map如何配置和读取呢?这里以之前自己开发的一个项目中用到复杂的配置数据来做示例之前有发布一个基于

Spring Cache实现二级缓存(Caffeine+Redis) 的项目,里面的配置就比较复杂。

具体项目地址:基于Spring Cache实现分布式二级缓存

这里展示配置示例:

application.yml

# 二级缓存配置
l2cache:
config:
# 是否存储空值,默认true,防止缓存穿透
allowNullValues: true
# 组合缓存配置
composite:
# 是否全部启用一级缓存,默认false
l1AllOpen: false
# 是否手动启用一级缓存,默认false
l1Manual: true
# 手动配置走一级缓存的缓存key集合,针对单个key维度
l1ManualKeySet:
- userCache:user01
- userCache:user02
- userCache:user03
- userCache:user04 # 一级缓存
caffeine:
# 缓存刷新调度线程池的大小
refreshPoolSize: 2
# 写入后过期时间(秒)
expireAfterWrite: 180
# 访问后过期时间(秒)
expireAfterAccess: 180
# 初始化大小
initialCapacity: 100
# 最大缓存对象个数,超过此数量时之前放入的缓存将失效
maximumSize: 300 # 二级缓存
redis:
# 全局过期时间,单位毫秒,默认不过期
defaultExpiration: 300000
# 每个cacheName的过期时间,单位毫秒
expires: {userCache: 300000,goodsCache: 50000}
# 缓存更新时通知其他节点的topic名称 默认 cache:redis:caffeine:topic
topic: cache:redis:caffeine:topic

配置实体类

@Data
@ConfigurationProperties(prefix = "l2cache")
public class L2CacheProperties {
/**
* 缓存配置
*/
private L2CacheConfig config;
}

L2CacheConfig

/**
* 缓存配置
*
* @author xub
* @date 2022/9/20 下午6:02
*/
@Data
public class L2CacheConfig { /** 是否存储空值,设置为true时,可防止缓存穿透 */
private boolean allowNullValues = true; /** 组合缓存配置 */
private final Composite composite = new Composite(); /** 一级缓存配置 */
private final Caffeine caffeine = new Caffeine(); /** 二级缓存配置 */
private final Redis redis = new Redis(); /**
* 组合缓存配置
*/
@Data
public static class Composite { /** 是否全部启用一级缓存,默认false*/
private boolean l1AllOpen = false; /** 是否手动启用一级缓存,默认false */
private boolean l1Manual = false; /** 手动配置走一级缓存的缓存key集合,针对单个key维度*/
private Set<String> l1ManualKeySet = new HashSet<>();
} /**
* 一级缓存配置
*/
@Data
public static class Caffeine { /** 缓存刷新调度线程池的大小 默认为 CPU数 * 2 */
private Integer refreshPoolSize = Runtime.getRuntime().availableProcessors(); /** 写入后过期时间,单位秒 */
private long expireAfterWrite; /** 写入后刷新时间,单位秒 */
private long refreshAfterWrite; /** 初始化大小 */
private int initialCapacity; /** 最大缓存对象个数,超过此数量时之前放入的缓存将失效 */
private long maximumSize;
} /**
* 二级缓存配置
*/
@Data
public static class Redis { /** 全局过期时间,单位毫秒,默认不过期 */
private long defaultExpiration = 0; /** 每个cacheName的过期时间,单位毫秒,优先级比defaultExpiration高 */
private Map<String, Long> expires = new HashMap<>(); /** 缓存更新时通知其他节点的topic名称 */
private String topic = "cache:redis:caffeine:topic"; }
}

Configuration类

@Configuration
@EnableConfigurationProperties(L2CacheProperties.class)
public class CacheRedisCaffeineAutoConfiguration { @Autowired
private L2CacheProperties l2CacheProperties; @Bean
public RedisCaffeineCacheManager cacheManager() {
return new RedisCaffeineCacheManager(l2CacheProperties.getConfig());
}
}

测试

项目启动后,进行Debug打断点,看有木有注入到L2CacheProperties实体中

通过上面截图就可以看出,所有application.yml配置数据,都已经在L2CacheProperties实体中,说明配置成功,获取也成功了。

SpringBoot 常用读取配置文件的 3 种方法!的更多相关文章

  1. java读取配置文件的几种方法

    java读取配置文件的几种方法 原文地址:http://hbcui1984.iteye.com/blog/56496         在现实工作中,我们常常需要保存一些系统配置信息,大家一般都会选择配 ...

  2. Springboot读取配置文件的两种方法

    第一种: application.yml配置中的参数: zip: Hello Springboot 方法读取: @RestController public class ControllerTest ...

  3. 转:java读取配置文件的几种方法

    转自: http://www.iteye.com/topic/56496 在现实工作中,我们常常需要保存一些系统配置信息,大家一般都会选择配置文件来完成,本文根据笔者工作中用到的读取配置文件的方法小小 ...

  4. Java中spring读取配置文件的几种方法

    Spring读取配置XML文件分三步: 一.新建一个Java Bean: package springdemo; public class HelloBean { private String hel ...

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

    1.读取application文件 在application.yml或者properties文件中添加: info: name: xiaoming age: 13 sex: 1 读取方式如下: imp ...

  6. Spring Boot 入门系列(二十五)读取配置文件的几种方式详解!

    在项目开发中经常会用到配置文件,之前介绍过Spring Boot 资源文件属性配置的方法,但是很多朋友反馈说介绍的不够详细全面.所以, 今天完整的分享Spring Boot读取配置文件的几种方式! S ...

  7. Spring---加载配置文件的几种方法(org.springframework.beans.factory.BeanDefinitionStoreException)

    Spring中的几种容器都支持使用xml装配bean,包括:XmlBeanFactory ,ClassPathXmlApplicationContext ,FileSystemXmlApplicati ...

  8. SpringBoot接收前端参数的三种方法

    都是以前的笔记了,有时间就整理出来了,SpringBoot接收前端参数的三种方法,首先第一种代码: @RestController public class ControllerTest { //访问 ...

  9. js中常用追加元素的几种方法

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

随机推荐

  1. 五分钟给你的 gRPC服务 加上 HTTP 接口

    gRPC 服务要加 HTTP 接口? go-zero 给大家带来极简的 RESTful 和 gRPC 服务开发体验的同时,社区又给我们提出了新的期望: 我想只写一次代码 既要 gRPC 接口 也要 H ...

  2. ajax04_实现关键字联想和自动补全

    用ajax实现关键字联想和自动补全 遇到的小坑 回调函数相对window.onload的摆放位置 给回调函数addData传数据时,如何操作才能将数据传进去 代码实现 前端代码 <!DOCTYP ...

  3. HashSet集合存储数据的结构(哈希表)和Set集合存储㢝不重复的原理

    HashSet集合存储数据的结构(哈希表) Set集合存储㢝不重复的原理 前提:存储的元素必须重写hashCode方法和equals方法

  4. SkiaSharp 之 WPF 自绘 拖曳小球(案例版)

    感谢各位大佬和粉丝的厚爱和关心( 催更),我会再接再厉的,其实这也是督促自己的一种方式,非常感谢. 刚写了一篇万字长文,自己也休养生息(低调发育)了一段时间,接下来来几个小案例. 拖曳小球 WPF的拖 ...

  5. CSS 上下居中和最低高度语法

    /*上下居中*/ vertical-align:center; font-size=line-height; /*最低高度*/ height:auto!important; height:400px; ...

  6. YII的lazy loading

    版本1 require('class\class1.php'); require('class\class1.php'); if($is_girl){ echo 'this is a girl'; $ ...

  7. 一代版本一代神:利用Docker在Win10系统极速体验Django3.1真实异步(Async)任务

    一代版本一代神:利用Docker在Win10系统极速体验Django3.1真实异步(Async)任务 原文转载自「刘悦的技术博客」https://v3u.cn/a_id_177 就在去年(2019年) ...

  8. 利用本地HTTPS模拟环境为FastAPI框架集成FaceBook社交三方登录

    原文转载自「刘悦的技术博客」https://v3u.cn/a_id_174 提起社交,就不得不说马克·扎克伯格(Mark Zuckerberg)一手创办的社交网络(FaceBook).进入2020年, ...

  9. 从贡献第一个 pr 开始,我的开源之路正式开启

    点击上方蓝字关注我们 1 我是一名开源爱好者 我是李进勇,Github Id:JinyLeeChina,目前就职于政采云,专注于大数据平台及数仓领域,是开源项目爱好者. 2 我与小海豚的不解之缘 记得 ...

  10. 设置 Git 用户名和邮箱

    安装完 Git 之后,要做的第一件事就是设置你的用户名和邮件地址.因为每一个提交都会使用这些信息,如果你不完善它们,在 GitHub 远程仓库里很有可能没有你的贡献统计. 以下操作需要你打开 Git ...