Spring 誕生時是 Java 企業版(Java Enterprise Edition,JEE,也稱 J2EE)的輕量級代替品。無需開發重量級的 Enterprise JavaBean(EJB),Spring 爲企業級Java 開發提供了一種相對簡單的方法,經過依賴注入和麪向切面編程,用簡單的Java 對象(Plain Old Java Object,POJO)實現了 EJB 的功能。html
雖然 Spring 的組件代碼是輕量級的,但它的配置倒是重量級的。一開始,Spring 用 XML 配置,並且是不少 XML 配置。Spring 2.5 引入了基於註解的組件掃描,這消除了大量針對應用程序自身組件的顯式 XML 配置。Spring 3.0 引入了基於 Java 的配置,這是一種類型安全的可重構配置方式,能夠代替 XML。全部這些配置都表明了開發時的損耗。由於在思考 Spring 特性配置和解決業務問題之間須要進行思惟切換,因此寫配置擠佔了寫應用程序邏輯的時間。和全部框架同樣,Spring 實用,但與此同時它要求的回報也很多。java
除此以外,項目的依賴管理也是件吃力不討好的事情。決定項目裏要用哪些庫就已經夠讓人頭痛的了,你還要知道這些庫的哪一個版本和其餘庫不會有衝突,這難題實在太棘手。而且,依賴管理也是一種損耗,添加依賴不是寫應用程序代碼。一旦選錯了依賴的版本,隨之而來的不兼容問題毫無疑問會是生產力殺手。web
Spring Boot 讓這一切成爲了過去。spring
Spring Boot 是 Spring 社區較新的一個項目。該項目的目的是幫助開發者更容易的建立基於 Spring 的應用程序和服務,讓更多人的人更快的對 Spring 進行入門體驗,爲 Spring 生態系統提供了一種固定的、約定優於配置風格的框架。編程
Spring Boot 具備以下特性:json
(1)爲基於 Spring 的開發提供更快的入門體驗瀏覽器
(2)開箱即用,沒有代碼生成,也無需 XML 配置。同時也能夠修改默認值來知足特定的需求。安全
(3)提供了一些大型項目中常見的非功能性特性,如嵌入式服務器、安全、指標,健康檢測、外部配置等。springboot
(4)Spring Boot 並非對 Spring 功能上的加強,而是提供了一種快速使用 Spring 的方式。服務器
建立Maven工程 springboot_demo(打包方式jar)
在pom.xml中添加以下依賴
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.4.0.RELEASE</version> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> </dependencies>
咱們會驚奇地發現,咱們的工程自動添加了好多好多jar包
而這些jar包正是咱們作開發時須要導入的jar包。由於這些jar包被咱們剛纔引入的spring-boot-starter-web所引用了,因此咱們引用spring-boot-starter-web後會自動把依賴傳遞過來。
/** * @SpringBootApplication 來標註一個主程序類,說明這是一個Spring Boot應用 */ @SpringBootApplication public class HelloWorldMainApplication { public static void main(String[] args) { // Spring應用啓動起來 SpringApplication.run(HelloWorldMainApplication.class,args); } }
咱們直接執行這個引導類,會發現控制檯出現的這個標識
咱們如今開始使用spring MVC框架,實現json數據的輸出。若是按照咱們原來的作法,須要在web.xml中添加一個DispatcherServlet的配置,還須要添加一個spring的配置文件(springmvc.xml)。
可是咱們用SpringBoot,這一切都省了。咱們直接寫Controller類
@RestController public class HelloWordController { @RequestMapping("/info") public String info() { return "HelloWorld"; } }
咱們運行啓動類來運行程序
在瀏覽器地址欄輸入 http://localhost:8080/info 便可看到運行結果
在pom.xml中添加
<!-- 這個插件,能夠將應用打包成一個可執行的jar包;--> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build>
執行package命令,將項目打包成jar包
在命令行中直接使用java -jar進行執行
【父項目】
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.9.RELEASE</version> </parent>
跟進<artifactId>spring-boot-starter-parent</artifactId>,發現它的父項目是
他來真正管理Spring Boot應用裏面的全部依賴版本,至關於Spring Boot的版本仲裁中心,之後咱們導入依賴默認是不須要寫版本;(沒有在dependencies裏面管理的依賴天然須要聲明版本號)
【啓動器】
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
spring-boot-starter:spring-boot場景啓動器;幫咱們導入了web模塊正常運行所依賴的組件;
Spring Boot將全部的功能場景都抽取出來,作成一個個的starters(啓動器),只須要在項目裏面引入這些starter相關場景的全部依賴都會導入進來。要用什麼功能就導入什麼場景的啓動器
/** * @SpringBootApplication 來標註一個主程序類,說明這是一個Spring Boot應用 */ @SpringBootApplication public class HelloWorldMainApplication { public static void main(String[] args) { // Spring應用啓動起來 SpringApplication.run(HelloWorldMainApplication.class,args); } }
SpringBootApplication背後的祕密
@SpringBootApplication註解是Spring Boot的核心註解,它標註在某個類上說明這個類是SpringBoot的主配置類,SpringBoot就應該運行這個類的main方法來啓動SpringBoot應用;@SpringBootApplication實際上是一個組合註解:
雖然定義使用了多個Annotation進行了原信息標註,但實際上重要的只有三個Annotation:
即 @SpringBootApplication = (默認屬性)@Configuration + @EnableAutoConfiguration + @ComponentScan。
因此,若是咱們使用以下的SpringBoot啓動類,整個SpringBoot應用依然能夠與以前的啓動類功能對等:
@Configuration @EnableAutoConfiguration @ComponentScan public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }
每次寫這3個比較累,因此寫一個@SpringBootApplication方便點。接下來分別介紹這3個Annotation。
【@Configuration】
這裏的@Configuration對咱們來講不陌生,它就是JavaConfig形式的Spring Ioc容器的配置類使用的那個@Configuration,SpringBoot社區推薦使用基於JavaConfig的配置形式,因此,這裏的啓動類標註了@Configuration以後,自己其實也是一個IoC容器的配置類。
舉幾個簡單例子回顧下,XML跟config配置方式的區別:
(1)表達形式層面
基於XML配置的方式是這樣:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd" default-lazy-init="true"> <!--bean定義--> </beans>
而基於JavaConfig的配置方式是這樣:
@Configuration public class MockConfiguration{ //bean定義 }
任何一個標註了@Configuration的Java類定義都是一個JavaConfig配置類。
(2)註冊bean定義層面
基於XML的配置形式是這樣:
<bean id="mockService" class="..MockServiceImpl"> ... </bean>
而基於JavaConfig的配置形式是這樣的:
@Configuration public class MockConfiguration{ @Bean public MockService mockService(){ return new MockServiceImpl(); } }
任何一個標註了@Bean的方法,其返回值將做爲一個bean定義註冊到Spring的IoC容器,方法名將默認成該bean定義的id。
(3)表達依賴注入關係層面
爲了表達bean與bean之間的依賴關係,在XML形式中通常是這樣:
<bean id="mockService" class="..MockServiceImpl"> <propery name ="dependencyService" ref="dependencyService" /> </bean> <bean id="dependencyService" class="DependencyServiceImpl"></bean>
而基於JavaConfig的配置形式是這樣的:
@Configuration public class MockConfiguration{ @Bean public MockService mockService(){ return new MockServiceImpl(dependencyService()); } @Bean public DependencyService dependencyService(){ return new DependencyServiceImpl(); } }
若是一個bean的定義依賴其餘bean,則直接調用對應的JavaConfig類中依賴bean的建立方法就能夠了。
提到@Configuration就要提到他的搭檔@Bean。使用這兩個註解就能夠建立一個簡單的spring配置類,能夠用來替代相應的xml配置文件。
<beans> <bean id = "car" class="com.test.Car"> <property name="wheel" ref = "wheel"></property> </bean> <bean id = "wheel" class="com.test.Wheel"></bean> </beans>
至關於:
@Configuration public class Conf { @Bean public Car car() { Car car = new Car(); car.setWheel(wheel()); return car; } @Bean public Wheel wheel() { return new Wheel(); } }
@Configuration的註解類標識這個類可使用Spring IoC容器做爲bean定義的來源。
@Bean註解告訴Spring,一個帶有@Bean的註解方法將返回一個對象,該對象應該被註冊爲在Spring應用程序上下文中的bean。
【@ComponentScan】
@ComponentScan這個註解在Spring中很重要,它對應XML配置中的元素,@ComponentScan的功能其實就是自動掃描並加載符合條件的組件(好比@Component和@Repository等)或者bean定義,最終將這些bean定義加載到IoC容器中。
咱們能夠經過basePackages等屬性來細粒度的定製@ComponentScan自動掃描的範圍,若是不指定,則默認Spring框架實現會從聲明@ComponentScan所在類的package進行掃描。
注:因此SpringBoot的啓動類最好是放在root package下,由於默認不指定basePackages。
【@EnableAutoConfiguration】
我的感受@EnableAutoConfiguration這個Annotation最爲重要,因此放在最後來解讀,你們是否還記得Spring框架提供的各類名字爲@Enable開頭的Annotation定義?好比@EnableScheduling、@EnableCaching、@EnableMBeanExport等,@EnableAutoConfiguration的理念和作事方式其實一脈相承,簡單歸納一下就是,藉助@Import的支持,收集和註冊特定場景相關的bean定義。
而@EnableAutoConfiguration也是藉助@Import的幫助,將全部符合自動配置條件的bean定義加載到IoC容器,僅此而已!之前咱們須要配置的東西,Spring Boot幫咱們自動配置;@EnableAutoConfiguration告訴SpringBoot開啓自動配置功能,這樣自動配置才能生效;
@EnableAutoConfiguration會根據類路徑中的jar依賴爲項目進行自動配置,如:添加了spring-boot-starter-web依賴,會自動添加Tomcat和Spring MVC的依賴,Spring Boot會對Tomcat和Spring MVC進行自動配置。
@EnableAutoConfiguration做爲一個複合Annotation,其自身定義關鍵信息以下:
(1)
@Import(AutoConfigurationPackages.Registrar.class):Spring的底層註解@Import,給容器中導入一個組件;導入的組件由AutoConfigurationPackages.Registrar.class將主配置類(@SpringBootApplication標註的類)的所在包及下面全部子包裏面的全部組件掃描到Spring容器;經過打斷點的方式,能夠看出:
(2)@Import(AutoConfigurationImportSelector.class),藉助AutoConfigurationImportSelector,@EnableAutoConfiguration告訴咱們SpringBoot給容器中導入哪些組件。將全部須要導入的組件以全類名的方式返回;這些組件就會被添加到容器中;
就像一隻「八爪魚」同樣,藉助於Spring框架原有的一個工具類:SpringFactoriesLoader的支持,@EnableAutoConfiguration能夠智能的自動配置功效才得以大功告成!
自動配置幕後英雄:SpringFactoriesLoader詳解
SpringFactoriesLoader屬於Spring框架私有的一種擴展方案,其主要功能就是從指定的配置文件META-INF/spring.factories加載配置。
配合@EnableAutoConfiguration使用的話,它更可能是提供一種配置查找的功能支持,即根據@EnableAutoConfiguration的完整類名org.springframework.boot.autoconfigure.EnableAutoConfiguration做爲查找的Key,獲取對應的一組@Configuration類。
上圖就是從SpringBoot的autoconfigure依賴包中的META-INF/spring.factories配置文件中摘錄的一段內容,能夠很好地說明問題。
因此,@EnableAutoConfiguration自動配置的魔法騎士就變成了:從classpath中搜尋全部的META-INF/spring.factories配置文件,並將其中org.springframework.boot.autoconfigure.EnableutoConfiguration對應的配置項經過反射(Java Refletion)實例化爲對應的標註了@Configuration的JavaConfig形式的IoC容器配置類,而後彙總爲一個並加載到IoC容器。