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(); } } }