Spring官方網站自己使用Spring框架開發,隨着功能以及業務邏輯的日益複雜,應用伴隨着大量的XML配置文件以及複雜的Bean依賴關係。隨着Spring 3.0的發佈,Spring IO團隊逐漸開始擺脫XML配置文件,而且在開發過程當中大量使用「約定優先配置」(convention over configuration)的思想來擺脫Spring框架中各種繁複紛雜的配置(即時是Java Config)。html
Spring Boot正是在這樣的一個背景下被抽象出來的開發框架,它自己並不提供Spring框架的核心特性以及擴展功能,只是用於快速、敏捷地開發新一代基於Spring框架的應用程序。也就是說,它並非用來替代Spring的解決方案,而是和Spring框架緊密結合用於提高Spring開發者體驗的工具。同時它集成了大量經常使用的第三方庫配置(例如Jackson, JDBC, Mongo, Redis, Mail等等),Spring Boot應用中這些第三方庫幾乎能夠零配置的開箱即用(out-of-the-box),大部分的Spring Boot應用都只須要很是少許的配置代碼,開發者可以更加專一於業務邏輯。mysql
傳統基於Spring的Java Web應用,須要配置web.xml
, applicationContext.xml
,將應用打成war包放入應用服務器(Tomcat, Jetty等)中並運行。若是基於Spring Boot,這一切都將變得簡單:react
以Maven項目爲例,首先引入Spring Boot的開發依賴:git
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.2.5.RELEASE</version> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> </dependencies>
編寫一個類包含處理HTTP請求的方法以及一個main()
函數:github
@Controller @EnableAutoConfiguration public class SampleController { @RequestMapping("/") @ResponseBody String home() { return "Hello World!"; } public static void main(String[] args) throws Exception { SpringApplication.run(SampleController.class, args); } }
啓動main函數後,在控制檯中能夠發現啓動了一個Tomcat容器,一個基於Spring MVC的應用也同時啓動起來,這時訪問http://localhost:8080
就能夠看到Hello World!
出如今瀏覽器中了。web
在Maven依賴中引入了spring-boot-starter-web
,它包含了Spring Boot預約義的一些Web開發的經常使用依賴:redis
spring-web
, spring-webmvc
Spring WebMvc框架tomcat-embed-*
內嵌Tomcat容器jackson
處理json數據spring-*
Spring框架spring-boot-autoconfigure
Spring Boot提供的自動配置功能Java代碼中沒有任何配置,和傳統的Spring應用相比,多了兩個咱們不認識的符號:spring
@EnableAutoConfiguration
SpringApplication
它們都是由Spring Boot框架提供。在SpringApplication.run()
方法執行後,Spring Boot的autoconfigure
發現這是一個Web應用(根據類路徑上的依賴肯定),因而在內嵌的Tomcat容器中啓動了一個Spring的應用上下文,而且監聽默認的tcp端口8080(默認約定)。同時在Spring Context中根據默認的約定配置了Spring WebMvc:sql
/
DispatherServlet
匹配的路徑(servlet-mapping
中的url-patterns
)是/*
@ComponentScan
路徑被默認設置爲SampleController
的同名package,也就是該package下的全部@Controller
,@Service
, @Component
, @Repository
都會被實例化後並加入Spring Context中。沒有一行配置代碼、也沒有web.xml
。基於Spring Boot的應用在大多數狀況下都不須要咱們去顯式地聲明各種配置,而是將最經常使用的默認配置做爲約定,在不聲明的狀況下也能適應大多數的開發場景。mongodb
除了最基本的Web框架,另外一種很是廣泛的開發場景是訪問數據庫。在傳統的Spring應用中,訪問數據庫咱們須要配置:
DataSource
對象,指定數據庫url
, username
, password
等信息JdbcTemplate
對象,若是使用Hibernate
,Mybatis
等框架,還須要進一步配置框架信息在Spring Boot中,上述過程會被簡化。首先在Maven項目依賴中定義:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web-jdbc</artifactId> </dependency> <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> </dependency>
spring-boot-starter-web-jdbc
引入了spring-jdbc
依賴,h2
是一個內存關係型數據庫。在引入了這些依賴並啓動Spring Boot應用程序後,autoconfigure
發現spring-jdbc
位於類路徑中,因而:
h2
,預約義了derby
, sqlite
, mysql
, oracle
, sqlserver
等等),建立一個DataSource
鏈接池對象,本例中的h2
是內存數據庫,無需任何配置,若是是mysql
, oracle
等類型的數據庫須要開發者配置相關信息。JdbcTemplate
對象(使用DataSource
初始化)接下來開發者的工做就很是簡單了,在業務邏輯中直接引入JdbcTemplate
便可:
@Service public class MyService { @Autowired JdbcTemplate jdbcTemplate; }
除了spring-jdbc
,Spring Boot還可以支持JPA,以及各類NoSQL數據庫——包括MongoDB,Redis,全文索引工具elasticsearch
, solr
等等。
Spring Boot最大的特點是「約定優先配置」,大量的默認配置對開發者十分的友好。可是在實際的應用開發過程當中,默認配置不可能知足全部場景,同時用戶也須要配置一些必須的配置項——例如數據庫鏈接信息。Spring Boot的配置系統可以讓開發者快速的覆蓋默認約定,同時支持Properties配置文件和YAML配置文件兩種格式,默認狀況下Spring Boot加載類路徑上的application.properties
或application.yml
文件,例如:
spring.datasource.url=jdbc:mysql://localhost/test spring.datasource.username=dbuser spring.datasource.password=dbpass spring.datasource.driver-class-name=com.mysql.jdbc.Driver
YAML格式更加簡潔:
spring: datasource: url: jdbc:mysql://localhost/test username: dbuser password: dbpass driver-class: com.mysql.jdbc.Driver
一旦發現這些信息,Spring Boot就會根據它們建立DataSource
對象。另外一個常見的配置場景是Web應用服務器:
# Server settings (ServerProperties) server: port: 8080 address: 127.0.0.1 sessionTimeout: 30 contextPath: / # Tomcat specifics tomcat: accessLogEnabled: false protocolHeader: x-forwarded-proto remoteIpHeader: x-forwarded-for basedir: backgroundProcessorDelay: 30 # secs
經過port
和address
能夠修改服務器監聽的地址和端口,sessionTimeout
配置session過時時間(不再用修改web.xml
了,由於它根本不存在)。同時若是在生產環境中使用內嵌Tomcat,固然但願可以配置它的日誌、線程池等信息,這些如今均可以經過Spring Boot的屬性文件配置,而再也不須要再對生產環境中的Tomcat實例進行單獨的配置管理了。
從Spring 3.0開始,爲了替代繁瑣的XML配置,引入了@Enable...
註解對@Configuration
類進行修飾以達到和XML配置相同的效果。想必很多開發者已經使用過相似註解:
@EnableTransactionManagement
開啓Spring事務管理,至關於XMl中的<tx:*>
@EnableWebMvc
使用Spring MVC框架的一些默認配置@EnableScheduling
會初始化一個Scheduler用於執行定時任務和異步任務Spring Boot提供的@EnableAutoCongiguration
彷佛功能更增強大,一旦加上,上述全部的配置彷佛都被包含進來而無需開發者顯式聲明。它到底是如何作到的呢,先看看它的定義:
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Import({ EnableAutoConfigurationImportSelector.class, AutoConfigurationPackages.Registrar.class }) public @interface EnableAutoConfiguration { /** * Exclude specific auto-configuration classes such that they will never be applied. */ Class<?>[] exclude() default {}; }
EnableAutoConfigurationImportSelector
使用的是spring-core
模塊中的SpringFactoriesLoader#loadFactoryNames()
方法,它的做用是在類路徑上掃描META-INF/spring.factories
文件中定義的類:
# Initializers org.springframework.context.ApplicationContextInitializer=\ org.springframework.boot.autoconfigure.logging.AutoConfigurationReportLoggingInitializer # Auto Configure org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\ org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration,\ org.springframework.boot.autoconfigure.MessageSourceAutoConfiguration,\ org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration,\ org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration,\ org.springframework.boot.autoconfigure.data.JpaRepositoriesAutoConfiguration,\ org.springframework.boot.autoconfigure.data.MongoRepositoriesAutoConfiguration,\ org.springframework.boot.autoconfigure.redis.RedisAutoConfiguration,\ org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,\ org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration,\ org.springframework.boot.autoconfigure.jms.JmsTemplateAutoConfiguration,\ org.springframework.boot.autoconfigure.jmx.JmxAutoConfiguration,\ org.springframework.boot.autoconfigure.mobile.DeviceResolverAutoConfiguration,\ org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration,\ org.springframework.boot.autoconfigure.mongo.MongoTemplateAutoConfiguration,\ org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration,\ org.springframework.boot.autoconfigure.reactor.ReactorAutoConfiguration,\ org.springframework.boot.autoconfigure.security.SecurityAutoConfiguration,\ org.springframework.boot.autoconfigure.security.FallbackWebSecurityAutoConfiguration,\ org.springframework.boot.autoconfigure.thymeleaf.ThymeleafAutoConfiguration,\ org.springframework.boot.autoconfigure.web.EmbeddedServletContainerAutoConfiguration,\ org.springframework.boot.autoconfigure.web.DispatcherServletAutoConfiguration,\ org.springframework.boot.autoconfigure.web.ServerPropertiesAutoConfiguration,\ org.springframework.boot.autoconfigure.web.MultipartAutoConfiguration,\ org.springframework.boot.autoconfigure.web.HttpMessageConvertersAutoConfiguration,\ org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration,\ org.springframework.boot.autoconfigure.websocket.WebSocketAutoConfiguration
實際上這就是Spring Boot會自動配置的一些對象,例如前面提到的Web框架由EmbeddedServletContainerAutoConfiguration
, DispatcherServletAutoConfiguration
, ServerPropertiesAutoConfiguration
等配置完成,而DataSource
的自動配置則是由DataSourceAutoConfiguration
完成。如今咱們以Mongo的配置MongoAutoConfiguration
爲例,來探索Spring Boot是如何完成這些配置的:
@Configuration @ConditionalOnClass(Mongo.class) @EnableConfigurationProperties(MongoProperties.class) public class MongoAutoConfiguration { @Autowired private MongoProperties properties; private Mongo mongo; @PreDestroy public void close() throws UnknownHostException { if (this.mongo != null) { this.mongo.close(); } } @Bean @ConditionalOnMissingBean public Mongo mongo() throws UnknownHostException { this.mongo = this.properties.createMongoClient(); return this.mongo; } }
首先這是一個Spring的配置@Configuration
,它定義了咱們訪問Mongo須要的@Bean
,若是這個@Configuration
被Spring Context掃描到,那麼Context中天然也就有兩個一個Mongo
對象可以直接爲開發者所用。
可是注意到其它幾個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就再也不建立。接下來看一看MongoProperties
:
@ConfigurationProperties(prefix = "spring.data.mongodb") public class MongoProperties { private String host; private int port = DBPort.PORT; private String uri = "mongodb://localhost/test"; private String database; // ... getters/ setters omitted }
顯然,它就是以spring.data.mongodb
做爲前綴的屬性,而後經過名字直接映射爲對象的屬性,同時還包含了一些默認值。若是不配置,那麼mongo.uri
就是mongodb://localhost/test
。
從前面的例子能夠看出,Spring Boot可以很是快速的作出一些原型應用,可是它一樣能夠被用於生產環境。爲了添加生產環境特性支持,須要在Maven依賴中引入:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency>
加入actuator
依賴後,應用啓動後會建立一些基於Web的Endpoint:
/autoconfig
,用來查看Spring Boot的框架自動配置信息,哪些被自動配置,哪些沒有,緣由是什麼。/beans
,顯示應用上下文的Bean列表/dump
,顯示線程dump信息/health
,應用健康情況檢查/metrics
/shutdown
, 默認沒有打開/trace
Spring Boot是新一代Spring應用的開發框架,它可以快速的進行應用開發,讓人忘記傳統的繁瑣配置,更加專一於業務邏輯。如今Spring官方文檔中全部的Guide中的例子都是使用Spring Boot進行構建,這也是一個學習Spring, Spring Boot很是好的地方。若是想進一步深度學習Spring Boot,能夠參考: