spring boot(1)

1.简介

Spring Boot 是由 Pivotal 团队提供的全新框架,其设计目的是用来简化新 Spring 应用的初始搭建(起步依赖)以及开发过程(自动配置)。该框架使用了特定的方式来进行配置,从而使开发人员再也不须要定义样板化的配置。html

2.特色

Spring Boot将不少魔法带入了Spring应用程序的开发之中,其中重要的是如下四个核心。  自动配置:针对不少Spring应用程序常见的应用功能,Spring Boot能自动提供相关配置。 (约定大于配置)  起步依赖:告诉Spring Boot须要什么功能,它就能引入须要的库。  命令行界面:这是Spring Boot的可选特性,借此你只需写代码就能完成完整的应用程序, 无需传统项目构建。  Actuator:让你可以深刻运行中的Spring Boot应用程序,一探究竟。java

3.原理

Spring Boot没有引入任何形式的代码生成,而是利用了Spring 4的条件化配置特性, 以及经过提供众多起步依赖下降项目依赖的复杂度。起步依赖本质上是一个Maven项 目对象模型(Project Object Model,POM),定义了对其余库的传递依赖,这些东西加在一块儿即 支持某项功能。不少起步依赖的命名都暗示了它们提供的某种或某类功能。简而言之,从本质上来讲,Spring Boot就是Spring,它作了那些没有它你本身也会去作的Spring Bean配置。谢天谢地,幸亏有Spring,你不用再写这些样板配置了,能够专一于应用程序的逻辑, 这些才是应用程序独一无二的东西。spring

起步依赖:Maven和Gradle 自动配置:条件化配置(@ConditionalOnMissingBean注解)mongodb

4.自定义配置

Springboot 提供的自动配置当然很好,可是若是想要自定义某些功能就要覆盖自动配置了。 覆盖自动配置很简单,就当自动配置不存在,直接显式地写一段配置。显式配置的形式不限,Spring支持的XML和Groovy形式配置均可以。简而言之,就是没有Spring以前是怎么配置的,如今手写一遍就能够了。 第二种方式能够修改自动配置的属性(properties文件)来微调设置。如:server.port = 9080 这些属性。数据库

自定义配置技巧 spring自动配置都在org.springframework.boot.autoconfigure包下面,并且springboot的自动配置bean的命名都以Autoconfiguretion结尾,所以只要在这个包下稍做搜索就能找到想要的自动配置。 找到这些类以后就能够参照其配置来覆盖自动配置,并且每每这些包下还有properties类,能够看springboot提供了什么微调属性能够配置。springboot

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package org.springframework.boot.autoconfigure.mongo;

import com.mongodb.MongoClient;
import com.mongodb.MongoClientOptions;
import com.mongodb.MongoClientURI;
import com.mongodb.MongoCredential;
import com.mongodb.ServerAddress;
import com.mongodb.MongoClientOptions.Builder;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.core.env.Environment;

@ConfigurationProperties(
    prefix = "spring.data.mongodb"
)
public class MongoProperties {
    public static final int DEFAULT_PORT = 27017;
    public static final String DEFAULT_URI = "mongodb://localhost/test";
    private String host;
    private Integer port = null;
    private String uri;
    private String database;
    private String authenticationDatabase;
    private String gridFsDatabase;
    private String username;
    private char[] password;
    private Class<?> fieldNamingStrategy;

   //....省略方法
}

看到MongoProperties类,那么我在application.Properties 文件中配置好 spring.data.mongodb.uri = xxxxx就能够指定mongo数据库的链接地址。app

咱们还能够参照MongoDataAutoConfiguration类,复写其中的java配置Bean 至于具体如何复写能够参考另外一篇文章 - mongo自定义类型映射框架

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package org.springframework.boot.autoconfigure.data.mongo;

import com.mongodb.DB;
import com.mongodb.MongoClient;
import java.net.UnknownHostException;
import java.util.Collections;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.domain.EntityScanner;
import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration;
import org.springframework.boot.autoconfigure.mongo.MongoProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.ApplicationContext;
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.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.StringUtils;

@Configuration
@ConditionalOnClass({MongoClient.class, MongoTemplate.class})
@EnableConfigurationProperties({MongoProperties.class})
@AutoConfigureAfter({MongoAutoConfiguration.class})
public class MongoDataAutoConfiguration {
    private final ApplicationContext applicationContext;
    private final MongoProperties properties;

    public MongoDataAutoConfiguration(ApplicationContext applicationContext, MongoProperties properties) {
        this.applicationContext = applicationContext;
        this.properties = properties;
    }

    @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, CustomConversions conversions) {
        DbRefResolver dbRefResolver = new DefaultDbRefResolver(factory);
        MappingMongoConverter mappingConverter = new MappingMongoConverter(dbRefResolver, context);
        mappingConverter.setCustomConversions(conversions);
        return mappingConverter;
    }

    @Bean
    @ConditionalOnMissingBean
    public MongoMappingContext mongoMappingContext(BeanFactory beanFactory, CustomConversions conversions) throws ClassNotFoundException {
        MongoMappingContext context = new MongoMappingContext();
        context.setInitialEntitySet((new EntityScanner(this.applicationContext)).scan(new Class[]{Document.class, Persistent.class}));
        Class<?> strategyClass = this.properties.getFieldNamingStrategy();
        if (strategyClass != null) {
            context.setFieldNamingStrategy((FieldNamingStrategy)BeanUtils.instantiate(strategyClass));
        }

        context.setSimpleTypeHolder(conversions.getSimpleTypeHolder());
        return context;
    }

    @Bean
    @ConditionalOnMissingBean
    public GridFsTemplate gridFsTemplate(MongoDbFactory mongoDbFactory, MongoTemplate mongoTemplate) {
        return new GridFsTemplate(new MongoDataAutoConfiguration.GridFsMongoDbFactory(mongoDbFactory, this.properties), mongoTemplate.getConverter());
    }

    @Bean
    @ConditionalOnMissingBean
    public CustomConversions mongoCustomConversions() {
        return new CustomConversions(Collections.emptyList());
    }

    private 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;
        }

        public DB getDb() throws DataAccessException {
            String gridFsDatabase = this.properties.getGridFsDatabase();
            return StringUtils.hasText(gridFsDatabase) ? this.mongoDbFactory.getDb(gridFsDatabase) : this.mongoDbFactory.getDb();
        }

        public DB getDb(String dbName) throws DataAccessException {
            return this.mongoDbFactory.getDb(dbName);
        }

        public PersistenceExceptionTranslator getExceptionTranslator() {
            return this.mongoDbFactory.getExceptionTranslator();
        }
    }
}