You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot配置类获取application.properties属性值为null问题

解决Spring Boot配置类中属性注入为null的问题

我来帮你排查这个属性返回null的问题,结合你的代码来看,主要问题出在手动配置的属性加载逻辑和Spring Boot自动配置的冲突,再加上一些容易忽略的细节。下面是具体的解决步骤:

1. 移除冗余的属性加载配置

Spring Boot默认会自动加载classpath:application.properties文件,你手动添加的@PropertySource和静态的PropertySourcesPlaceholderConfigurer Bean反而会干扰默认的属性加载流程,导致属性无法正确注入。

修改你的AppProperties类,去掉这两部分内容:

@Configuration
// 移除@PropertySource注解
public class AppProperties {
    @Value("${server.ssl.key-store}")
    private String serverSSLKeyStore;
    @Value("${server.ssl.trust-store}")
    private String serverSSLTrustStore;
    @Value("${server.ssl.key-store-password}")
    private String serverSSLKeyStorePwd;
    @Value("${server.ssl.trust-store-password}")
    private String serverSSLTrustStorePwd;
    @Value("${rabo.api.url}")
    private String raboApiUrl;
    @Value("${tpp.certificate}")
    private String TPPCertificate;
    @Value("${rabo.client.id}")
    private String raboClientId;
    @Value("${rabo.key.id}")
    private String raboKeyId;
    @Value("${rabo.private.key}")
    private String raboPrivateKey;

    // 必须保留所有属性的public getter方法!
    public String getServerSSLKeyStore() {
        return serverSSLKeyStore;
    }

    public String getServerSSLTrustStore() {
        return serverSSLTrustStore;
    }

    public String getServerSSLKeyStorePwd() {
        return serverSSLKeyStorePwd;
    }

    public String getServerSSLTrustStorePwd() {
        return serverSSLTrustStorePwd;
    }

    // 其他属性的getter方法也要补充完整
}

2. 确保getter方法完整

这是很容易忽略的点:如果你的AppProperties没有为每个属性提供public的getter方法,那么外部类(比如RetrofitConfiguration)调用getXXX()时会返回null,因为Spring注入的属性是私有字段,必须通过getter访问。

3. 验证属性键的正确性

检查application.properties中的属性键和@Value注解里的表达式完全一致,比如:

  • 配置文件里是server.ssl.key-store,注解里就不能写成server.ssl.keystore(虽然Spring Boot属性不区分大小写,但连字符和驼峰的映射要对应,或者直接完全匹配)。

4. 确保配置类被Spring扫描到

如果AppProperties和你的Spring Boot主启动类不在同一个包或子包下,需要在主启动类上添加@ComponentScan指定扫描路径:

@SpringBootApplication
@ComponentScan(basePackages = {"com.your.config.package", "com.your.main.package"})
public class YourApplication {
    public static void main(String[] args) {
        SpringApplication.run(YourApplication.class, args);
    }
}

如果在同一个包下,这一步可以跳过,因为Spring Boot默认扫描主启动类所在包及其子包。

(可选)更优雅的替代方案:使用@ConfigurationProperties

如果你的属性较多,推荐用@ConfigurationProperties替代@Value,这种方式类型更安全,也更容易维护:

修改AppProperties类

@Configuration
@ConfigurationProperties
public class AppProperties {
    private ServerSsl serverSsl;
    private Rabo rabo;
    private String tppCertificate;

    // Getters and Setters
    public ServerSsl getServerSsl() {
        return serverSsl;
    }

    public void setServerSsl(ServerSsl serverSsl) {
        this.serverSsl = serverSsl;
    }

    public Rabo getRabo() {
        return rabo;
    }

    public void setRabo(Rabo rabo) {
        this.rabo = rabo;
    }

    public String getTppCertificate() {
        return tppCertificate;
    }

    public void setTppCertificate(String tppCertificate) {
        this.tppCertificate = tppCertificate;
    }

    // 内部类对应配置前缀
    public static class ServerSsl {
        private String keyStore;
        private String trustStore;
        private String keyStorePassword;
        private String trustStorePassword;

        // Getters and Setters
        public String getKeyStore() {
            return keyStore;
        }

        public void setKeyStore(String keyStore) {
            this.keyStore = keyStore;
        }

        // 其他属性的getter/setter
    }

    public static class Rabo {
        private String apiUrl;
        private String clientId;
        private String keyId;
        private String privateKey;

        // Getters and Setters
    }
}

对应的application.properties配置

server.ssl.key-store=your-keystore-path
server.ssl.trust-store=your-truststore-path
server.ssl.key-store-password=your-keystore-pwd
server.ssl.trust-store-password=your-truststore-pwd

rabo.api.url=your-rabo-api-url
rabo.client.id=your-client-id
rabo.key.id=your-key-id
rabo.private.key=your-private-key

tpp.certificate=your-tpp-cert-path

在RetrofitConfiguration中使用

@Configuration
public class RetrofitConfiguration {
    private static final Logger LOG = LoggerFactory.getLogger(RetrofitConfiguration.class);

    @Bean
    SSLTrustManagerHelper provideSSLTrustManagerHelper(AppProperties properties) {
        try {
            String keyStorePath = properties.getServerSsl().getKeyStore();
            LOG.info("Key store path: {}", keyStorePath); // 现在应该能打印正确的值了
            InputStream keystore = new FileInputStream(keyStorePath);
            InputStream truststore = new FileInputStream(properties.getServerSsl().getTrustStore());
            String keystorePwd = properties.getServerSsl().getKeyStorePassword();
            String truststorePwd = properties.getServerSsl().getTrustStorePassword();
            
            return new SSLTrustManagerHelper(keystore, keystorePwd, truststore, truststorePwd);
        } catch (FileNotFoundException e) {
            LOG.error("File not found", e);
            return null;
        } catch (Exception e) {
            LOG.error("Error creating SSLTrustManagerHelper", e);
            return null;
        }
    }
}

完成以上步骤后,重新启动应用,应该就能正确获取到属性值了。

内容的提问来源于stack exchange,提问作者Bas Velden

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 17:32:49