Connecting to MongoDB
基于 Java 的元数据方法注册 MongoClient 实例时使用 @Bean 注解,而基于 XML 的元数据方法使用 MongoDB-specific XML 架构。
本文还提供了使用 FactoryBean 注册 MongoClient 实例的示例,该实例提供异常转换功能。此外,本文介绍了 MongoDatabaseFactory 和 ReactiveMongoDatabaseFactory 接口,用于引导连接到特定数据库实例,以及在 IoC 容器中注册它们的示例。最后,它讨论了使用 SimpleMongoClientDbFactory 连接到数据库时的身份验证选项。
使用 MongoDB 和 Spring 时,首要任务之一是使用 IoC 容器创建一个 MongoClient
对象。有两种主要方法来执行此操作,要么使用基于 Java 的 Bean 元数据,要么使用基于 XML 的 Bean 元数据。
One of the first tasks when using MongoDB and Spring is to create a MongoClient
object using the IoC container.
There are two main ways to do this, either by using Java-based bean metadata or by using XML-based bean metadata.
Registering a Mongo Instance
以下示例显示注册 MongoClient
实例的示例:
The following example shows an example to register an instance of a MongoClient
:
MongoClient
-
Imperative
-
Reactive
-
XML
@Configuration
public class AppConfig {
/*
* Use the standard Mongo driver API to create a com.mongodb.client.MongoClient instance.
*/
public @Bean com.mongodb.client.MongoClient mongoClient() {
return com.mongodb.client.MongoClients.create("mongodb://localhost:27017");
}
}
@Configuration
public class AppConfig {
/*
* Use the standard Mongo driver API to create a com.mongodb.client.MongoClient instance.
*/
public @Bean com.mongodb.reactivestreams.client.MongoClient mongoClient() {
return com.mongodb.reactivestreams.client.MongoClients.create("mongodb://localhost:27017");
}
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mongo="http://www.springframework.org/schema/data/mongo"
xsi:schemaLocation=
"
http://www.springframework.org/schema/data/mongo https://www.springframework.org/schema/data/mongo/spring-mongo.xsd
http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- Default bean name is 'mongo' -->
<mongo:mongo-client host="localhost" port="27017"/>
</beans>
这种方法使您能够使用标准 MongoClient
实例,同时容器使用 Spring 的 MongoClientFactoryBean
/ReactiveMongoClientFactoryBean
。与直接实例化 MongoClient
实例相比,FactoryBean
具有额外的优势,因为它还为容器提供了 ExceptionTranslator
实现,该实现将 MongoDB 异常转换为 Spring 可移植 DataAccessException
层次结构中适用于使用 @Repository
注解注释了的数据访问类的异常。此层次结构和 @Repository
的使用在 Spring’s DAO support features 中进行了描述。
This approach lets you use the standard MongoClient
instance, with the container using Spring’s MongoClientFactoryBean
/ReactiveMongoClientFactoryBean
.
As compared to instantiating a MongoClient
instance directly, the FactoryBean
has the added advantage of also providing the container with an ExceptionTranslator
implementation that translates MongoDB exceptions to exceptions in Spring’s portable DataAccessException
hierarchy for data access classes annotated with the @Repository
annotation.
This hierarchy and the use of @Repository
is described in Spring’s DAO support features.
以下示例显示基于 Java 的 Bean 元数据的示例,它支持对 @Repository
注释的类的异常转换:
The following example shows an example of a Java-based bean metadata that supports exception translation on @Repository
annotated classes:
MongoClient
via MongoClientFactoryBean
/ ReactiveMongoClientFactoryBean
-
Imperative
-
Reactive
@Configuration
public class AppConfig {
/*
* Factory bean that creates the com.mongodb.client.MongoClient instance
*/
public @Bean MongoClientFactoryBean mongo() {
MongoClientFactoryBean mongo = new MongoClientFactoryBean();
mongo.setHost("localhost");
return mongo;
}
}
@Configuration
public class AppConfig {
/*
* Factory bean that creates the com.mongodb.reactivestreams.client.MongoClient instance
*/
public @Bean ReactiveMongoClientFactoryBean mongo() {
ReactiveMongoClientFactoryBean mongo = new ReactiveMongoClientFactoryBean();
mongo.setHost("localhost");
return mongo;
}
}
要访问由其他 @Configuration
类或你自己的类中的 FactoryBean
所创建的 MongoClient
对象,请使用 private @Autowired MongoClient mongoClient;
字段。
To access the MongoClient
object created by the FactoryBean
in other @Configuration
classes or your own classes, use a private @Autowired MongoClient mongoClient;
field.
The MongoDatabaseFactory Interface
尽管 MongoClient
是 MongoDB 驱动程序 API 的入口点,但连接到特定的 MongoDB 数据库实例需要更多信息,例如数据库名称以及可选的用户名和密码。有了这些信息,就可以获取 MongoDatabase
对象,并访问特定 MongoDB 数据库实例的所有功能。Spring 提供 org.springframework.data.mongodb.core.MongoDatabaseFactory
和 org.springframework.data.mongodb.core.ReactiveMongoDatabaseFactory
接口,如下列清单所示,用于引导到数据库的连接:
While MongoClient
is the entry point to the MongoDB driver API, connecting to a specific MongoDB database instance requires additional information, such as the database name and an optional username and password.
With that information, you can obtain a MongoDatabase
object and access all the functionality of a specific MongoDB database instance.
Spring provides the org.springframework.data.mongodb.core.MongoDatabaseFactory
& org.springframework.data.mongodb.core.ReactiveMongoDatabaseFactory
interfaces, shown in the following listing, to bootstrap connectivity to the database:
-
Imperative
-
Reactive
public interface MongoDatabaseFactory {
MongoDatabase getDatabase() throws DataAccessException;
MongoDatabase getDatabase(String dbName) throws DataAccessException;
}
public interface ReactiveMongoDatabaseFactory {
Mono<MongoDatabase> getDatabase() throws DataAccessException;
Mono<MongoDatabase> getDatabase(String dbName) throws DataAccessException;
}
以下小节显示了如何使用基于 Java 或基于 XML 的元数据来配置 MongoDatabaseFactory
接口的实例。然后,可以使用 MongoDatabaseFactory
/ ReactiveMongoDatabaseFactory
实例来配置 MongoTemplate
/ ReactiveMongoTemplate
。
The following sections show how you can use the container with either Java-based or XML-based metadata to configure an instance of the MongoDatabaseFactory
interface.
In turn, you can use the MongoDatabaseFactory
/ ReactiveMongoDatabaseFactory
instance to configure MongoTemplate
/ ReactiveMongoTemplate
.
除了使用 IoC 容器创建模板实例,还可以在标准 Java 代码中使用它们,如下所示:
Instead of using the IoC container to create an instance of the template, you can use them in standard Java code, as follows:
- Imperative
-
public class MongoApplication { public static void main(String[] args) throws Exception { MongoOperations mongoOps = new MongoTemplate(new SimpleMongoClientDatabaseFactory(MongoClients.create(), "database")); // ... } }
以粗体显示的代码突出了 SimpleMongoClientDbFactory
的使用,并且是 getting started section 中所示列表之间的唯一差异。选择 com.mongodb.client.MongoClient
作为首选入口点时,请使用 SimpleMongoClientDbFactory
。
The code in bold highlights the use of SimpleMongoClientDbFactory
and is the only difference between the listing shown in the getting started section.
Use SimpleMongoClientDbFactory
when choosing com.mongodb.client.MongoClient
as the entrypoint of choice.
- Reactive
-
public class ReactiveMongoApplication { public static void main(String[] args) throws Exception { ReactiveMongoOperations mongoOps = new MongoTemplate(new SimpleReactiveMongoDatabaseFactory(MongoClients.create(), "database")); // ... } }
Registering a MongoDatabaseFactory
/ ReactiveMongoDatabaseFactory
要使用容器注册 MongoDatabaseFactory
/ ReactiveMongoDatabaseFactory
实例,需要编写类似于上一部分中突出显示的代码。以下清单显示了一个简单的示例:
To register a MongoDatabaseFactory
/ ReactiveMongoDatabaseFactory
instance with the container, you write code much like what was highlighted in the previous section.
The following listing shows a simple example:
-
Imperative
-
Reactive
@Configuration
public class MongoConfiguration {
@Bean
public MongoDatabaseFactory mongoDatabaseFactory() {
return new SimpleMongoClientDatabaseFactory(MongoClients.create(), "database");
}
}
@Configuration
public class ReactiveMongoConfiguration {
@Bean
public ReactiveMongoDatabaseFactory mongoDatabaseFactory() {
return new SimpleReactiveMongoDatabaseFactory(MongoClients.create(), "database");
}
}
MongoDB Server 第 3 代在连接到数据库时更改了身份验证模型,因此,某些可用于身份验证的配置选项不再有效。应该使用特定于 MongoClient
的选项通过 MongoCredential
设置凭据,以提供身份验证数据,如下面的示例所示:
MongoDB Server generation 3 changed the authentication model when connecting to the DB.
Therefore, some of the configuration options available for authentication are no longer valid.
You should use the MongoClient
-specific options for setting credentials through MongoCredential
to provide authentication data, as shown in the following example:
- Java
-
@Configuration public class MongoAppConfig extends AbstractMongoClientConfiguration { @Override public String getDatabaseName() { return "database"; } @Override protected void configureClientSettings(Builder builder) { builder .credential(MongoCredential.createCredential("name", "db", "pwd".toCharArray())) .applyToClusterSettings(settings -> { settings.hosts(singletonList(new ServerAddress("127.0.0.1", 27017))); }); } }
- XML
-
<mongo:db-factory dbname="database" />
在基于 XML 的配置中使用的用户名和密码凭证在包含诸如 :
、%
、@
或 ,
之类的保留字符时必须进行 URL 编码。以下示例展示了编码凭证:m0ng0@dmin:mo_res:bw6},Qsdxx@admin@database
→ m0ng0%40dmin:mo_res%3Abw6%7D%2CQsdxx%40admin@database
有关更多详细信息,请参阅 section 2.2 of RFC 3986。
Username and password credentials used in XML-based configuration must be URL-encoded when these contain reserved characters, such as :
, %
, @
, or ,
.
The following example shows encoded credentials:
m0ng0@dmin:mo_res:bw6},Qsdxx@admin@database
→ m0ng0%40dmin:mo_res%3Abw6%7D%2CQsdxx%40admin@database
See section 2.2 of RFC 3986 for further details.
如果需要针对用于创建 SimpleMongoClientDbFactory
的 com.mongodb.client.MongoClient
实例配置其他选项,可以参考现有 bean,如下面的示例所示。为了展示另一种常见的用法模式,以下清单显示了属性占位符的使用情况,该属性占位符允许对配置以及 MongoTemplate
的创建进行参数化:
If you need to configure additional options on the com.mongodb.client.MongoClient
instance that is used to create a SimpleMongoClientDbFactory
, you can refer to an existing bean as shown in the following example. To show another common usage pattern, the following listing shows the use of a property placeholder, which lets you parametrize the configuration and the creation of a MongoTemplate
:
-
Java
-
XML
@Configuration
@PropertySource("classpath:/com/myapp/mongodb/config/mongo.properties")
public class MongoAppConfig extends AbstractMongoClientConfiguration {
@Autowired
Environment env;
@Override
public String getDatabaseName() {
return "database";
}
@Override
protected void configureClientSettings(Builder builder) {
builder.applyToClusterSettings(settings -> {
settings.hosts(singletonList(
new ServerAddress(env.getProperty("mongo.host"), env.getProperty("mongo.port", Integer.class))));
});
builder.applyToConnectionPoolSettings(settings -> {
settings.maxConnectionLifeTime(env.getProperty("mongo.pool-max-life-time", Integer.class), TimeUnit.MILLISECONDS)
.minSize(env.getProperty("mongo.pool-min-size", Integer.class))
.maxSize(env.getProperty("mongo.pool-max-size", Integer.class))
.maintenanceFrequency(10, TimeUnit.MILLISECONDS)
.maintenanceInitialDelay(11, TimeUnit.MILLISECONDS)
.maxConnectionIdleTime(30, TimeUnit.SECONDS)
.maxWaitTime(15, TimeUnit.MILLISECONDS);
});
}
}
<context:property-placeholder location="classpath:/com/myapp/mongodb/config/mongo.properties"/>
<mongo:mongo-client host="${mongo.host}" port="${mongo.port}">
<mongo:client-settings connection-pool-max-connection-life-time="${mongo.pool-max-life-time}"
connection-pool-min-size="${mongo.pool-min-size}"
connection-pool-max-size="${mongo.pool-max-size}"
connection-pool-maintenance-frequency="10"
connection-pool-maintenance-initial-delay="11"
connection-pool-max-connection-idle-time="30"
connection-pool-max-wait-time="15" />
</mongo:mongo-client>
<mongo:db-factory dbname="database" mongo-ref="mongoClient"/>
<bean id="anotherMongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
<constructor-arg name="mongoDbFactory" ref="mongoDbFactory"/>
</bean>