Auto-configure Data Mongo if user provides MongoDbFactory but no client
Previously, if a user defined a MongoDbFactory bean but did not define a client bean, MongoDataAutoConfiguration would back off leaving the context without a MongoTemplate, etc. This commit reworks the auto-configuration so that only the auto-configuration of a MongoDbFactory is dependent on the existence of a Mongo client bean. Auto-configuration of the other components that depend on a MongoDbFactory will now continue in the absence of a Mongo client bean. Closes gh-17416pull/17511/head
parent
7553b60e68
commit
7f85aba546
@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright 2012-2019 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 org.springframework.boot.autoconfigure.data.mongo;
|
||||
|
||||
import com.mongodb.MongoClient;
|
||||
|
||||
import org.springframework.beans.factory.ObjectProvider;
|
||||
import org.springframework.boot.autoconfigure.condition.AnyNestedCondition;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.data.mongo.MongoDbFactoryConfiguration.AnyMongoClientAvailable;
|
||||
import org.springframework.boot.autoconfigure.mongo.MongoProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Conditional;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.data.mongodb.MongoDbFactory;
|
||||
import org.springframework.data.mongodb.core.MongoDbFactorySupport;
|
||||
import org.springframework.data.mongodb.core.SimpleMongoClientDbFactory;
|
||||
import org.springframework.data.mongodb.core.SimpleMongoDbFactory;
|
||||
|
||||
/**
|
||||
* Configuration for a {@link MongoDbFactory}.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
*/
|
||||
@Configuration
|
||||
@ConditionalOnMissingBean(MongoDbFactory.class)
|
||||
@Conditional(AnyMongoClientAvailable.class)
|
||||
class MongoDbFactoryConfiguration {
|
||||
|
||||
@Bean
|
||||
public MongoDbFactorySupport<?> mongoDbFactory(ObjectProvider<MongoClient> mongo,
|
||||
ObjectProvider<com.mongodb.client.MongoClient> mongoClient, MongoProperties properties) {
|
||||
MongoClient preferredClient = mongo.getIfAvailable();
|
||||
if (preferredClient != null) {
|
||||
return new SimpleMongoDbFactory(preferredClient, properties.getMongoClientDatabase());
|
||||
}
|
||||
com.mongodb.client.MongoClient fallbackClient = mongoClient.getIfAvailable();
|
||||
if (fallbackClient != null) {
|
||||
return new SimpleMongoClientDbFactory(fallbackClient, properties.getMongoClientDatabase());
|
||||
}
|
||||
throw new IllegalStateException("Expected to find at least one MongoDB client.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if either a {@link MongoClient com.mongodb.MongoClient} or
|
||||
* {@link com.mongodb.client.MongoClient com.mongodb.client.MongoClient} bean is
|
||||
* available.
|
||||
*/
|
||||
static class AnyMongoClientAvailable extends AnyNestedCondition {
|
||||
|
||||
AnyMongoClientAvailable() {
|
||||
super(ConfigurationPhase.REGISTER_BEAN);
|
||||
}
|
||||
|
||||
@ConditionalOnBean(MongoClient.class)
|
||||
static class PreferredClientAvailable {
|
||||
|
||||
}
|
||||
|
||||
@ConditionalOnBean(com.mongodb.client.MongoClient.class)
|
||||
static class FallbackClientAvailable {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,135 @@
|
||||
/*
|
||||
* Copyright 2012-2019 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 org.springframework.boot.autoconfigure.data.mongo;
|
||||
|
||||
import com.mongodb.ClientSessionOptions;
|
||||
import com.mongodb.DB;
|
||||
import com.mongodb.client.ClientSession;
|
||||
import com.mongodb.client.MongoDatabase;
|
||||
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.mongo.MongoProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.dao.support.PersistenceExceptionTranslator;
|
||||
import org.springframework.data.mongodb.MongoDbFactory;
|
||||
import org.springframework.data.mongodb.core.MongoTemplate;
|
||||
import org.springframework.data.mongodb.core.convert.DbRefResolver;
|
||||
import org.springframework.data.mongodb.core.convert.DefaultDbRefResolver;
|
||||
import org.springframework.data.mongodb.core.convert.MappingMongoConverter;
|
||||
import org.springframework.data.mongodb.core.convert.MongoConverter;
|
||||
import org.springframework.data.mongodb.core.convert.MongoCustomConversions;
|
||||
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
|
||||
import org.springframework.data.mongodb.gridfs.GridFsTemplate;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Configuration for Mongo-related beans that depend on a {@link MongoDbFactory}.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
*/
|
||||
@Configuration
|
||||
@ConditionalOnBean(MongoDbFactory.class)
|
||||
class MongoDbFactoryDependentConfiguration {
|
||||
|
||||
private final MongoProperties properties;
|
||||
|
||||
MongoDbFactoryDependentConfiguration(MongoProperties properties) {
|
||||
this.properties = properties;
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public MongoTemplate mongoTemplate(MongoDbFactory mongoDbFactory, MongoConverter converter) {
|
||||
return new MongoTemplate(mongoDbFactory, converter);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(MongoConverter.class)
|
||||
public MappingMongoConverter mappingMongoConverter(MongoDbFactory factory, MongoMappingContext context,
|
||||
MongoCustomConversions conversions) {
|
||||
DbRefResolver dbRefResolver = new DefaultDbRefResolver(factory);
|
||||
MappingMongoConverter mappingConverter = new MappingMongoConverter(dbRefResolver, context);
|
||||
mappingConverter.setCustomConversions(conversions);
|
||||
return mappingConverter;
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public GridFsTemplate gridFsTemplate(MongoDbFactory mongoDbFactory, MongoTemplate mongoTemplate) {
|
||||
return new GridFsTemplate(new GridFsMongoDbFactory(mongoDbFactory, this.properties),
|
||||
mongoTemplate.getConverter());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link MongoDbFactory} decorator to respect
|
||||
* {@link MongoProperties#getGridFsDatabase()} if set.
|
||||
*/
|
||||
static class GridFsMongoDbFactory implements MongoDbFactory {
|
||||
|
||||
private final MongoDbFactory mongoDbFactory;
|
||||
|
||||
private final MongoProperties properties;
|
||||
|
||||
GridFsMongoDbFactory(MongoDbFactory mongoDbFactory, MongoProperties properties) {
|
||||
Assert.notNull(mongoDbFactory, "MongoDbFactory must not be null");
|
||||
Assert.notNull(properties, "Properties must not be null");
|
||||
this.mongoDbFactory = mongoDbFactory;
|
||||
this.properties = properties;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MongoDatabase getDb() throws DataAccessException {
|
||||
String gridFsDatabase = this.properties.getGridFsDatabase();
|
||||
if (StringUtils.hasText(gridFsDatabase)) {
|
||||
return this.mongoDbFactory.getDb(gridFsDatabase);
|
||||
}
|
||||
return this.mongoDbFactory.getDb();
|
||||
}
|
||||
|
||||
@Override
|
||||
public MongoDatabase getDb(String dbName) throws DataAccessException {
|
||||
return this.mongoDbFactory.getDb(dbName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PersistenceExceptionTranslator getExceptionTranslator() {
|
||||
return this.mongoDbFactory.getExceptionTranslator();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public DB getLegacyDb() {
|
||||
return this.mongoDbFactory.getLegacyDb();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClientSession getSession(ClientSessionOptions options) {
|
||||
return this.mongoDbFactory.getSession(options);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MongoDbFactory withSession(ClientSession session) {
|
||||
return this.mongoDbFactory.withSession(session);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue