SpringBoot外化配置源码解析:综合实战演示参数及配置

本文主要是介绍SpringBoot外化配置源码解析:综合实战演示参数及配置,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

综合实战

本章我们讲解了关于 Spring Boot 外化配置的原理及源码分析,本节我们通过一个具体的例子来简单演示在 Spring Boot 中如何使用不同类型的参数及配置。本节实例涉及的部分新知识点我们也会进行简单介绍和拓展。

在本节实例中,我们会用到命令行传递参数、默认配置文件 application.properties 及基于profile 配置参数、@Value 注解获取参数、 基于类型安全的@ConfigurationProperties 注解关联 Bean 等功能。

由于 Spring Boot 已经对外化配置进行了简化处理,对照此前章节中相关原理的介绍,我们在实践中使用起来是非常方便的。这里我创建了一个标准的 Spring Boot 项目,版本采用2.2.1.RELEASE。首先我们看一下项目的目录结构。

在 pom.xml 中引入的核心依赖为 spring-boot-starter-web,对应依赖源码如下。

<dependency>
<groupId>org. springframework . boot</ groupId>
<artifactId>spring- boot- starter-web</artifactId>
</ dependency>


SpringbootConfigApplication 类为 Spring Boot 项目的启动类,我们不再做过多介绍。

ConfigController类为接收请求的 Controller, 在 其内部定义了 一 个 默 认 的getConfigParams 方法,在该方法内打印了不同途径获得的参数值,相关源码如下。

@RestController
public class ConfigController {
@Value( "${user . username}")
private String username ;
@Value("${user . password}")
private String password;
@Resource
private LoginUserConfig loginUserConfig;
@Value("${projectName :unknown}")
private String projectName ;
@RequestMapping("/")
public String getConfigParams() {
//启动命令传递参数
System. out . println("Command config projectName:" + projectName);//通过 appl ication 配置文件配置的参数
System. out . println("Application config Username
System. out . println("Application config Password :”+ password);
//通过@ConfigurationProperties 注解配置的参数
System. out. println("ConfigurationProperties config Username :”+ login
UserConfig.
getUsername());
System . out . println("Configurat ionProperties config Password :”+ login
UserConfig.
getPassword());
return "";
}

其中通过@RestController 注解指定该类为可接收请求的 Controller,并进行实例化。在该类内部分 别通过@Value 注解、@Resource 注解来 获取不同途径 设置的参数。 通过getConfigParams 方法对外提供访问请求, 当前接收到请求之后会打印不同途径获得参数的值。

首先我们来看通过@Value 获取到的值的来源,在该实例中有两个途径来设置对应的值:

application.properties 配置文件和命令行参数。

关于命令行参数,我们之前也已经提到过,基本传递方式就是在执行启动项目的命令时通过“一 name=value' 的形式进行传递。结合并实例,传递方式如下。

java -jar springboot-config-0. 0.1- SNAPSHOT. jar -- projectName=SpringBoot

在 ConfigController 类中,我们可以看到@Value 的使用基本格式为@Value("${param}"),但针对命令行参数获取时我们采用了@Value("${param:default}")方式。在实践中这两种方式都比较常用,而第二种通过冒号分隔符进行传递默认值,当 param 参数不存在或未在application 中配置时,会使用指定的默认值。

以当前实例为例,如果启动命令中未指定 projectName 参数,同时@Value 获取时也未指定默认值"unknown",那么在执行启动命令时便会抛出异常无法启动。这是我们在使用@Value的过程中需要注意的一种情况。

关于 application.properties 配置文件中参数的设置更简单,直接在对应文件中设置对应的key=value 值即可,比如本例中 application.properties 中的配置源码如下。

#公共配置,任何环境启动均采用 8080 端
server. port=8080
spring. profiles . active=dev

但在实践的过程中,我们经常会遇到不同环境需要不同配置文件的情况,如果每换一-个环境就重新修改配置文件或重新打包一次会比较麻烦,这时就可以用 Spring Boot 提供的Profile 配置功能来解决问题了。而我们实例中提供的 3 个 properties 配置文件就是为了展示 Profile 配置的基本使用。

通常情况下,项目中根据环境的多少会创建 1 个到多个 properties 配置文件,一般情况下它们对应的命名格式和相关功能如下。

  1. *applcation.properties:公共配置。
  2. *application-dev.properties:开发环境配置。
  3. .application-test.properties:测试环境配置。
  4. application-prod.properties:生产环境配置。

当然,命名中的“dev'"test 和"prod”是可以自定义的,而这些配置在什么时候会被使用,则可通过激活 application.properties 配置文件中的 spring.profiles. active 参数来控制。

比如,在 applcation.properties 中进行公共配置, 然后通过如下配置激活指定环境的配置。

spring. profiles.active = prod

其中“prod”对照文件名中
application-prod.properties。Spring Boot 在处理时会获取配置文件 applcation.properties, 然 后 通 过 指 定 的 profile 的 值 “prod" 进 行 拼 接 , 获 得application-prod.properties 文件的名称和路径。 具体加载拼接的步骤和原理,我们在前面的章节中已经讲过,可对照实例回顾一下。

在上述实例中,我们激活了 dev 的配置环境,
application-dev.properties 中的配置如下。

#测试环境用户名和账户
user. username=test - admin
user. password=test-pwd

此时,通过访问对应的请求,getConfigParams 方 法中对应打印的日志如下。

Application config
Username : test- admin
Application config Password : test - pwd

如果想激活生产环境的配置,只须在 application.properties 中配置spring.profiles. active=prod 即可。

@Value 参数值的获取和基于 Profile 的参数配置我们就拓展这么多,@Value 的使用还包括注入普通字符串、操作系统属性、表达式结果、文件资源、URL 资源等内容,大家可查阅官方文档和相关实例进一步学习。

在上述@Value 使用中,我们可以对单个属性进行注入配置,但如果有很多配置属性或者配置属性本身拥有层级结构,便显得不够方便灵活。因此,Spring Boo 提供了基于类型安全的配置方式。

在 ConfigController 中我们通过@Resource 注入了一个 LoginUserConfig 类,该类便是通过@ConfigurationProperties 注解将 properties 属性和 LoginUserConfig 的属性进行关联,从而实现类型安全配置。LoginUserConfig 的源码如下。

@Component@Configurat ionProperties(prefix = "user")
public class LoginUserConfig {
private String username ;
private String password;
//省略 getter/setter 方法
}

在 LoginUserConfig 类的源代码中,通过@ConfigurationProperties 注解指定在实例化时将前缀为 user 的配置属性绑定到 LoginUserConfig 类的对应属性上,而通过@Component将该类实例化。

这 里 由 于 指 定 配 置 文 件 为 dev , 则 会 将 上 述 dev 配 置 文 件 中 的 user.username 和user.password 的值分别绑定到 LoginUserConfig 类的 username 和 password 属性上。而在 ConfigController 中注入 之后, 便可获 得对应的属 性值。同样在 执行请求时 ,getConfigParams 方法中对应打印的日志如下。

  • ConfigurationProperties config Username : test - admin
  • ConfigurationProperties config Password : test- pwd

上述实例只演示了@ConfigurationProperties 绑定属性的一种情况,Spring Boot 将 Environment 属性绑定到@ConfigurationProperties 标注的 Bean 时,还可以使用一些宽松的规则,也就是说 Environment 属性名和 Bean 属性名不需要精确匹配。

比如在对象 User 中有一-个 firstName 属性,那么在配置文件中对应如下配置项均会匹配。

  • user. firstName // 标准驼峰命名语法
  • user. first-name // 短横线隔开表示,推荐用于. properties 和. yml 文件中
  • user. first_ name // 下划线表示,用于. properties 和 yml 文件的可选格式
  • USER_ FIRST _NAME //大写形式,推荐用于系统环境变量

同时,基于类型安全的属性配置还可以结合@Validated 注解进行属性的约束校验,比如判断是否非空、是否是正确的手机号(邮箱)格式、是否是正确的日期等,这里就不进行展开了。

大家可以结合本实例尝试拓展。

最后,我们再整体回顾一-下本节实例的重 点内容,首先基于 Profile 机制我们设定了多个环境的配置文件;然后通过 spring. profiles. active 配置指定具体使用哪些环境的参数值;接着通过@Value 和@ConfigurationProperties 注解将这些配置属性绑定到类属性或 Bean 对象上;最后在具体的场景中获取并使用(本实例为打印)。

在具体实践中我们还会遇到优先级的问题,比如某些参数直接通过命令行参数进行指定,那么它将覆盖同名的配置文件中的参数。再比如,如果将 application 配置文件放置在项目同级目录下,它的优先级高于 jar 包内的配置等。这些内容我们在原理篇都有涉及,读者可参考本实例进行逐一验证学习。

小结

本章重点介绍了 Spring Boot 中参数的传递过程和配置文件的加载,特别是基于 profile 的加载机制。而关于加载、默认配置、配置优先级等操作,都位于
ConfigFileApplicationListener类中,该类还是值得读者朋友花时间研究一下的。

实战部分通过一个简单的实例演示了部分原理的使用方法,大家可结合该实例来验证和使用更多的相关功能。

最后,由于本章涉及源码较多,逻辑层次较深,不同的配置模式又会形成不同的组合,形成较多的场景,因此建议在学习过程中通过 debug 来跟踪每一步的操作,以便能够更好地理解整个流程。

本文给大家讲解的内容是SpringBoot外化配置源码解析综合实战演示如何使用不同类型的参数及配置。

  1. 下篇文章给大家讲解的是SpringBootWeb应用源码解析;
  2. 觉得文章不错的朋友可以转发此文关注小编;
  3. 感谢大家的支持!

这篇关于SpringBoot外化配置源码解析:综合实战演示参数及配置的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/610618

相关文章

网页解析 lxml 库--实战

lxml库使用流程 lxml 是 Python 的第三方解析库,完全使用 Python 语言编写,它对 XPath表达式提供了良好的支 持,因此能够了高效地解析 HTML/XML 文档。本节讲解如何通过 lxml 库解析 HTML 文档。 pip install lxml lxm| 库提供了一个 etree 模块,该模块专门用来解析 HTML/XML 文档,下面来介绍一下 lxml 库

JVM 的类初始化机制

前言 当你在 Java 程序中new对象时,有没有考虑过 JVM 是如何把静态的字节码(byte code)转化为运行时对象的呢,这个问题看似简单,但清楚的同学相信也不会太多,这篇文章首先介绍 JVM 类初始化的机制,然后给出几个易出错的实例来分析,帮助大家更好理解这个知识点。 JVM 将字节码转化为运行时对象分为三个阶段,分别是:loading 、Linking、initialization

Spring Security 基于表达式的权限控制

前言 spring security 3.0已经可以使用spring el表达式来控制授权,允许在表达式中使用复杂的布尔逻辑来控制访问的权限。 常见的表达式 Spring Security可用表达式对象的基类是SecurityExpressionRoot。 表达式描述hasRole([role])用户拥有制定的角色时返回true (Spring security默认会带有ROLE_前缀),去

浅析Spring Security认证过程

类图 为了方便理解Spring Security认证流程,特意画了如下的类图,包含相关的核心认证类 概述 核心验证器 AuthenticationManager 该对象提供了认证方法的入口,接收一个Authentiaton对象作为参数; public interface AuthenticationManager {Authentication authenticate(Authenti

Spring Security--Architecture Overview

1 核心组件 这一节主要介绍一些在Spring Security中常见且核心的Java类,它们之间的依赖,构建起了整个框架。想要理解整个架构,最起码得对这些类眼熟。 1.1 SecurityContextHolder SecurityContextHolder用于存储安全上下文(security context)的信息。当前操作的用户是谁,该用户是否已经被认证,他拥有哪些角色权限…这些都被保

Spring Security基于数据库验证流程详解

Spring Security 校验流程图 相关解释说明(认真看哦) AbstractAuthenticationProcessingFilter 抽象类 /*** 调用 #requiresAuthentication(HttpServletRequest, HttpServletResponse) 决定是否需要进行验证操作。* 如果需要验证,则会调用 #attemptAuthentica

Spring Security 从入门到进阶系列教程

Spring Security 入门系列 《保护 Web 应用的安全》 《Spring-Security-入门(一):登录与退出》 《Spring-Security-入门(二):基于数据库验证》 《Spring-Security-入门(三):密码加密》 《Spring-Security-入门(四):自定义-Filter》 《Spring-Security-入门(五):在 Sprin

Java架构师知识体认识

源码分析 常用设计模式 Proxy代理模式Factory工厂模式Singleton单例模式Delegate委派模式Strategy策略模式Prototype原型模式Template模板模式 Spring5 beans 接口实例化代理Bean操作 Context Ioc容器设计原理及高级特性Aop设计原理Factorybean与Beanfactory Transaction 声明式事物

Zookeeper安装和配置说明

一、Zookeeper的搭建方式 Zookeeper安装方式有三种,单机模式和集群模式以及伪集群模式。 ■ 单机模式:Zookeeper只运行在一台服务器上,适合测试环境; ■ 伪集群模式:就是在一台物理机上运行多个Zookeeper 实例; ■ 集群模式:Zookeeper运行于一个集群上,适合生产环境,这个计算机集群被称为一个“集合体”(ensemble) Zookeeper通过复制来实现

CentOS7安装配置mysql5.7 tar免安装版

一、CentOS7.4系统自带mariadb # 查看系统自带的Mariadb[root@localhost~]# rpm -qa|grep mariadbmariadb-libs-5.5.44-2.el7.centos.x86_64# 卸载系统自带的Mariadb[root@localhost ~]# rpm -e --nodeps mariadb-libs-5.5.44-2.el7