2

是我,还是 MongoDb 驱动程序和 Spring-Shell 严重不兼容?首先,我不是在谈论 Spring-Data-Mongo 的东西,我是在谈论 MongoDb 人员推出的实际 Java 客户端。

我的Pom如下:

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.7.RELEASE</version>
    </parent>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.shell</groupId>
            <artifactId>spring-shell-starter</artifactId>
            <version>2.0.1.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.mongodb</groupId>
            <artifactId>mongodb-driver-sync</artifactId>
            <version>3.11.0</version>
        </dependency>
    </dependencies>

如果我尝试从 Spring shell 中使用 MongoDb 客户端,我会一直得到 noclassdeffound 错误。一个简化的裸骨壳方法如下:

import com.mongodb.MongoClientSettings;
import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoClients;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;
import org.bson.codecs.configuration.CodecRegistry;
import org.bson.codecs.pojo.PojoCodecProvider;
import org.springframework.shell.standard.ShellComponent;
import org.springframework.shell.standard.ShellMethod;

import java.util.Date;

import static org.bson.codecs.configuration.CodecRegistries.fromProviders;
import static org.bson.codecs.configuration.CodecRegistries.fromRegistries;

@ShellComponent
public class AuditCommands {

    @ShellMethod("Just testing here")
    public int cube(int number)
    {
        return number*number*number;
    }

    @ShellMethod("Sends a test document to mongo")
    public void mgo()
    {
        System.out.println("Hello there.  Doing some mongo stuff");


        //MongoClient mongoClient = MongoClients.create();
        MongoClient mongoClient = MongoClients.create("mongodb://whateversite:12345");

        // New up a registry to automatically handle pojos
        CodecRegistry pojoCodecRegistry = fromRegistries(MongoClientSettings.getDefaultCodecRegistry(),
                fromProviders(PojoCodecProvider.builder().automatic(true).build()));

        // Grep database instance
        MongoDatabase database = mongoClient.getDatabase("MyDb");
        database = database.withCodecRegistry(pojoCodecRegistry);

        MongoCollection<Audit> collection = database.getCollection("MyCollection", Audit.class);

        Audit audit = new Audit();
        audit.setAuditId(1);
        audit.setAuditTypeId(5);
        audit.setCreatedOn(new Date());
        audit.setMessage("Making mongo great again..");

        collection.insertOne(audit);

        System.out.println("Done..!!..");
    }
}

如果我尝试在示例中执行“mgo”ShellMethod,则会收到以下错误,我会收到以下错误。

Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2019-09-02 18:10:54.634 ERROR 18848 --- [           main] o.s.b.d.LoggingFailureAnalysisReporter   : 

***************************
APPLICATION FAILED TO START
***************************

Description:

An attempt was made to call a method that does not exist. The attempt was made from the following location:

    com.mongodb.client.internal.MongoClientImpl.<init>(MongoClientImpl.java:67)

The following method did not exist:

    com.mongodb.MongoClientSettings.getAutoEncryptionSettings()Lcom/mongodb/AutoEncryptionSettings;

The method's class, com.mongodb.MongoClientSettings, is available from the following locations:

    jar:file:/C:/Users/xxxxx/.m2/repository/org/mongodb/mongodb-driver-core/3.8.2/mongodb-driver-core-3.8.2.jar!/com/mongodb/MongoClientSettings.class

It was loaded from the following location:

    file:/C:/Users/xxxxx/.m2/repository/org/mongodb/mongodb-driver-core/3.8.2/mongodb-driver-core-3.8.2.jar


Action:

Correct the classpath of your application so that it contains a single, compatible version of com.mongodb.MongoClientSettings


Process finished with exit code 1

如果我删除 Spring-Shell 和 Spring-Boot,则 MongoDb 代码可以正常工作。

那么这里给出了什么?我在这里遗漏了一些要点还是这些东西基本上坏了?我不是Java/Spring 本地人,所以当我说在 C#、Python 和 node 中使用 muuuuuuch 清洁器连接到 Mongo 并抛出一些文档时,我相信这不会让人感到意外。(是的,我知道我可以使用 spring-data-mongo,但这对于来自不同语言背景的人来说似乎是一个非常自以为是的 API)

4

1 回答 1

1

好的,我将在这里回答我自己的问题,因为我对此有所了解。

我最终放弃了尝试让 spring boot 排除所有我不想要也没有要求的 mongodb 依赖项。所以这不是一个真正的弹簧壳问题。我最后只是匹配了 spring boot 在我自己的 pom.xml 中使用的驱动程序的版本。

如在..

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

一旦你这样做了,你就会得到一堆“连接到 localhost:27017 ....”的问题。您可以通过排除 spring 默认使用的可笑 MongoAutoConfigure 来解决此问题。更具体地说,您必须使用像这样的参数化 SpringBootApplication 注释:

@SpringBootApplication(exclude = MongoAutoConfiguration.class)
public class Main {
    public static void main(String[] args)
    {
        SpringApplication.run(Main.class);
    }
}

正如我之前提到的,我不是 Java 本地人,所以我的观点深受我成长的框架的影响。但是.. spring 只是自动尝试连接到潜在的网络资源的想法对我来说完全是愚蠢的。如果我真的在尝试使用 spring-mongodb 并且它是超级自以为是的模式,那是一回事,但我不是这样。等效的情况是,如果我从 NuGet 中提取 Dapper 程序集,并且他们尝试登录最近的本地 sql server 实例,只是为了搞定它。充其量是非常粗略的价值主张,最坏的情况是某种创造性利用的表面积。我只是看不到“我”从这种行为中得到了什么。

于 2019-09-21T19:42:02.833 回答