SpringBoot2.x升级踩坑--新增Configuration property name限制
最近公司项目在做SpringBoot的升级,在升级过程中遇到了一些问题,简单记录一下,做个分享。另外,本文中的程序只为示例代码,并非公司生产环境代码。
遇到什么问题
从SpringBoot1.x升级到SpringBoot2.x之后,解决完编译异常,运行程序,在程序启动时报错:
报错信息就已经很直白的告诉了我们错误原因:
配置属性名称“com_shen”无效
无效字符: '_', 原因:规范名称应为kebab-case(用'-'分隔),小写字母数字字符,并且必须以字母开头
怎么解决
经过排查,是因为在application.properties
文件中有如下一个配置项:
com_shen.name=xiaohei
对应Java程序代码:
@Getter
@Setter
@ConfigurationProperties(prefix = "com_shen")
public class Service {
private String name;
}
结合报错日志,我们可以很容易的解决这个问题,去掉配置项中的_
,将配置项name修改为com.shen.name
即可。
源码解析
你以为文章写到这里就结束了吗?其实并没有。hhhhhh,通过这个问题,我们来看一下SpringBoot2.x的内部源码。什么,你不知道该从哪里入手来看这个源码,没关系,我们一步一步来。
点开@ConfigurationProperties
源码,
在Spring中,大量的功能都是通过BeanPostProcessor
来实现的。而且,Spring中的源码注释写的非常的仔细。通过源码注释我们可以猜到可能是ConfigurationPropertiesBindingPostProcessor
这个类在负责@ConfigurationProperties
注解的背后支持。
点开ConfigurationPropertiesBindingPostProcessor
类源码,发现在该类中Override了BeanPostProcessor
的postProcessBeforeInitialization
方法:
在这个方法中,调用了bind(bean, beanName, annotation);
方法。这个方法名叫"绑定",方法中传入了bean、beanName和annotation的信息,经验告诉我这个方法大概率就是在负责解析@ConfigurationProperties
,进行属性绑定。
于是,在这里打一个条件断点,debug运行项目:
通过debug发现的确是这个方法在进行属性绑定。而且底层调用了org.springframework.boot.context.properties.bind.Binder#bind(String, Bindable<T>, BindHandler)
方法:
在这个bind
方法中,又调用了另一个方法bind(ConfigurationPropertyName.of(name), target, handler);
,而且通过name
生成了ConfigurationPropertyName
对象ConfigurationPropertyName.of(name)
,通过方法名我们可以猜测,这个方法可能是在负责解析Configuration Property Name,项目启动的报错信息很有可能是这个方法中抛出的。点开源码:
发现在这个方法中,调用了InvalidConfigurationPropertyNameException.throwIfHasInvalidChars(name,ElementValidator.getInvalidChars(elementValue));
。Spring代码命名真的是太优雅了,虽然名称很长,但是让源码阅读者一看就能明白这个方法在做什么。
通过源码,我们可以看到,在SpringBoot中对Configuration property name中的字符进行了有效性的判断,判断规则如上图所示。
ElementValidator
类是ConfigurationPropertyName
的一个内部类。ConfigurationPropertyName
是SpringBoot2.0新增的一个类,让我们一起来阅读一下类中注释,了解一下这个类:
机器翻译结果如下:
由点分隔的元素组成的配置属性名称。 用户创建的名称可以包含字符“ a-z”,“ 0-9”)和“-”,它们必须为小写字母,并且必须以字母数字字符开头。 “-”仅用于格式化,即“ foo-bar”和“ foobar”被认为是等效的。
“ [”和“]”字符可用于表示关联索引(即Map键或Collection索引。索引名称不受限制,并且区分大小写。以下是一些典型示例:
spring.main.banner-mode
server.hosts [0]。名称
日志[org.springboot] .level
使用@Value
我们知道,SpringBoot中除了可以使用@ConfigurationProperties
之外,还可以使用@Value
。
Demo程序如下:
@Getter
@Setter
@Component
public class Service {
@Value("${com_shen.name}")
private String name;
}
application.properties
文件:
com_shen.name=xiaohei
在这种情况下,项目依旧启动成功了,而且成功的获取到了com_shen.name
的属性值。也就是说,@Value
注解中并没有表达式做限制。
拓展阅读
Property Binding in Spring Boot 2.0 : https://spring.io/blog/2018/03/28/property-binding-in-spring-boot-2-0
欢迎关注公众号,大家一起学习成长。
SpringBoot2.x升级踩坑--新增Configuration property name限制的更多相关文章
- jQuery升级踩坑大全
jQuery升级踩坑大全 背景 jQuery想必各个web工程师都再熟悉不过了,不过现如今很多网站还采用了很古老的jQuery版本.其实如果早期版本使用不当,可能会有DOMXSS漏洞,非常建议升级到j ...
- jQuery升级踩坑之路
1.使用了被废弃的jQuery.browser属性 jQuery 从 1.9 版开始,移除了 $.browser 和 $.browser.version , 取而代之的是 $.support . 在更 ...
- async语法升级踩坑小记
从今年过完年回来,三月份开始,就一直在做重构相关的事情. 就在今天刚刚上线了最新一次的重构代码,希望高峰期安好,接近半年的Node.js代码重构. 包含从callback+async.waterfal ...
- spring-cloud /pause 平滑升级 踩坑记录
0.客户端添加依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId& ...
- jQuery版本升级踩坑大全
背景 -------------------------------------------------------------------------------- jQuery想必各个web工程师 ...
- SpringBoot1.x升级SpringBoot2.x踩坑之文件上传大小限制
SpringBoot1.x升级SpringBoot2.x踩坑之文件上传大小限制 前言 LZ最近升级SpringBoo框架到2.1.6,踩了一些坑,这里介绍的是文件上传大小限制. 升级前 #文件上传配置 ...
- Spark 1.6升级2.x防踩坑指南
原创文章,谢绝转载 Spark 2.x自2.0.0发布到目前的2.2.0已经有一年多的时间了,2.x宣称有诸多的性能改进,相信不少使用Spark的同学还停留在1.6.x或者更低的版本上,没有升级到2. ...
- .NET Core 从1.1升级到2.0记录(Cookie中间件踩坑)
.NET Core 2.0 新时代 万众瞩目的.NET Core 2.0终于发布了,原定于9.19的dotnetconf大会的发布时间大大提前了1个月,.NET Core 2.0/.NET Stand ...
- Rxjava1升级Rxjava2踩坑一记
Rxjava1升级Rxjava2坑 共存问题 通常情况下,如果我们希望在一个模块中既想使用rxjava1又想使用rxjava2,这个时候在运行的时候会出现一下报错: ... APK META/-INF ...
随机推荐
- JDBC进行批处理Batch
在实际的项目开发中,有时候需要向数据库发送一批SQL语句执行,这时应避免向数据库一条条的发送执行,而应采用JDBC的批处理机制,以提升执行效率. JDBC实现批处理有两种方式:statement和pr ...
- 解决The mysql extension is deprecated and will be removed
今天打开网站突然发现报错:“PHP Deprecated: mysql_connect(): The mysql extension is deprecated and will be remove ...
- FreeSql (四)实体特性 Fluent Api
FreeSql 提供使用 Fluent Api, 在外部配置实体的数据库特性,Fluent Api 的方法命名与特性名保持一致,如下: fsql.CodeFirst .ConfigEntity< ...
- Net基础篇_学习笔记_第九天_数组_三个练习
练习一: using System; using System.Collections.Generic; using System.Linq; using System.Text; using Sys ...
- 浅谈PHP反序列化漏洞原理
序列化与反序列化 序列化用途:方便于对象在网络中的传输和存储 0x01 php反序列化漏洞 在PHP应用中,序列化和反序列化一般用做缓存,比如session缓存,cookie等. 常见的序列化格式: ...
- Nginx 的三大功能
1.HTTP服务器 Nginx是一个HTTP服务器,可以将服务器上的静态文件(如HTML.图片)通过HTTP协议展现给客户端. 2.反向代理服务器 Nginx也是反向代理服务器. 说反向代理之前先说一 ...
- 启动第二个activity,然后返回数据给第一个数据
第一个activity启动的代码: intent = new Intent(MainActivity.this, Main2Activity.class); startActivityForResul ...
- 从零开始用golang创建一条简单的区块链
区块链(Blockchain),是比特币的一个重要概念,它本质上是一个去中心化的数据库,同时作为比特币的底层技术,是一串使用密码学方法相关联产生的数据块,每一个数据块中包含了一批次比特币网络交易的信息 ...
- 自定义构建基于.net core 的基础镜像
先说一个问题 首先记录一个问题,今天在用 Jenkins 构建项目的时候突然出现包源的错误: /usr/share/dotnet/sdk/2.2.104/NuGet.targets(114,5): e ...
- WPF中资源的引用方法
一.引用同一个程序中的资源 1.使用相对Uri来引用资源,如下所示 img.Source=new BitmapImage(new Uri(@"d"\iamges\Backgroun ...