美文网首页
spring boot 启动报错:Reason: Canonic

spring boot 启动报错:Reason: Canonic

作者: Always_July | 来源:发表于2022-03-10 18:44 被阅读0次

Spring Boot 版本

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.1.RELEASE</version>
    </parent>

错误异常

Configuration property name 'helloWorld' is not valid:
    
    Invalid characters: 'W'
    Bean: helloWorldProperties
    Reason: Canonical names should be kebab-case ('-' separated), lowercase alpha-numeric characters and must start with a letter

java代码

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;

@Configuration
@ConfigurationProperties(prefix = "helloWorld")
@Data
public class HelloWorldProperties {
    private String userName;
    private Integer userAge;
}

yml 配置

helloWorld:
  userName: mindong
  userAge: 12

解决办法

yml 文件保持不变
修改 HelloWorldProperties.java 的@ConfigurationProperties(prefix = "helloWorld")

方法一

1、hellWorld -> helloworld

方法二

2、helloWorld->hello-world

我又试了将 yml文件中helloWorld改为helloworld,hello-world,hello-World 都可以获取正确的配置。

看来只要 java文件中@ConfigurationProperties的prefix不带大写就可以了。

源码

抛出异常的地方

org.springframework.boot.context.properties.source.ConfigurationPropertyName#elementsOf(java.lang.CharSequence, boolean, int)

    Elements elements = new ElementsParser(name, '.', parserCapacity).parse();
        for (int i = 0; i < elements.getSize(); i++) {
             // 字符为non uniform characters
            if (elements.getType(i) == ElementType.NON_UNIFORM) {
                if (returnNullIfInvalid) {
                    return null;
                }
              // 抛出异常的地方
                throw new InvalidConfigurationPropertyNameException(name, getInvalidChars(elements, i));
            }
        }

具体的解析

org.springframework.boot.context.properties.source.ConfigurationPropertyName.ElementsParser#updateType

// 不是小写字母,不是数字,不在第一位的  - 符号
    if (!isValidChar(ch, index)) {
 // 转换小写后,是合法的,return ElementType.NON_UNIFORM;
                if (existingType == ElementType.EMPTY && !isValidChar(Character.toLowerCase(ch), index)) {
                    return ElementType.EMPTY;
                }
                return ElementType.NON_UNIFORM;
            }

    static boolean isValidChar(char ch, int index) {
            return isAlpha(ch) || isNumeric(ch) || (index != 0 && ch == '-');
        }

ConfigurationPropertyName 类注释

org.springframework.boot.context.properties.source.ConfigurationPropertyName

/**
 * A configuration property name composed of elements separated by dots. User created
 * names may contain the characters "{@code a-z}" "{@code 0-9}") and "{@code -}", they
 * must be lower-case and must start with an alpha-numeric character. The "{@code -}" is
 * used purely for formatting, i.e. "{@code foo-bar}" and "{@code foobar}" are considered
 * equivalent.
 * <p>
 * The "{@code [}" and "{@code ]}" characters may be used to indicate an associative
 * index(i.e. a {@link Map} key or a {@link Collection} index. Indexes names are not
 * restricted and are considered case-sensitive.
 * <p>
 * Here are some typical examples:
 * <ul>
 * <li>{@code spring.main.banner-mode}</li>
 * <li>{@code server.hosts[0].name}</li>
 * <li>{@code log[org.springboot].level}</li>
 * </ul>
 *
 * @author Phillip Webb
 * @author Madhura Bhave
 * @since 2.0.0
 * @see #of(CharSequence)
 * @see ConfigurationPropertySource
 */
翻译如下:

由点分隔的元素组成的配置属性名称。 用户创建的名称可能包含字符“a-z”、“0-9”)和“-”,它们必须小写并且必须以字母数字字符开头。 “-”纯粹用于格式化,即“foo-bar”和“foobar”被认为是等价的。
“[”和“]”字符可用于指示关联索引(即 Map 键或 Collection 索引。索引名称不受限制并且区分大小写。

以下是一些典型的例子:

spring.main.banner-mode
server.hosts[0].name
log[org.springboot].level

从注释可以看出 java代码ConfigurationPropertySource的prefix中字母需要大写,并且“foo-bar”和“foobar”认为是等价的,这个类是从2.0.0 版本开始创建的。

打印错误的地方

org.springframework.boot.diagnostics.analyzer.InvalidConfigurationPropertyNameFailureAnalyzer#buildDescription

    private String buildDescription(InvalidConfigurationPropertyNameException cause, BeanCreationException exception) {
        StringBuilder description = new StringBuilder(
                String.format("Configuration property name '%s' is not valid:%n", cause.getName()));
        String invalid = cause.getInvalidCharacters().stream().map(this::quote).collect(Collectors.joining(", "));
        description.append(String.format("%n    Invalid characters: %s", invalid));
        if (exception != null) {
            description.append(String.format("%n    Bean: %s", exception.getBeanName()));
        }
        description.append(String.format("%n    Reason: Canonical names should be "
                + "kebab-case ('-' separated), lowercase alpha-numeric characters and must start with a letter"));
        return description.toString();
    }

相关文章

网友评论

      本文标题:spring boot 启动报错:Reason: Canonic

      本文链接:https://www.haomeiwen.com/subject/vzzfdrtx.html