Spring boot在添加mongo-java-driver maven依赖时尝试连接mongo

Posted

技术标签:

【中文标题】Spring boot在添加mongo-java-driver maven依赖时尝试连接mongo【英文标题】:Spring boot tries to connect to mongo when adding mongo-java-driver maven dependency 【发布时间】:2020-02-09 07:29:44 【问题描述】:

我刚刚添加了:

    <dependency>
        <groupId>org.mongodb</groupId>
        <artifactId>mongo-java-driver</artifactId>
    </dependency>

到我的 Maven 春季启动项目。我也有这个测试:

/*
 * Copyright 2016 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package hello;

import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;

@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
public class GreetingControllerTests 

    @Autowired
    private MockMvc mockMvc;

    @Test
    public void noParamGreetingShouldReturnDefaultMessage() throws Exception 

        this.mockMvc.perform(get("/greeting")).andDo(print()).andExpect(status().isOk())
                .andExpect(jsonPath("$.content").value("Hello, World!"));
    

    @Test
    public void paramGreetingShouldReturnTailoredMessage() throws Exception 

        this.mockMvc.perform(get("/greeting").param("name", "Spring Community"))
                .andDo(print()).andExpect(status().isOk())
                .andExpect(jsonPath("$.content").value("Hello, Spring Community!"));
    


由于某种原因,当我使用 mvn clean package 构建项目时,spring boot 现在尝试连接到 mongodb:

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.1.7.RELEASE)

2019-10-11 20:36:58.418  INFO 14870 --- [           main] hello.GreetingControllerTests            : Starting GreetingControllerTests on user-ThinkPad-X390 with PID 14870 (started by user in /home/user/repos/frontend-backend/backend)
2019-10-11 20:36:58.423  INFO 14870 --- [           main] hello.GreetingControllerTests            : No active profile set, falling back to default profiles: default
2019-10-11 20:36:59.311  INFO 14870 --- [           main] o.s.s.concurrent.ThreadPoolTaskExecutor  : Initializing ExecutorService 'applicationTaskExecutor'
2019-10-11 20:36:59.565  INFO 14870 --- [           main] org.mongodb.driver.cluster               : Cluster created with settings hosts=[localhost:27017], mode=SINGLE, requiredClusterType=UNKNOWN, serverSelectionTimeout='30000 ms', maxWaitQueueSize=500
2019-10-11 20:36:59.591  INFO 14870 --- [localhost:27017] org.mongodb.driver.cluster               : Exception in monitor thread while connecting to server localhost:27017

com.mongodb.MongoSocketOpenException: Exception opening socket
    at com.mongodb.internal.connection.SocketStream.open(SocketStream.java:67) ~[mongo-java-driver-3.8.2.jar:na]
    at com.mongodb.internal.connection.InternalStreamConnection.open(InternalStreamConnection.java:126) ~[mongo-java-driver-3.8.2.jar:na]
    at com.mongodb.internal.connection.DefaultServerMonitor$ServerMonitorRunnable.run(DefaultServerMonitor.java:117) ~[mongo-java-driver-3.8.2.jar:na]
    at java.base/java.lang.Thread.run(Thread.java:834) ~[na:na]
Caused by: java.net.ConnectException: Connection refused (Connection refused)
    at java.base/java.net.PlainSocketImpl.socketConnect(Native Method) ~[na:na]
    at java.base/java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:399) ~[na:na]

如果我只是删除测试 mongo 依赖,上述mongo 连接不会启动。

但是上面的测试中没有提到mongo,为什么spring会尝试启动mongo连接呢?

【问题讨论】:

【参考方案1】:

如果非要我一句话来回答,那是因为Springboot是自以为是的。一旦通过AutoConfiguration 类注意到您的pom 中的mongo 依赖项,它将尝试连接到mongo。

如果你想覆盖默认行为并告诉 Springboot 不要做 MongoAutoConfiguration 那么你可以这样做

@SpringBootApplication(exclude=MongoAutoConfiguration.class)
public class YourMainApplication 

    public static void main(String[] args) 
        SpringApplication.run(TestApplication.class, args);
    

或者你可以在你的属性文件中使用这一行

spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration

如果您执行上述任一操作,那么它将从您的应用程序中排除 MongoAutoconfiguration(而不仅仅是从您的测试中)。这意味着当您启动应用程序时,您将无法访问 mongo(如果这是您想要的)。

由于SpringbootTest 注释加载了整个应用程序上下文,它会查找这个主应用程序类。如果您排除了一些自动配置,那么即使在您的测试中,它也会被排除。所以你不会有连接到 mongo 的问题。

如果您希望仅在测试中排除此自动配置(以便在运行您的应用程序时不会更改任何内容),您可以这样做

@TestPropertySource(properties=
"spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration")
@SpringBootTest
public class GreetingControllerTests ...

【讨论】:

以上是关于Spring boot在添加mongo-java-driver maven依赖时尝试连接mongo的主要内容,如果未能解决你的问题,请参考以下文章

在 Spring Boot 应用程序上添加 jpa 依赖项时,Okta Spring Boot 不起作用

改进spring boot添加监控

如何使用 graphql-spring-boot 向 GraphQL Java 添加检测?

Spring boot之添加JSP支持

如何在 Spring (Boot) 应用程序的代码中动态添加 bean?

如何在 Spring Boot Health 中添加自定义健康检查?