如何在 Spring Boot 中初始化一次 MongoClient 并使用它的方法?

Posted

技术标签:

【中文标题】如何在 Spring Boot 中初始化一次 MongoClient 并使用它的方法?【英文标题】:How to initialize MongoClient once in Spring Boot and use its methods? 【发布时间】:2020-08-23 02:24:47 【问题描述】:

您好,我正在尝试在 Spring Boot 中成功连接后导出 MongoClient,并且我正在尝试在其他文件中使用它,这样我就不必每次需要更改时都调用连接我的 MongoDB 数据库。

连接非常简单,但目标是将应用程序连接到我的数据库一次,然后通过将其导入任何 Java 文件中的任何位置使用它。

谢谢

【问题讨论】:

【参考方案1】:

以下是创建MongoClient 实例、在 Spring Boot 应用程序中配置和使用它的几种方法。

(1) 使用基于 Java 的元数据注册 Mongo 实例:

@Configuration
public class AppConfig 
    public @Bean MongoClient mongoClient() 
        return MongoClients.create();
    

CommandLineRunnerrun 方法的用法(所有示例都以类似方式运行):

@Autowired 
MongoClient mongoClient;

// Retrieves a document from the "test1" collection and "test" database.
// Note the MongoDB Java Driver API methods are used here.
private void getDocument() 
    MongoDatabase database = client.getDatabase("test");
    MongoCollection<Document> collection = database.getCollection("test1");
    Document myDoc = collection.find().first();
    System.out.println(myDoc.toJson());

(2) 使用 AbstractMongoClientConfiguration 类进行配置并与 MongoOperations 一起使用:

@Configuration
public class MongoClientConfiguration extends AbstractMongoClientConfiguration 

    @Override
    public MongoClient mongoClient() 
        return MongoClients.create();
    

    @Override
    protected String getDatabaseName() 
        return "newDB";
    

请注意,您可以设置可以连接的数据库名称 (newDB)。此配置用于使用 Spring Data MongoDB API 处理 MongoDB 数据库:MongoOperations(及其实现MongoTemplate)和MongoRepository

@Autowired 
MongoOperations mongoOps;

// Connects to "newDB" database, and gets a count of all documents in the "test2" collection.
// Uses the MongoOperations interface methods.
private void getCollectionSize() 
    Query query = new Query();
    long n = mongoOps.count(query, "test2");
    System.out.println("Collection size: " + n);

(3) 使用 AbstractMongoClientConfiguration 类进行配置并与 MongoRepository 一起使用

使用相同的配置 MongoClientConfiguration 类(在主题 2 中),但另外使用 @EnableMongoRepositories 进行注释。在这种情况下,我们将使用MongoRepository 接口方法将集合数据作为Java 对象获取。

存储库:

@Repository
public interface MyRepository extends MongoRepository<Test3, String> 


代表test3 集合文档的Test3.java POJO 类:

public class Test3 

    private String id;
    private String fld;

    public Test3()     
    

    // Getter and setter methods for the two fields
    // Override 'toString' method
    ...

以下方法获取文档并作为 Java 对象打印:

@Autowired 
MyRepository repository;

// Method to get all the `test3` collection documents as Java objects.
private void getCollectionObjects() 
    List<Test3> list = repository.findAll();
    list.forEach(System.out::println);

【讨论】:

您好,当您使用MongoDatabase database = client.getDatabase("test"); 时,client 变量来自哪里? 这位于getDocument()方法中的第二个代码块 另外你如何在公共静态方法中使用 Autowired MongoClient 请尝试搜索:“spring boot how to use the Autowired (MongoClient) in a public static method”。您会找到很多答案 - 取决于您的需要。 @alienCY 你需要Test3 POJO 类、MyRepository 接口、MongoClientConfiguration 类。然后,实现CommandLineRunner 接口(可以从Spring Boot 应用程序的类中实现) - 并从实现的run 方法中调用getCollectionObjects()。请注意,这是针对 (3) 示例的。【参考方案2】:
    **Pom Changes :**
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-mongodb</artifactId>
            </dependency>
    
            <!-- jpa, crud repository -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-jpa</artifactId>
            </dependency>
    
    **Main Application :**
    
    @SpringBootApplication(exclude = 
            MongoAutoConfiguration.class,
            MongoDataAutoConfiguration.class
    )
    public class Application 
    public static void main(String[] args) 
            SpringApplication.run(Application.class, args);
        
    
    
**MongoConfig Class :**

@Configuration
@EnableMongoRepositories("com.repository.mongo")
public class MongoConfig 

    private final MongoProperties properties;

    public MongoConfig(MongoProperties properties) 
        this.properties = properties;
    

    @Bean
    public MongoClient mongo() throws IOException 
        log.info("Creating mongo client. Socket timeout: , request timeout: ",
                properties.getSocketTimeout(), properties.getConnectTimeout()
        );
        MongoCredential credential = MongoCredential.createCredential(properties.getUsername(), properties.getDatabase(), readPassword(properties.getPasswordFilePath()).toCharArray());

        MongoClientSettings settings = MongoClientSettings.builder()
                .credential(credential)
                .applyToSocketSettings(builder -> builder.readTimeout(properties.getSocketTimeout().intValue(), TimeUnit.MILLISECONDS).connectTimeout(properties.getConnectTimeout().intValue(), TimeUnit.MILLISECONDS))
                .applyToClusterSettings(builder ->
                        builder.hosts(Arrays.asList(new ServerAddress(properties.getHost(), properties.getPort()))).requiredReplicaSetName(properties.getReplicaSet()))
                .build();

        return MongoClients.create(settings);
    


    @Bean
    public MongoDatabase database() throws IOException 
        // Allow POJOs to be (de)serialized
        CodecRegistry extendedRegistry = fromRegistries(
                MongoClientSettings.getDefaultCodecRegistry(),
                fromProviders(PojoCodecProvider.builder().automatic(true).build())
        );
        return mongo().getDatabase(properties.getDatabase()).withCodecRegistry(extendedRegistry);
    

    @Bean
    public MongoTemplate mongoTemplate() throws IOException 
        return new MongoTemplate(mongo(), properties.getDatabase());
    

    @PreDestroy
    public void destroy() throws IOException 
        mongo().close();
    

    private String readPassword(String path) throws IOException 
       // return Files.readString(Paths.get(path));
        return "****";
    


【讨论】:

以上是关于如何在 Spring Boot 中初始化一次 MongoClient 并使用它的方法?的主要内容,如果未能解决你的问题,请参考以下文章

Spring Boot 2.0:Spring Boot 如何解决项目启动时初始化资源

Spring Boot 2.0:Spring Boot 如何解决项目启动时初始化资源

Spring boot连接MongoDB集群

3000字教你如何加快Spring Boot启动

Spring Boot 系统初始化器是如何别调用的,以及实现原理

如何使用Spring Boot在Map中加载属性?