Spring Boot自定义属性在application.yml中无法生效问题
问题背景
原本使用application.properties配置文件,内容如下:
spring.profiles.active=EN, cat custom.username=user custom.password=pass
删除该文件后创建application.yml(IntelliJ显示绿色启动图标),内容:
spring: profiles: active: EN, cat custom: username: user password: pass
此时IDE标记custom属性为红色,提示"Key 'custom' is not expected here"。尝试修改profile激活的数组写法后问题依旧:
spring: profiles: active: - EN - cat custom: username: user password: pass
项目使用的Spring Boot版本为2.2.2.RELEASE,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.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>
启动报错信息
切换为yml后启动项目出现Bean注入错误:
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
注意:切换回application.properties后项目可正常启动,仅修改了配置文件类型,无其他代码变更。
添加@ConfigurationProperties后的报错
按照建议给配置类添加@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")}
解决方案
1. 确保YAML文件语法完全正确
YAML对缩进和格式极度敏感,必须满足以下要求:
- 所有缩进使用2个空格,禁止使用Tab键(Tab和空格混合会导致解析错误)
- 键值对冒号后必须加空格(如
spring:后要有空格) - 数组元素的
-后必须加空格(如- EN)
验证后的正确application.yml示例:
spring: profiles: active: - EN - cat custom: username: user password: pass
2. 解决IDE对自定义属性的识别问题
IDE提示"Key 'custom' is not expected here"是因为缺少配置处理器依赖,在pom.xml中添加以下依赖即可让IDE识别自定义属性:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> <optional>true</optional> </dependency>
添加后执行mvn clean compile,IDE的红色提示会消失。
3. 排查Profile激活有效性
Bean注入失败的核心原因是指定的Profile未被正确激活,导致i18nService所在的Profile Bean未加载。可以通过以下方式验证:
- 在启动类添加日志,打印当前激活的Profile:
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.core.env.Environment; @SpringBootApplication public class MyApplication { public static void main(String[] args) { Environment env = SpringApplication.run(MyApplication.class, args).getEnvironment(); System.out.println("Activated Profiles: " + String.join(", ", env.getActiveProfiles())); } }
如果输出的激活Profile不包含EN或cat,说明YAML中的Profile配置未被解析,需重新检查YAML格式。
4. 清理IDE缓存并重新构建
IntelliJ有时会缓存旧的配置信息,导致YAML配置不生效:
- 执行
File -> Invalidate Caches... -> Invalidate and Restart - 执行
mvn clean package清理并重新构建项目
5. 验证自定义属性绑定方式
如果使用@Value注解直接读取custom.username等属性,不需要添加@ConfigurationProperties;如果使用配置类绑定属性,需确保:
- 配置类添加
@ConfigurationProperties(prefix = "custom")和@Component(或通过@EnableConfigurationProperties注册)
import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; @Component @ConfigurationProperties(prefix = "custom") public class CustomProperties { private String username; private String password; // Getters and Setters 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; } }
内容的提问来源于stack exchange,提问作者Benjamin Basmaci

