Spring Boot Java Sping Boot 自定义属性在application.yml中不起作用

dly7yett  于 2023-01-13  发布在  Spring
关注(0)|答案(2)|浏览(188)

bounty将在4天后过期。回答此问题可获得+50声望奖励。Benjamin Basmaci希望引起更多人对此问题的关注:我期望赏金接收者以一种不寻求变通办法的方式解决问题,理想情况下能够解释不寻常的行为。

我正在学习Java Sping Boot 教程,当前的主题是可以同时使用application.propertiesapplication.yml
我的application.properties看起来像这样:

spring.profiles.active=EN, cat
custom.username=user
custom.password=pass

我删除了它,并创建了一个application.yml。IntelliJ甚至用绿色的小开始按钮图标标记它。application.yml看起来像这样:

spring:
  profiles:
    active: EN, cat
custom:
  username: user
  password: pass

但是当我这样做时,custom属性不再被识别。IDE将它们标记为红色并显示以下错误:“此处不应有'custom'键”
我不确定这是否正确,所以我尝试了IDE在使用autocomplete编写spring.profiles.active时的建议,它是这样编写列表元素的:

spring:
  profiles:
    active:
      - EN
      - cat
custom:
  username: user
  password: pass

但这也无济于事。
我不知道从这里去哪里。我试着谷歌的问题,但唯一的命中,我得到的有点接近都只是提到,它可以使用yml,而不是properties,有些甚至使用自定义属性,如我上面显示的。
这可能是一个版本问题吗?如果有帮助的话,我的pom看起来像这样:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.2.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>myID</groupId>
    <artifactId>myArtifact</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>myName</name>
    <description>myDescription</description>
    <properties>
        <java.version>11</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

更新

要回答注解中提出的问题Mark B。这是错误消息:

Error starting ApplicationContext. To display the condition evaluation report re-run your application with 'debug' enabled.
2023-01-05T08:58:07.711+01:00 ERROR 5026 --- [           main] o.s.b.d.LoggingFailureAnalysisReporter   : 

***************************
APPLICATION FAILED TO START
***************************

Description:

Parameter 0 of constructor in my.package.controllers.I18nController required a bean of type 'my.package.services.GreetingService' that could not be found.

The injection point has the following annotations:
    - @org.springframework.beans.factory.annotation.Qualifier("i18nService")

The following candidates were found but could not be injected:
    - User-defined bean
    - User-defined bean
    - User-defined bean method 'primaryGreetingService' in 'GreetingServiceConfig'
    - User-defined bean method 'propertyInjectedGreetingService' in 'GreetingServiceConfig'
    - User-defined bean method 'setterInjectedGreetingService' in 'GreetingServiceConfig'
    - User-defined bean

Action:

Consider revisiting the entries above or defining a bean of type 'my.package.services.GreetingService' in your configuration.

Process finished with exit code 1

乍一看,这看起来像是我在bean的定义或配置中搞砸了一些东西,但是,当我将存储库恢复到如上所述使用application.properties文件时的状态时,一切都按预期工作。
我重新执行了这些步骤,以尽可能地隔离问题。
我所做的就是:
1.删除application.properties
1.创建application.yml
我什么都没改变。

git状态(已翻译和简化):

On Branch master
Your Branch is in the same state as 'origin/master'.

Staged changes:
        deleted:       src/main/resources/application.properties
        new file:     src/main/resources/application.yml

Unstaged changes::
        changed:       src/main/resources/application.yml

src/main/resources/application.yml被暂存为新文件,然后具有未暂存的更改,因为IDE在创建新文件时暂存了该文件。这只是为了消除任何混淆。但这不应影响结果。

更新2

正如评论中所建议的,我尝试添加@ConfigurationProperties(prefix = "custom"),但所做的只是稍微改变了错误:

Error creating bean with name 'i18nController' defined in file
[/path/target/classes/my/package/controllers/I18nController.class]:
Unsatisfied dependency expressed through constructor parameter 0:
No qualifying bean of type 'my.package.services.GreetingService' available:
expected at least 1 bean which qualifies as autowire candidate.
Dependency annotations:
{@org.springframework.beans.factory.annotation.Qualifier("i18nService")}
zbdgwd5y

zbdgwd5y1#

由于您使用的是spring-boot-starter,SnakeYAML库应该位于您的类路径中,但请使用mvn dependency:list进行复查,搜索输出中的[INFO] org.yaml:snakeyaml:jar:1.33:compile -- module org.yaml.snakeyaml [auto]行。
如果缺少,请添加SnakeYAML依赖项:https://mvnrepository.com/artifact/org.yaml/snakeyaml
Eclipse IDE有自动转换机制,可以将属性转换为yaml格式。只需右键单击文件,然后单击“转换”,它就像一个魅力。我使用的是Eclipse STS版。

我猜您没有共享完整的属性文件,可能是语法错误或您的yaml配置中缺少了一些东西。请尝试使用InteliJ IDEA提供的插件:https://plugins.jetbrains.com/plugin/8000-properties-to-yaml-converter或在线转换器,如:https://www.javainuse.com/app2yaml .

更新:

我决定在我的机器上用完全相同版本的SpringBoot和Java复制你的示例代码。首先我创建了一个属性文件并进行了测试(它工作正常),然后将属性文件迁移到YAML格式,它也工作正常,得到了完全相同的结果。

当遇到意外的键custom时,它只说这个键未知(更像是警告,而不是错误),你可以像下面这样在META-INF中定义它。

因此,正如其他评论所建议的那样,我确信它以某种硬编码的方式连接到依赖于属性文件的代码(例如@PropertySource注解,也请参见我下面的评论)。

ql3eal8s

ql3eal8s2#

结论

我是不是误解了问题的重点?
我测试正常。我无法重复错误消息。

演示项目

├── pom.xml
└── src
    └── main
        ├── java
        │   └── com
        │       └── example
        │           └── demo
        │               ├── DemoApplication.java
        │               └── Hello.java
        └── resources
            └── application.yaml

应用程序名称

spring:
  profiles:
    active:
      - EN
      - cat
custom:
  username: userAAA
  password: passBBB

www.example.comDemoApplication.java

package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class DemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }

}

www.example.comHello.java

package com.example.demo;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.bind.annotation.*;

@RestController
@Configuration
@ConfigurationProperties(prefix = "custom")
public class Hello {
private String username;
private String password;
    @RequestMapping("/hello")
    public String hello() {        
        return "OK - ****>>>" + getUsername()+ "<<<****>>>>" + getPassword()+"<<<****";
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}

pom.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <!--<version>2.7.6</version>-->
        <!--<version>3.0.1</version>-->
        <version>2.2.2.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>demo</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <!--<java.version>17</java.version>-->
        <java.version>11</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

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

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

运行

mvn clean package spring-boot:run

测试

$ curl http://localhost:8080/hello

结果

OK - ****>>>userAAA<<<****>>>>passBBB<<<****

pom.xml可以添加更多

我不添加它,也许您可以将其添加到您的pom.xml中

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-configuration-processor</artifactId>
    <optional>true</optional>
</dependency>

相关问题