Properties读取yaml/yml值为null

                在分模块,单体项目多模块情况下,在其他模块的Properties使用@ConfigurationProperties是会去默认找主启动类模块的yml,所以会导致找不到对应值,解决方案就是指定类去读取哪个模块的yml值,可以使用 @PropertySource 指定额外的 YAML 文件,但是发现 @PropertySource 并不直接支持解析 .yml,导致属性无法注入、出现 null 值或报错。

最终解决方案

准备自定义的 YamlPropertySourceFactory

package com.example.config;

import org.springframework.beans.factory.config.YamlPropertiesFactoryBean;
import org.springframework.context.annotation.PropertySourceFactory;
import org.springframework.core.env.PropertiesPropertySource;
import org.springframework.core.env.PropertySource;
import org.springframework.core.io.support.EncodedResource;

import java.io.IOException;
import java.util.Properties;

public class YamlPropertySourceFactory implements PropertySourceFactory {
    @Override
    public PropertySource<?> createPropertySource(String name, EncodedResource resource) throws IOException {
        // 利用 Spring 的 YamlPropertiesFactoryBean 将 YAML 转换为 Properties
        YamlPropertiesFactoryBean factory = new YamlPropertiesFactoryBean();
        factory.setResources(resource.getResource());
        Properties properties = factory.getObject();

        // 如果 name 为空,就用文件名做 name
        return new PropertiesPropertySource(
                (name != null ? name : resource.getResource().getFilename()),
                properties
        );
    }
}

在配置类上使用 @PropertySource + @ConfigurationProperties

package com.ssy.properties;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;
import com.example.config.YamlPropertySourceFactory;

@Data
@Component
@PropertySource(value = "classpath:security.yml", factory = YamlPropertySourceFactory.class)
@ConfigurationProperties(prefix = "jwt")
public class JwtProperties {

    private String secretKey;
    private long ttl;
    private String headName;
    private String headBase;
}

常见注意点

1. 包路径:要保证 JwtProperties(以及 YamlPropertySourceFactory)在主应用类扫描范围内;否则需使用 @ComponentScan 或 @EnableConfigurationProperties 手动导入。

2. 文件位置:security.yml 必须在 classpath 中(通常放在 src/main/resources),并确保命名正确。

3. 覆盖优先级:若项目中还有 application.yml,则 Spring Boot 也会自动加载;如果同样存在 jwt: 字段,可能产生覆盖。要避免冲突,请在 application.yml 中去掉同样的前缀,或使用不同 key。

4. 自定义工厂原理:@PropertySource 内部调用 PropertySourceFactory 处理资源文件。Spring 原生仅支持 .properties,我们通过 YamlPropertiesFactoryBean 将 .yml 转为 Properties,再注入到 Environment。