Spring Boot實戰:逐行釋義HelloWorld

1、前言java

   研究Spring boot也有一小段時間了,最近會將研究東西整理一下給你們分享,大概會有10~20篇左右的博客,整個系列會以一個簡單的博客系統做爲基礎,由於光講理論不少東西不是特別容易理解,而且若是每次經過一個簡單的小程序也沒法系統的把握好一些知識點,因此就以一個簡單的系統做爲基礎來說,看看經過spring boot如何實現一個完整系統。本系列除了Spring boot基本的知識點以外,還會涉及到Spring boot與數據庫、緩存(redis)、消息隊列等的結合以及多實例部署等方面的內容。有興趣的同窗能夠關注一下。web

2、Spring boot 簡介redis

   Spring boot 從名稱上就能夠看出,它是基於Spring的一個框架,因此不熟悉Spring的同窗仍是得先去學習一下Spring。其次,Spring boot幫咱們集成不少經常使用的功能,使得整個配置更加簡單。用過Spring的同窗應該知道,雖然Spring一直在努力的減小配置的複雜性,可是,配置一個徹底可用的(web)環境仍是挺麻煩的,好比須要配置日誌、數據庫、緩存等,而後再配置tomcat,最後將程序發佈到tomcat目錄下。而Spring boot則幫咱們大大簡化了這個過程,它提供了不少starter,只要引入對應的jar包就能夠了。例如,咱們須要集成tomcat,只須要引入tomcat的starter便可:spring

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-tomcat</artifactId>
</dependency>

  備註:本文的例子都是基於Maven來實現的,因此若是不熟悉Maven,能夠先去看下怎麼用,若是熟悉gradle的話,也能夠根據狀況對配置作相應調整。數據庫

  咱們能夠從官方文檔上查看Spring boot提供的starter:json

  這裏我只截取了一小部分,能夠看到Spring boot支持緩存、批處理、mq、es等等,完整的列表參考官方文檔。其餘就很少解釋了,後續經過示例來說解整個Spring boot功能,咱們先看Spring boot來如何實現一個web版的Hello World!小程序

3、Hello World程序緩存

  3.1 Hello World 源碼tomcat

  第一步:導入jar包架構

 <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.8.RELEASE</version>
    </parent>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>

  第二步:編寫控制器類  

package com.pandy.blog;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.HashMap;
import java.util.Map;

@Controller
public class HelloWorld {
    @RequestMapping("/hello")
    @ResponseBody
    public Map<String, Object> hello() {
        Map<String, Object> map = new HashMap<>();
        map.put("hello", "world");
        return map;
    }
}

  第三步:編寫啓動類(入庫)

package com.pandy.blog;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Application {

    public static void main(String[] args) throws Exception {
        SpringApplication.run(Application.class, args);
    }
}

 運行該類的main方法,而後訪問http://localhost:8080/hello,就能夠看到以下結果:

  是否是感受很開心?一行配置都沒有,就能夠直接運行一個Web應用。不過開心完之後有沒有想過這是怎麼實現的呢?接下來咱們一行一行解析上面的代碼,雖然行數很少,可是仍是有不少東西值得咱們去學習和理解的。

  3.2 pom文件分析

  咱們先從pom文件入手,pom文件裏面只引入了兩個依賴項。第一個是spring-boot-starter-parent,熟悉Maven的朋友應該知道,Maven也能夠跟類同樣,從父pom文件中繼承配置。咱們能夠看下spring-boot-starter-parent的pom文件,因爲篇幅問題,這裏面只看兩部分,其餘東西比較容易理解,你們能夠本身讀一下。第一個部分是:

  該文件又繼承了另外一個pom文件,即spring-boot-dependencies,這個文件其實就是包含了一大堆的jar,其做用是統一管理spring boot所依賴的jar包的版本,因此以後你們能夠看到,各個組件裏面引入jar的時候就再也不須要再指定版本號了。另外一個地方須要說明一下是配置文件的管理:

  你們能夠看到,默認狀況下會將/src/main/resources目錄下的文件做爲資源文件加入到classpath下,另外,這個地方的僅僅對application*.yml,application*.yaml,application*.properties三種文件進行過濾。這個過濾是指什麼呢?你們配置過spring mvc的人應該都知道,配置數據庫時,咱們一般將數據庫的信息配置在一個properties文件中,而後在spring的配置文件中經過<property name="driverClass" value="${jdbc.driver}" /> 的形式引入,這個filter的做用就是在編譯的時候將配置文件中配置的名值對替換到spring的配置文件中${xxx}字符,但這個功能不是必要的,即便不進行替換,Spring也能在運行時讀取到配置項。

  總結一下:spring-boot-starter-parent的做用::

  1)jar包的版本管理。

  2)配置文件的過濾。

  3)經常使用插件管理。

  spring-boot-starter-parent最核心的功能是管理了Spring boot所依賴的全部jar包。不過通parent的方式有一個很明顯的問題,不少公司本身有本身的parent文件,而maven是沒辦法配置多個parent的。若是不使用spring-boot-starter-parent,那應該怎麼作??實際上Spring boot提供了另外一種方式來解決這個問題,就是在本身的pom文件中加入spring boot的依賴的管理:

<dependencyManagement>
     <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>1.5.9.RELEASE</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

  其實從上面的分析能夠看到,這個也是spring-boot-starter-parent 的pom文件的parent,而這個pom文件裏面主要就是管理了一大堆的jar包版本。因此導入這個後,就不須要本身再去作版本管理,各個starter會本身根據須要導入對應的jar,但版本號由spring-boot-dependencies統一管理。可是這樣的話,spring-boot-starter-parent中的插件就沒法使用,而且默認配置文件的過濾功能也沒有了。不過這沒什麼影響,一方面這些功能不是必須的,另外一方面若是須要,本身添加也是件很容易的事情。  

  3.3 HelloWorld類解析:

  咱們再看下HelloWorld這個類,用過Spring mvc應該知道,其實這個類跟Spring boot沒半毛錢關係,業務代碼更是沒任何跟spring相關的東西,這也是spring一直奉行的一個原則,侵入性極小,這也是Spring成功的一個主要緣由。這個類裏面跟spring相關的是三個註解,即@Controller,@RequestMapping,@ResponseBody,可是這三個註解也都是Spring mvc提供的。跟Spring boot沒有太多聯繫,在這我就不細講了,若是不是很清楚,能夠去看下Spring MVC的內容,三個註解的基本做用以下:

  • Controller:標識爲一個控制器,spring會自動實例化該類。
  • RequestMapping:url映射。
  • ResponseBody:將返回結果自動轉換爲json串。

  3.4 Application類解析

  最後咱們看下Application這個類,你會發現這個類的東西更少,總共就一行有用的代碼,即SpringApplication.run(Application.class, args);這個方法的做用是加載Application這個類,那Application這個類有什麼特別之處嗎?能夠看一下,其實這個類的惟一特殊的地方是一個註解@SpringBootApplication,因此Spring boot的運行確定跟這個註解有着諸多的聯繫,咱們能夠看下這個註解的源碼:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = {
		@Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
		@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {

  該註解的主要方法就不說了,你們看下就知道,主要是爲上面這些註解提供別名。該註解上前四個註解(@Target(ElementType.TYPE),@Retention(RetentionPolicy.RUNTIME),@Documented,@Inherited)你們應該都知道,不熟悉的朋友本身去看下JDK如何實現自定義的註解。咱們詳細解釋一下後面三個註解:@SpringBootConfiguration,@EnableAutoConfiguration,@ComponentScan。

  先看一下SpringBootConfiguration,這個註解比較簡單,源碼以下:

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration
public @interface SpringBootConfiguration {
}

  這個註解僅僅是繼承了@Configuration,你們應該知道,Spring提供三種方式的配置:(1)xml文件配置(2)annotation配置(3)Java 類配置。而@Configuration就是用於標識一個類爲配置類的註解。Spring 4之後比較推崇經過Java類的方式來進行配置,因此Spring boot也傾向於這種方配置式。而且從源碼能夠看出,SpringBootConfiguration的做用就是標識類爲配置類。

  接下來咱們看一下@EnableAutoConfiguration註解,這個註解的源碼有點複雜,在這不作細講,後面的文章再詳細解析期實現方式。這裏說一下該註解的做用,它的主要功能是實現自動配置,什麼叫作自動配置?就是Spring boot會根據你引入的jar包作一些自動的配置,例如,在classpath有HSQLDB的jar,spring boot就會自動給你配置一個內存數據庫。在這個例子裏面咱們也能夠看到,由於咱們引入了Spring-mvc、tomcat等相關的jar,spring boot就會猜想你是一個web工程,而後就會自動作一些spring mvc的配置,好比對靜態資源的支持、將返回結果自動轉爲json格式數據的支持等。這些都是自動配置的結果。對Spring Enable*註解熟悉的同窗應該可以更容易理解這個註解,由於Spring中有不少相似的註解。

  最後咱們再看下@ComponentScan,這個註解不是Spring boot提供的,而是Spring提供的,Spring掃描的包或類,即哪些包和類會自動歸入Spring IoC容器的管理,IoC根據配置對這些類進行實例化。

   如今咱們再總結一下SpringBootConfiguration這個註解的做用:

  1)標誌該類爲一個配置類。
  2)指定掃描的包,便於Spring IoC容器對其進行實例和生命週期的管理。
  3)自動配置,經過引入的jar包,猜想用戶的意圖進行自動化配置。

4、總結

   本文詳細分析了Spring boot實現的一個web版的Hello World,經過這個例子,咱們瞭解了Spring boot的基本操做,並經過對每行的代碼的分析,對Spring boot的原理有了一個大體的瞭解。整體來說,Spring boot 統一管理了jar包,而後會根據咱們選擇的starter來進行自動化配置,經過這種方式來解決複雜的依賴管理,精簡配置,從而使得開發者可以更加專一於本身的業務,而不須要作那些很複雜的配置工做。同時,Spring boot這種快速、輕量級的服務也很是適合微服務架構,這個後續有機會再跟你們分享,歡迎繼續關注。

相關文章
相關標籤/搜索