Spring Boot入門

1、什麼是Spring Boot 

  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 的方式。服務器

2、Spring Boot之Hello World

2.1 添加起步依賴

  建立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後會自動把依賴傳遞過來。

2.2 編寫一個主程序

  編寫一個主程序,啓動Spring Boot應用

/**
 *  @SpringBootApplication 來標註一個主程序類,說明這是一個Spring Boot應用
 */
@SpringBootApplication
public class HelloWorldMainApplication {

    public static void main(String[] args) {

        // Spring應用啓動起來
        SpringApplication.run(HelloWorldMainApplication.class,args);
    }
}

   咱們直接執行這個引導類,會發現控制檯出現的這個標識

  

2.3 編寫相關的Controller

  咱們如今開始使用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 便可看到運行結果

2.4 簡化部署

  在pom.xml中添加

<!-- 這個插件,能夠將應用打包成一個可執行的jar包;-->
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

  執行package命令,將項目打包成jar包

 

  在命令行中直接使用java -jar進行執行

 

3、Hello World探討

3.1 POM文件

【父項目】

<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-web

  spring-boot-starter:spring-boot場景啓動器;幫咱們導入了web模塊正常運行所依賴的組件;

  Spring Boot將全部的功能場景都抽取出來,作成一個個的starters(啓動器),只須要在項目裏面引入這些starter相關場景的全部依賴都會導入進來。要用什麼功能就導入什麼場景的啓動器

 

3.2 啓動原理解析

/**
 *  @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:

  • @Configuration(@SpringBootConfiguration點開查看發現裏面仍是應用了@Configuration)
  • @EnableAutoConfiguration
  • @ComponentScan

  即 @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定義。

  • @EnableScheduling是經過@Import將Spring調度框架相關的bean定義都加載到IoC容器。
  • @EnableMBeanExport是經過@Import將JMX相關的bean定義加載到IoC容器。

  而@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)@AutoConfigurationPackage:自動配置包,跟進這個類:

  

  @Import(AutoConfigurationPackages.Registrar.class):Spring的底層註解@Import,給容器中導入一個組件;導入的組件由AutoConfigurationPackages.Registrar.class將主配置類(@SpringBootApplication標註的類)的所在包及下面全部子包裏面的全部組件掃描到Spring容器;經過打斷點的方式,能夠看出:

  (2)@Import(AutoConfigurationImportSelector.class),藉助AutoConfigurationImportSelector,@EnableAutoConfiguration告訴咱們SpringBoot給容器中導入哪些組件。將全部須要導入的組件以全類名的方式返回;這些組件就會被添加到容器中;會給容器中導入很是多的自動配置類(xxxAutoConfiguration);就是給容器中導入這個場景須要的全部組件,並配置好這些組件。有了自動配置類,免去了咱們手動編寫配置注入功能組件等的工做;

  就像一隻「八爪魚」同樣,藉助於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容器。

 

 

 

 

參考博文:http://www.javashuo.com/article/p-wslrskye-gp.html

相關文章
相關標籤/搜索