Spring Boot中使用 MongoDB 3.0

mongodb 3.0出来了, 有多了很多新特性. 不过这不是我要说的
.
如果要在Java应用程序里用mongodb 3.0你得用3.0的Java驱动程序. 旧的是不行的.
然而很多Java的库还没有跟上脚步, 用的是2.6的驱动程序. Spring Boot就是其中之一.
我相信过不了多久, Spring Boot就会升级支持3.0. 那么现在如果想要用mongodb 3.0怎办呢?

首先你需要把maven的依赖改成3.0相关的版本:


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

<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb</artifactId>
<version>1.7.0.RELEASE</version>
</dependency>

<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-commons</artifactId>
<version>1.10.0.RELEASE</version>
</dependency>


然后以Spring Boot为例, 你要配置mongodb连接的参数 (application.yaml)

spring:
data:
mongodb:
host: localhost
port: 27017
username: user
password: abc123
database: zen
authenticationDatabase: zen


我在mongodb 3.0里已经创建了一个数据库叫zen, 并且给zen创建了一个用户user, 密码是abc123
然后我设置mongodb的auth=true
在2.6开始可以用yaml的方式配置:

security:
authorization: enabled


按照Spring Boot的文档, 有了以上配置后, 你就可以使用Mongodb了, 比如用MongodbTemplate访问数据库. 而实际上如果是3.0那么数据库会告诉你认证失败.

这个问题困扰了很久, 最后还是查看Spring Boot的源码才发现, 原来MongoDB 3.0新增了一种认证机制(authenticationMechanisms) SCRAM-SHA-1, 并把他设置为默认的方式. 而Spring Boot里默认使用旧的认证机制. 这就造成了不一致从而认证通不过.

解决方法有两种:
1. 把Mongodb的认证机制改了:
[url=http://docs.mongodb.org/manual/reference/parameters/#param.authenticationMechanisms]mongodb支持如下几种[/url]:

SCRAM-SHA-1
MONGODB-CR
MONGODB-X509
GSSAPI (Kerberos)
PLAIN (LDAP SASL)

把Mongodb的认证方式改变一下自然能解决问题. 可以同时支持多个.

setParameter:
authenticationMechanisms: MONGODB-CR,SCRAM-SHA-1
enableLocalhostAuthBypass: false
logLevel: 4


但是既然MongoDB从3.0开始用SCRAM-SHA-1作为默认,应该是有道理的, 比如安全性方面比MONGODB-CR更好之类的.
[quote]
MongoDB’s implementation of SCRAM-SHA-1 represents an improvement in security over the previously-used MONGODB-CR, providing:

* A tunable work factor (iterationCount),
* Per-user random salts rather than server-wide salts,
* A cryptographically stronger hash function (SHA-1 rather than MD5), and
* Authentication of the server to the client as well as the client to the server.
[/quote]

2. 如果你不行改变认证方式, 就只能改java代码了

我们看一下Spring Boot的源码;
org.springframework.boot.autoconfigure.mongo.MongoProperties 的 createMongoClient方法:

public MongoClient createMongoClient(MongoClientOptions options)
throws UnknownHostException {
try {
if (hasCustomAddress() || hasCustomCredentials()) {
if (options == null) {
options = MongoClientOptions.builder().build();
}
List<MongoCredential> credentials = null;
if (hasCustomCredentials()) {
String database = this.authenticationDatabase == null ? getMongoClientDatabase()
: this.authenticationDatabase;
credentials = Arrays.asList(MongoCredential.createMongoCRCredential(
this.username, database, this.password));
}
String host = this.host == null ? "localhost" : this.host;
int port = this.port == null ? DEFAULT_PORT : this.port;
return new MongoClient(Arrays.asList(new ServerAddress(host, port)),
credentials, options);
}
// The options and credentials are in the URI
return new MongoClient(new MongoClientURI(this.uri, builder(options)));
}
finally {
clearPassword();
}
}

可以看到它是用MongoCredential.createMongoCRCredential方法来创建认证信息, 并且没有留出任何公开的接口让你改变这一行为. 这个真是不应该呀.

找到问题所在, 其实解决就非常方便了, 使用createScramSha1Credential方法既可.

但是就像上面说的, 没有公开接口, 只能把MongoProperties复制一份, 然后改这一行代码了 :(

首先创建一个MongoDBConfiguration类, 用于创建MongoClient实例.

@Configuration
@EnableConfigurationProperties(MongoProperties.class)
public class MongoDBConfiguration {
@Autowired
private MongoProperties properties;

@Autowired(required = false)
private MongoClientOptions options;

private Mongo mongo;

@PreDestroy
public void close() {
if (this.mongo != null) {
this.mongo.close();
}
}

@Bean
public Mongo mongo() throws UnknownHostException {
this.mongo = this.properties.createMongoClient(this.options);
return this.mongo;
}
}


细心的程序猿们会发现一个问题: Spring Boot中不是有一个一模一样的类吗? 是啊. 但是没法直接用那个类(在org.springframework.boot.autoconfigure.mongo包), 因为它里面用的是同一个包下的MongoProperties, 而不会使用你的.

然后就是我们自己的MongoProperties类了, 我就不写了, 就上面那一句话不一样, 还有就是要让MongoDBConfiguration引用我们自己的MongoProperties类.

然后就OK了.

其实如果Spring Boot做的完善一点应该提供可以选择认证机制的功能, 或者提供公开接口实现自己的认证功能
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Boot使用MongoDB切换数据库,可以通过配置多个MongoDB连接信息和使用`MongoTemplate`的构造函数来实现。下面是具体的步骤: 1. 配置多个MongoDB连接信息 在`application.properties`文件配置多个MongoDB连接信息,例如: ``` # MongoDB1 spring.data.mongodb.uri=mongodb://localhost:27017/db1 spring.data.mongodb.database=db1 spring.data.mongodb.authentication-database=admin spring.data.mongodb.username=user1 spring.data.mongodb.password=password1 # MongoDB2 spring.data.mongodb2.uri=mongodb://localhost:27017/db2 spring.data.mongodb2.database=db2 spring.data.mongodb2.authentication-database=admin spring.data.mongodb2.username=user2 spring.data.mongodb2.password=password2 ``` 2. 创建多个MongoTemplate 创建多个MongoTemplate,并在构造函数指定要使用数据库,例如: ``` @Configuration public class MongoDbConfig { @Autowired private MongoProperties mongoProperties; @Bean(name = "mongoDb1Template") public MongoTemplate mongoDb1Template() { MongoDbFactory mongoDbFactory = new SimpleMongoDbFactory(new MongoClientURI(mongoProperties.getUri() + "/db1")); return new MongoTemplate(mongoDbFactory); } @Bean(name = "mongoDb2Template") public MongoTemplate mongoDb2Template() { MongoDbFactory mongoDbFactory = new SimpleMongoDbFactory(new MongoClientURI(mongoProperties.getUri() + "/db2")); return new MongoTemplate(mongoDbFactory); } } ``` 3. 在DAO层使用不同的MongoTemplate 在DAO层使用不同的MongoTemplate来操作不同的数据库,例如: ``` @Repository public class UserRepository { @Autowired @Qualifier("mongoDb1Template") private MongoTemplate mongoDb1Template; @Autowired @Qualifier("mongoDb2Template") private MongoTemplate mongoDb2Template; public void saveUser1(User user) { mongoDb1Template.save(user); } public void saveUser2(User user) { mongoDb2Template.save(user); } } ``` 这样就可以在DAO层使用不同的MongoTemplate来操作不同的数据库了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值