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

启动时读取ConfigurationProperties正常,Bean调用时却显示null

问题排查与解决

问题现象

将Mongo配置属性存储在外部application.properties文件中,通过自定义MongoProperties类读取。启动应用时,getDatabase()方法能正确输出配置的属性值,但在控制器调用MongoGeneral中的SimpleMongoClientDatabaseFactory Bean时,属性值变为null,仅硬编码配置能正常工作。

核心原因

手动创建新的Spring容器实例导致配置隔离:

  • 在UserController的getCollections方法中,通过new AnnotationConfigApplicationContext(MongoGeneral.class)创建了一个全新的Spring容器,这个容器与Spring Boot启动的主容器完全独立,无法获取主容器中已加载的配置属性,因此MongoProperties在新容器中未被正确初始化,属性值为null。
  • 启动时getDatabase()能正常输出,是因为此时是主容器初始化MongoGeneral Bean时调用的,MongoProperties已被正确加载配置。

解决方案

移除手动创建容器的代码,直接通过Spring依赖注入获取所需Bean,利用主容器的配置上下文。

修正后的UserController代码

package com.mistermorse.flawlessbeansjavaspringapi.controller;

import com.mistermorse.flawlessbeansjavaspringapi.config.MongoProperties;
import com.mongodb.client.MongoIterable;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.SimpleMongoClientDatabaseFactory;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/user")
public class UserController {

    private final SimpleMongoClientDatabaseFactory mongoDbFactory;
    private final MongoProperties mongoProperties;

    // 直接注入主容器中的Bean,无需手动创建新容器
    @Autowired
    public UserController(SimpleMongoClientDatabaseFactory mongoDbFactory, MongoProperties mongoProperties) {
        this.mongoDbFactory = mongoDbFactory;
        this.mongoProperties = mongoProperties;
    }

    @GetMapping("/collections")
    public MongoIterable<String> getCollections() {
        // 使用注入的Bean直接获取配置好的数据库
        return mongoDbFactory.getMongoDatabase().listCollectionNames();
    }
}

优化后的MongoGeneral代码(替换硬编码URI为配置属性)

package com.mistermorse.flawlessbeansjavaspringapi.config;

import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoClients;
import com.mongodb.lang.NonNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.mongodb.config.AbstractMongoClientConfiguration;
import org.springframework.data.mongodb.core.SimpleMongoClientDatabaseFactory;

@Configuration
public class MongoGeneral extends AbstractMongoClientConfiguration {

    private final MongoProperties mongoProperties;

    @Autowired
    public MongoGeneral(MongoProperties mongoProperties) {
        this.mongoProperties = mongoProperties;
    }

    @Override
    @NonNull
    public String getDatabaseName() {
        System.out.println("Name: " + this.mongoProperties.getDatabase());
        return this.mongoProperties.getDatabase();
    }

    @Override
    @NonNull
    public MongoClient mongoClient() {
        // 使用配置文件中的URI,不再硬编码
        return MongoClients.create(mongoProperties.getUri());
    }

    @Bean
    @NonNull
    @Override
    public SimpleMongoClientDatabaseFactory mongoDbFactory() {
        return new SimpleMongoClientDatabaseFactory(mongoClient(), getDatabaseName());
    }
}

额外说明

  • 移除了UserController和MongoGeneral中的@EnableConfigurationProperties,因为主类FlawlessBeansJavaSpringApiApplication已添加@ConfigurationPropertiesScan,会自动扫描并注册MongoProperties。
  • 避免手动创建ApplicationContext,Spring Boot的核心优势之一就是依赖注入,直接注入Bean能保证使用的是主容器中已初始化的实例,配置属性自然能正确读取。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 04:00:57