• Spring Boot Mongodb


    Spring注解学习,有助于更好的理解下面代码:

    • @ConditionOnClass表明该@Configuration仅仅在一定条件下才会被加载,这里的条件是Mongo.class位于类路径上
    • @EnableConfigurationProperties将Spring Boot的配置文件(application.properties)中的spring.data.mongodb.*属性映射为MongoProperties并注入到MongoAutoConfiguration中。
    • @ConditionalOnMissingBean说明Spring Boot仅仅在当前上下文中不存在Mongo对象时,才会实例化一个Bean。这个逻辑也体现了Spring Boot的另外一个特性——自定义的Bean优先于框架的默认配置,我们如果显式的在业务代码中定义了一个Mongo对象,那么Spring Boot就不再创建。

    一、先看看spring boot mongo部分源码片段

    /*
     * Copyright 2012-2015 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
     *
     *      http://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.mongo;
    
    import java.net.UnknownHostException;
    
    import javax.annotation.PreDestroy;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
    import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
    import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
    import org.springframework.boot.context.properties.EnableConfigurationProperties;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.core.env.Environment;
    
    import com.mongodb.MongoClient;
    import com.mongodb.MongoClientOptions;
    
    /**
     * {@link EnableAutoConfiguration Auto-configuration} for Mongo.
     *
     * @author Dave Syer
     * @author Oliver Gierke
     * @author Phillip Webb
     */
    @Configuration
    @ConditionalOnClass(MongoClient.class)
    @EnableConfigurationProperties(MongoProperties.class)
    @ConditionalOnMissingBean(type = "org.springframework.data.mongodb.MongoDbFactory")
    public class MongoAutoConfiguration {
    
    	@Autowired
    	private MongoProperties properties;
    
    	@Autowired(required = false)
    	private MongoClientOptions options;
    
    	@Autowired
    	private Environment environment;
    
    	private MongoClient mongo;
    
    	@PreDestroy
    	public void close() {
    		if (this.mongo != null) {
    			this.mongo.close();
    		}
    	}
    
    	@Bean
    	@ConditionalOnMissingBean
    	public MongoClient mongo() throws UnknownHostException {
    		this.mongo = this.properties.createMongoClient(this.options, this.environment);
    		return this.mongo;
    	}
    
    }

    /*
     * Copyright 2012-2015 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
     *
     *      http://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.mongo;
    
    import java.net.UnknownHostException;
    import java.util.Collection;
    import java.util.Collections;
    import java.util.HashSet;
    import java.util.Set;
    
    import org.springframework.beans.BeanUtils;
    import org.springframework.beans.factory.BeanClassLoaderAware;
    import org.springframework.beans.factory.BeanFactory;
    import org.springframework.beans.factory.NoSuchBeanDefinitionException;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.config.BeanDefinition;
    import org.springframework.boot.autoconfigure.AutoConfigurationPackages;
    import org.springframework.boot.autoconfigure.AutoConfigureAfter;
    import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
    import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
    import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
    import org.springframework.boot.context.properties.EnableConfigurationProperties;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.core.env.Environment;
    import org.springframework.core.io.ResourceLoader;
    import org.springframework.core.type.filter.AnnotationTypeFilter;
    import org.springframework.dao.DataAccessException;
    import org.springframework.dao.support.PersistenceExceptionTranslator;
    import org.springframework.data.annotation.Persistent;
    import org.springframework.data.mapping.model.FieldNamingStrategy;
    import org.springframework.data.mongodb.MongoDbFactory;
    import org.springframework.data.mongodb.core.MongoTemplate;
    import org.springframework.data.mongodb.core.SimpleMongoDbFactory;
    import org.springframework.data.mongodb.core.convert.CustomConversions;
    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.mapping.Document;
    import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
    import org.springframework.data.mongodb.gridfs.GridFsTemplate;
    import org.springframework.util.Assert;
    import org.springframework.util.ClassUtils;
    import org.springframework.util.StringUtils;
    
    import com.mongodb.DB;
    import com.mongodb.Mongo;
    import com.mongodb.MongoClient;
    
    /**
     * {@link EnableAutoConfiguration Auto-configuration} for Spring Data's mongo support.
     * <p>
     * Registers a {@link MongoTemplate} and {@link GridFsTemplate} beans if no other beans of
     * the same type are configured.
     * <P>
     * Honors the {@literal spring.data.mongodb.database} property if set, otherwise connects
     * to the {@literal test} database.
     *
     * @author Dave Syer
     * @author Oliver Gierke
     * @author Josh Long
     * @author Phillip Webb
     * @author Eddú Meléndez
     * @since 1.1.0
     */
    @Configuration
    @ConditionalOnClass({ Mongo.class, MongoTemplate.class })
    @EnableConfigurationProperties(MongoProperties.class)
    @AutoConfigureAfter(MongoAutoConfiguration.class)
    public class MongoDataAutoConfiguration implements BeanClassLoaderAware {
    
    	@Autowired
    	private MongoProperties properties;
    
    	@Autowired
    	private Environment environment;
    
    	@Autowired
    	private ResourceLoader resourceLoader;
    
    	private ClassLoader classLoader;
    
    	@Override
    	public void setBeanClassLoader(ClassLoader classLoader) {
    		this.classLoader = classLoader;
    	}
    
    	@Bean
    	@ConditionalOnMissingBean(MongoDbFactory.class)
    	public SimpleMongoDbFactory mongoDbFactory(MongoClient mongo) throws Exception {
    		String database = this.properties.getMongoClientDatabase();
    		return new SimpleMongoDbFactory(mongo, database);
    	}
    
    	@Bean
    	@ConditionalOnMissingBean
    	public MongoTemplate mongoTemplate(MongoDbFactory mongoDbFactory,
    			MongoConverter converter) throws UnknownHostException {
    		return new MongoTemplate(mongoDbFactory, converter);
    	}
    
    	@Bean
    	@ConditionalOnMissingBean(MongoConverter.class)
    	public MappingMongoConverter mappingMongoConverter(MongoDbFactory factory,
    			MongoMappingContext context, BeanFactory beanFactory) {
    		DbRefResolver dbRefResolver = new DefaultDbRefResolver(factory);
    		MappingMongoConverter mappingConverter = new MappingMongoConverter(dbRefResolver,
    				context);
    		try {
    			mappingConverter.setCustomConversions(beanFactory
    					.getBean(CustomConversions.class));
    		}
    		catch (NoSuchBeanDefinitionException ex) {
    			// Ignore
    		}
    		return mappingConverter;
    	}
    
    	@Bean
    	@ConditionalOnMissingBean
    	public MongoMappingContext mongoMappingContext(BeanFactory beanFactory)
    			throws ClassNotFoundException {
    		MongoMappingContext context = new MongoMappingContext();
    		context.setInitialEntitySet(getInitialEntitySet(beanFactory));
    		Class<? extends FieldNamingStrategy> strategyClass = this.properties
    				.getFieldNamingStrategy();
    		if (strategyClass != null) {
    			context.setFieldNamingStrategy(BeanUtils.instantiate(strategyClass));
    		}
    		return context;
    	}
    
    	private Set<Class<?>> getInitialEntitySet(BeanFactory beanFactory)
    			throws ClassNotFoundException {
    		Set<Class<?>> entitySet = new HashSet<Class<?>>();
    		ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(
    				false);
    		scanner.setEnvironment(this.environment);
    		scanner.setResourceLoader(this.resourceLoader);
    		scanner.addIncludeFilter(new AnnotationTypeFilter(Document.class));
    		scanner.addIncludeFilter(new AnnotationTypeFilter(Persistent.class));
    		for (String basePackage : getMappingBasePackages(beanFactory)) {
    			if (StringUtils.hasText(basePackage)) {
    				for (BeanDefinition candidate : scanner
    						.findCandidateComponents(basePackage)) {
    					entitySet.add(ClassUtils.forName(candidate.getBeanClassName(),
    							this.classLoader));
    				}
    			}
    		}
    		return entitySet;
    	}
    
    	private static Collection<String> getMappingBasePackages(BeanFactory beanFactory) {
    		try {
    			return AutoConfigurationPackages.get(beanFactory);
    		}
    		catch (IllegalStateException ex) {
    			// no auto-configuration package registered yet
    			return Collections.emptyList();
    		}
    	}
    
    	@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.
    	 */
    	private static class GridFsMongoDbFactory implements MongoDbFactory {
    
    		private final MongoDbFactory mongoDbFactory;
    
    		private final MongoProperties properties;
    
    		public 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 DB getDb() throws DataAccessException {
    			String gridFsDatabase = this.properties.getGridFsDatabase();
    			if (StringUtils.hasText(gridFsDatabase)) {
    				return this.mongoDbFactory.getDb(gridFsDatabase);
    			}
    			return this.mongoDbFactory.getDb();
    		}
    
    		@Override
    		public DB getDb(String dbName) throws DataAccessException {
    			return this.mongoDbFactory.getDb(dbName);
    		}
    
    		@Override
    		public PersistenceExceptionTranslator getExceptionTranslator() {
    			return this.mongoDbFactory.getExceptionTranslator();
    		}
    
    	}
    
    }

    /*
     * Copyright 2012-2015 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
     *
     *      http://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.mongo;
    
    import java.net.UnknownHostException;
    import java.util.Arrays;
    import java.util.List;
    
    import org.springframework.boot.context.properties.ConfigurationProperties;
    import org.springframework.core.env.Environment;
    import org.springframework.data.mapping.model.FieldNamingStrategy;
    
    import com.mongodb.MongoClient;
    import com.mongodb.MongoClientOptions;
    import com.mongodb.MongoClientOptions.Builder;
    import com.mongodb.MongoClientURI;
    import com.mongodb.MongoCredential;
    import com.mongodb.ServerAddress;
    
    /**
     * Configuration properties for Mongo.
     *
     * @author Dave Syer
     * @author Phillip Webb
     * @author Josh Long
     * @author Andy Wilkinson
     * @author Eddú Meléndez
     */
    @ConfigurationProperties(prefix = "spring.data.mongodb")
    public class MongoProperties {
    
    	/**
    	 * Default port used when the configured port is {@code null}.
    	 */
    	public static final int DEFAULT_PORT = 27017;
    
    	/**
    	 * Mongo server host.
    	 */
    	private String host;
    
    	/**
    	 * Mongo server port.
    	 */
    	private Integer port = null;
    
    	/**
    	 * Mongo database URI. When set, host and port are ignored.
    	 */
    	private String uri = "mongodb://localhost/test";
    
    	/**
    	 * Database name.
    	 */
    	private String database;
    
    	/**
    	 * Authentication database name.
    	 */
    	private String authenticationDatabase;
    
    	/**
    	 * GridFS database name.
    	 */
    	private String gridFsDatabase;
    
    	/**
    	 * Login user of the mongo server.
    	 */
    	private String username;
    
    	/**
    	 * Login password of the mongo server.
    	 */
    	private char[] password;
    
    	/**
    	 * Fully qualified name of the FieldNamingStrategy to use.
    	 */
    	private Class<? extends FieldNamingStrategy> fieldNamingStrategy;
    
    	public String getHost() {
    		return this.host;
    	}
    
    	public void setHost(String host) {
    		this.host = host;
    	}
    
    	public String getDatabase() {
    		return this.database;
    	}
    
    	public void setDatabase(String database) {
    		this.database = database;
    	}
    
    	public String getAuthenticationDatabase() {
    		return this.authenticationDatabase;
    	}
    
    	public void setAuthenticationDatabase(String authenticationDatabase) {
    		this.authenticationDatabase = authenticationDatabase;
    	}
    
    	public String getUsername() {
    		return this.username;
    	}
    
    	public void setUsername(String username) {
    		this.username = username;
    	}
    
    	public char[] getPassword() {
    		return this.password;
    	}
    
    	public void setPassword(char[] password) {
    		this.password = password;
    	}
    
    	public Class<? extends FieldNamingStrategy> getFieldNamingStrategy() {
    		return this.fieldNamingStrategy;
    	}
    
    	public void setFieldNamingStrategy(
    			Class<? extends FieldNamingStrategy> fieldNamingStrategy) {
    		this.fieldNamingStrategy = fieldNamingStrategy;
    	}
    
    	public void clearPassword() {
    		if (this.password == null) {
    			return;
    		}
    		for (int i = 0; i < this.password.length; i++) {
    			this.password[i] = 0;
    		}
    	}
    
    	public String getUri() {
    		return this.uri;
    	}
    
    	public void setUri(String uri) {
    		this.uri = uri;
    	}
    
    	public Integer getPort() {
    		return this.port;
    	}
    
    	public void setPort(Integer port) {
    		this.port = port;
    	}
    
    	public String getGridFsDatabase() {
    		return this.gridFsDatabase;
    	}
    
    	public void setGridFsDatabase(String gridFsDatabase) {
    		this.gridFsDatabase = gridFsDatabase;
    	}
    
    	public String getMongoClientDatabase() {
    		if (this.database != null) {
    			return this.database;
    		}
    		return new MongoClientURI(this.uri).getDatabase();
    	}
    
    	/**
    	 * Creates a {@link MongoClient} using the given {@code options}
    	 *
    	 * @param options the options
    	 * @return the Mongo client
    	 * @throws UnknownHostException if the configured host is unknown
    	 * @deprecated Since 1.3.0 in favour of
    	 * {@link #createMongoClient(MongoClientOptions, Environment)}
    	 */
    	@Deprecated
    	public MongoClient createMongoClient(MongoClientOptions options)
    			throws UnknownHostException {
    		return this.createMongoClient(options, null);
    	}
    
    	/**
    	 * Creates a {@link MongoClient} using the given {@code options} and
    	 * {@code environment}. If the configured port is zero, the value of the
    	 * {@code local.mongo.port} property retrieved from the {@code environment} is used
    	 * to configure the client.
    	 *
    	 * @param options the options
    	 * @param environment the environment
    	 * @return the Mongo client
    	 * @throws UnknownHostException if the configured host is unknown
    	 */
    	public MongoClient createMongoClient(MongoClientOptions options,
    			Environment environment) 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 = determinePort(environment);
    				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();
    		}
    	}
    
    	private boolean hasCustomAddress() {
    		return this.host != null || this.port != null;
    	}
    
    	private boolean hasCustomCredentials() {
    		return this.username != null && this.password != null;
    	}
    
    	private int determinePort(Environment environment) {
    		if (this.port == null) {
    			return DEFAULT_PORT;
    		}
    		if (this.port == 0) {
    			if (environment != null) {
    				String localPort = environment.getProperty("local.mongo.port");
    				if (localPort != null) {
    					return Integer.valueOf(localPort);
    				}
    			}
    			throw new IllegalStateException(
    					"spring.data.mongodb.port=0 and no local mongo port configuration "
    							+ "is available");
    		}
    		return this.port;
    	}
    
    	private Builder builder(MongoClientOptions options) {
    		Builder builder = MongoClientOptions.builder();
    		if (options != null) {
    			builder.alwaysUseMBeans(options.isAlwaysUseMBeans());
    			builder.connectionsPerHost(options.getConnectionsPerHost());
    			builder.connectTimeout(options.getConnectTimeout());
    			builder.cursorFinalizerEnabled(options.isCursorFinalizerEnabled());
    			builder.dbDecoderFactory(options.getDbDecoderFactory());
    			builder.dbEncoderFactory(options.getDbEncoderFactory());
    			builder.description(options.getDescription());
    			builder.maxWaitTime(options.getMaxWaitTime());
    			builder.readPreference(options.getReadPreference());
    			builder.socketFactory(options.getSocketFactory());
    			builder.socketKeepAlive(options.isSocketKeepAlive());
    			builder.socketTimeout(options.getSocketTimeout());
    			builder.threadsAllowedToBlockForConnectionMultiplier(options
    					.getThreadsAllowedToBlockForConnectionMultiplier());
    			builder.writeConcern(options.getWriteConcern());
    		}
    		return builder;
    	}
    
    }
    

    ------------------------------------------------------------------------------------------------------------------------------------------------------

    以上为spring boot mongo的片段,可以看出spring boot已经配置好了,也就是说springboot启动后@Bean创建的对象可以直接使用@Autowrite直接使用

    关注点(spring boot启动会直接读取application.yml或者是application.properties,这里我用的是yml)

    @ConfigurationProperties(prefix = "spring.data.mongodb")
    public class MongoProperties 


    启动入口

    Applicaiton.java 

    package com.modou.weixin;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.CommandLineRunner;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
    import org.springframework.context.annotation.ComponentScan;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.data.mongodb.core.MongoTemplate;
    
    /**
     * Created by chababa on 15/8/22.
     */
    @Configuration
    @ComponentScan(basePackages={"com.modou.conf","com.modou.weixin"})
    @EnableAutoConfiguration
    public class Application implements CommandLineRunner{
    	@Autowired
    	MongoTemplate template;
    	
    	public static void main(String[] args) {
    		SpringApplication.run(Application.class, args);
    	}
    
    	@Override
    	public void run(String... args) throws Exception {
    		System.err.println(template != null);
    	}
    }
    注入MongoTemplate结果


    # SPRING PROFILES
    spring:       
        # HTTP ENCODING
        http:
            encoding.charset: UTF-8
            encoding.enable: true
            encoding.force: true
        data:
            mongodb:
                   host: 127.0.0.1
                   port: 27017
                   username: 
                   password: 
                   database: xx
                   authenticationDatabase:  


  • 相关阅读:
    golang 的几个入门资料
    docker 容器网络基础
    nginx 容器反向代理网址的设置
    【知乎Live】狼叔:如何正确的学习Node.js
    nginx资料汇总
    web 框架
    work behind corp proxy
    [转载] 历史上前端领域的重要技术革命
    前后端要不要分离以及如何做
    微电子工艺基础知识讲解(集成电路历史/厂商/产业链)
  • 原文地址:https://www.cnblogs.com/duyinqiang/p/5696531.html
Copyright © 2020-2023  润新知