Connecting to MongoDB
基于 Java 的元数据方法注册 MongoClient 实例时使用 @Bean 注解,而基于 XML 的元数据方法使用 MongoDB-specific XML 架构。
本文还提供了使用 FactoryBean 注册 MongoClient 实例的示例,该实例提供异常转换功能。此外,本文介绍了 MongoDatabaseFactory 和 ReactiveMongoDatabaseFactory 接口,用于引导连接到特定数据库实例,以及在 IoC 容器中注册它们的示例。最后,它讨论了使用 SimpleMongoClientDbFactory 连接到数据库时的身份验证选项。
使用 MongoDB 和 Spring 时,首要任务之一是使用 IoC 容器创建一个 MongoClient
对象。有两种主要方法来执行此操作,要么使用基于 Java 的 Bean 元数据,要么使用基于 XML 的 Bean 元数据。
Registering a Mongo Instance
以下示例显示注册 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 中进行了描述。
以下示例显示基于 Java 的 Bean 元数据的示例,它支持对 @Repository
注释的类的异常转换:
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;
字段。
The MongoDatabaseFactory Interface
尽管 MongoClient
是 MongoDB 驱动程序 API 的入口点,但连接到特定的 MongoDB 数据库实例需要更多信息,例如数据库名称以及可选的用户名和密码。有了这些信息,就可以获取 MongoDatabase
对象,并访问特定 MongoDB 数据库实例的所有功能。Spring 提供 org.springframework.data.mongodb.core.MongoDatabaseFactory
和 org.springframework.data.mongodb.core.ReactiveMongoDatabaseFactory
接口,如下列清单所示,用于引导到数据库的连接:
-
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
。
除了使用 IoC 容器创建模板实例,还可以在标准 Java 代码中使用它们,如下所示:
-
Imperative
-
Reactive
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
。
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
实例,需要编写类似于上一部分中突出显示的代码。以下清单显示了一个简单的示例:
-
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
设置凭据,以提供身份验证数据,如下面的示例所示:
-
Java
-
XML
@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)));
});
}
}
<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。
如果需要针对用于创建 SimpleMongoClientDbFactory
的 com.mongodb.client.MongoClient
实例配置其他选项,可以参考现有 bean,如下面的示例所示。为了展示另一种常见的用法模式,以下清单显示了属性占位符的使用情况,该属性占位符允许对配置以及 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>