1. 程式人生 > >Spring Boot 2.X 來臨,本文將帶你起飛

Spring Boot 2.X 來臨,本文將帶你起飛

當前網際網路技術盛行,以Spring 框架為主導的Java 網際網路技術成了主流,而基於Spring 技術衍生出來的Spring Boot,採用了“約定優於配置”的思想,極大地簡化了Spring 框架的開發。

隨著近些年來微服務技術的流行,Spring Boot 也成了時下炙手可熱的熱點技術。2017 年9 月,Spring 框架出現了重大版本升級,從4.x 版本升級為了5.x 版本,隨著這次升級,Spring Boot的版本也在2018年3月從1.x升級到了2.x。

Spring Boot的優點

談到Spring Boot,就讓我們先來了解它的優點。依據官方的文件,Spring Boot的優點如下:

  • 建立獨立的Spring應用程式;

  • 嵌入的Tomcat、Jetty或者Undertow,無須部署WAR檔案;

  • 允許通過Maven來根據需要獲取starter;

  • 儘可能地自動配置Spring;

  • 提供生產就緒型功能,如指標、健康檢查和外部配置;

  • 絕對沒有程式碼生成,對XML沒有要求配置。

這段描述告訴我們,首先Spring Boot是一個基於Spring框架搭建起來的應用,其次它會嵌入Tomcat、Jetty或者Undertow等伺服器,並且不需要傳統的WAR檔案進行部署,也就是說搭建Spring Boot專案並不需要單獨下載Tomcat等傳統的伺服器。

同時提供通過Maven(或者Grandle)依賴的starter,這些starter可以直接獲取開發所需的相關包,通過這些starter專案就能以Java Application的形式執行Spring Boot的專案,而無須其他伺服器配置。

對於配置,Spring Boot提供Spring框架的最大自動化配置,大量使用自動配置,使得開發者對Spring的配置儘量減少。

此外還提供了一些監測、自動檢測的功能和外部配置,與此同時沒有附加程式碼和XML的配置要求。

約定優於配置,這是Spring Boot的主導思想。對於Spring Boot而言,大部分情況下存在預設配置,你甚至可以在沒有任何定義的情況下使用Spring框架,如果需要自定義也只需要在配置檔案配置一些屬性便可以,十分便捷。

而對於部署這些專案必需的功能,Spring Boot提供starter的依賴,例如,spring-boot-starter-web捆綁了Spring MVC所依賴的包,spring-boot-starter-tomcat綁定了內嵌的Tomcat,這樣使得開發者能夠儘可能快地搭建開發環境,快速進行開發和部署,這就是Spring Boot的特色。也許作為傳統開發者的你,還未能理解其意義,但這並不要緊。

為了展示Spring Boot的特色,下節將分別展示傳統Spring MVC專案和簡易的Spring Boot入門例項,並進行比較。

傳統Spring MVC和Spring Boot的對比

在傳統的Spring MVC專案開發中,開發一個簡易的Spring MVC專案,需要配置DispatcherServlet,也需要配置Spring IoC的容器。你可以選擇使用web.xml的配置來實現,當然,如果你使用的是Servlet 3.1規範,也可以繼承由Spring MVC提供的AbstractAnnotationConfigDispatcherServletInitializer來配置Spring MVC專案。

這裡先給出可以執行的程式碼示例,即使你還不熟悉Spring MVC也沒有關係,這裡只是為了說明開發比較煩瑣而已,後面將詳談Spring MVC的開發原理。

假設你已經匯入需要的Spring和Spring MVC相關的依賴包到工程中,那麼就可以開始配置DispatcherServlet了。例如,程式碼清單1-1就是通過繼承AbstractAnnotationConfigDispatcherServletInitializer的方式來配置Spring MVC的DispatcherServlet的。

程式碼清單1-1 配置Spring MVC

package com.springboot.springmvc.conf;

import  org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
public class MyWebAppInitializer   extends AbstractAnnotationConfigDispatcherServletInitializer {  
    // Spring IoC容器配置  
    @Override  
     protected Class<?>[] getRootConfigClasses() {  
         // 可以返回Spring的Java配置檔案陣列  
        return new Class<?>[] {};  
    }  
    // DispatcherServlet的URI對映關係配置  
    @Override  
    protected Class<?>[] getServletConfigClasses() {  
        // 可以返回Spring的Java配置檔案陣列  
        return new Class<?>[] { WebConfig.class };  
    }  
    // DispatcherServlet攔截請求匹配  
    @Override  
    protected String[] getServletMappings() {  
        return new String[] { "*.do" };  
    }  
}  

注意程式碼中加粗的地方。這裡引入了一個Java配置檔案—— WebConfig.java,它的主要作用是配置Spring MVC的核心類DispatcherServlet的上下文,如程式碼清單1-2所示。

程式碼清單1-2 配置DispatcherServlet的上下文

package com.springboot.springmvc.conf;
import java.util.ArrayList;
import java.util.List;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ComponentScan.Filter;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.http.MediaType;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.stereotype.Controller;
import org.springframework.web.servlet.HandlerAdapter;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;
import org.springframework.web.servlet.view.InternalResourceViewResolver;

@Configuration
// 定義Spring MVC掃描的包
@ComponentScan(value="com.*", 
includeFilters = {@Filter(type = FilterType.ANNOTATION,
       value = Controller.class)})
// 啟動Spring MVC配置
@EnableWebMvc
public class WebConfig {

    /***
     * 通過註解@Bean初始化檢視解析器
     * 
     * @return ViewResolver檢視解析器
     */
    @Bean(name = "internalResourceViewResolver")
    public ViewResolver initViewResolver() {
        InternalResourceViewResolver viewResolver 
          = new InternalResourceViewResolver();
        viewResolver.setPrefix("/WEB-INF/jsp/");
        viewResolver.setSuffix(".jsp");
        return viewResolver;
    }

    /**
     * 初始化RequestMappingHandlerAdapter,並載入HTTP的JSON轉換器
     * 
     * @return RequestMappingHandlerAdapter 物件
     */
    @Bean(name = "requestMappingHandlerAdapter")
    public HandlerAdapter initRequestMappingHandlerAdapter() {
        // 建立RequestMappingHandlerAdapter介面卡
        RequestMappingHandlerAdapter rmhd = new RequestMappingHandlerAdapter();
        // HTTP JSON轉換器
        MappingJackson2HttpMessageConverter jsonConverter 
          = new MappingJackson2HttpMessageConverter();
        // MappingJackson2HttpMessageConverter接收JSON型別訊息的轉換
        mediaType = MediaType.APPLICATION_JSON_UTF8;
        List<MediaType> mediaTypes = new ArrayList<MediaType>();
        mediaTypes.add(mediaType);
        // 加入轉換器的支援型別
        jsonConverter.setSupportedMediaTypes(mediaTypes);
        // 給介面卡加入JSON轉換器
        rmhd.getMessageConverters().add(jsonConverter);
        return rmhd;
    }
}

通過上面的程式碼,配置完成Spring MVC的開發環境後,才可以開發Spring MVC控制器Controller,這樣就可以開發一個簡單的控制器(Controller),如程式碼清單1-3所示。

程式碼清單1-3 開發Spring MVC控制器

package com.springboot.springmvc.controller;

import java.util.HashMap;
import java.util.Map;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class TestController {

    @RequestMapping("/test")
    @ResponseBody
    public Map<String, String> test() {
        Map<String, String> map = new HashMap<String, String>();
        map.put("key", "value");
        return map;
    }
}

這樣就完成了一個傳統Spring MVC的開發,但是你還需要第三方伺服器,如Tomcat、WebLogic等伺服器去部署你的工程。在啟動伺服器後,再開啟瀏覽器,輸入對應的URL,如專案名稱為SpringMVC則輸入http://localhost:8080/SpringMVC/test.do,就可以得到圖1-1所示的頁面。

 圖1-1 測試傳統的Spring MVC專案

從上面來看,傳統的Spring MVC開發需要配置的內容還是比較多的,而且對設計人員要求較高。開發完成後,開發者還需要找到對應的伺服器去執行,如Tomcat或者Jetty等,這樣既要進行開發,又要進行配置和部署,工作量還是不少的。

而使用Spring Boot開發後,你就會發現原來一切可以那麼簡單。不過在入門階段暫時不需要討論太多的細節問題,這是未來需要討論的問題,所以這裡只展示它是如何簡單而已。首先我們在IDE中建立一個Maven工程,並把其名稱定義為Chapter1,這樣就可以看到一個Maven配置檔案pom.xml,將其內容修改為如程式碼清單1-4所示。

程式碼清單1-4 配置Spring Boot依賴環境

<project xmlns="http://maven.apache.org/POM/4.0.0" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>springboot</groupId>
    <artifactId>chapter1</artifactId>
    <packaging>war</packaging>
    <version>0.0.1-SNAPSHOT</version>
    <name>chapter1 Maven Webapp</name>
    <url>http://maven.apache.org</url>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.0.RELEASE</version>
    </parent>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <!-- Spring Boot Starter依賴引入 -->
        <!-- AOP包 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>
        <!-- Web開發包,將載入Spring MVC所需要的包,且內嵌tomcat -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--載入測試依賴包 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
    <!-- 引入外掛 -->
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

從加粗的程式碼中可以看到Maven的配置檔案引入了多個Spring Boot的starter,Spring Boot會根據Maven配置的starter去尋找對應的依賴,將對應的jar包載入到工程中,而且它還會把繫結的伺服器也載入到工程中,這些都不需要你再進行處理。

正如Spring Boot承諾的那樣,繫結伺服器,並且實現Spring的儘可能的配置,採用約定優於配置的原則。這裡我們只需要開發一個類就可以執行Spring Boot的應用了,為此新建類——Chapter1Main,如程式碼清單1-5所示。

程式碼清單1-5 開發Spring Boot應用

package com.springboot.chapter1;

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

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
// 啟用Spring Boot自動裝配
@EnableAutoConfiguration
public class Chapter1Main {
    @RequestMapping("/test")
    @ResponseBody
    public Map<String, String> test() {
        Map<String, String> map = new HashMap<String, String>();
        map.put("key", "value");
        return map;
    }

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

好了,這個入門例項已經完結了。如果你沒有接觸過Spring Boot那麼你會十分驚訝,這樣就配置完成Spring MVC的內容了嗎?我可以回答你:“是的,已經完成了,現在完全可以使用Java Application的形式去執行類Chapter1Main。”下面是Spring Boot的執行日誌:

1 .   ____          _            __ _ _ 2 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \ 3( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \ 4 \\/  ___)| |_)| | | | | || (_| |  ) ) ) ) 5  '  |____| .__|_| |_|_| |_\__, | / / / / 6 =========|_|==============|___/=/_/_/_/ 7 :: Spring Boot ::        (v2.0.0.RELEASE) 8 92018-03-01 22:21:55.843  INFO 16324 --- [           main]  10com.springboot.chapter1.Chapter1Main     :  11Starting Chapter1Main on AFOIF-703271542 with PID 16324  12(G:\springboot\v2\chapter1\target\classes started by Administrator in  13G:\springboot\v2\chapter1) 14...... 152018-03-01 22:21:57.270  INFO 16324 --- [           main]  16s.w.s.m.m.a.RequestMappingHandlerMapping :  17Mapped "{[/test]}" onto public java.util.Map<java.lang.String, java.lang.String>  18com.springboot.chapter1.Chapter1Main.test() 19...... 202018-03-01 22:21:57.270  INFO 16324 --- [           main]  21com.springboot.chapter1.Chapter1Main : Started Chapter1Main in 1.845 seconds (JVM running for 2.143) 22

從日誌中可以看到,Tomcat已經啟動,並且將我們開發的Chapter1Main作為Spring MVC的控制器載入進來了,也將對應的路徑(/test)對映到開發的test方法上。因此,接下來就可以進行測試了。開啟瀏覽器,在位址列輸入http://localhost:8080/test,可以看到如圖1-2所示的結果。

圖1-2Spring Boot執行結果

與傳統的Spring MVC是不是很不一樣呢?從上面的對比可以看出,Spring Boot 允許直接進行開發,這就是它的優勢。在傳統所需要配置的地方,Spring Boot都進行了約定,也就是你可以直接以Spring Boot約定的方式進行開發和執行你的專案。

當你需要修改配置的時候,它也提供了一些快速配置的約定,猶如它所承諾的那樣,儘可能地配置好Spring專案和繫結對應的伺服器,使得開發人員的配置更少,更加直接地開發專案。

對於那些微服務而言,更喜歡的就是這樣能夠快速搭建環境的專案,而Spring Boot提供了這種可能性,同時Spring Boot還提供了監控的功能。

隨著雲技術的到來,微服務成了市場的熱點,於是代表Java微服務時代的Spring Boot微服務開發的時代已經到來,結合Spring Cloud後它還能很方便地構建分散式系統開發,滿足大部分無能力單獨開發分散式架構的企業所需,所以這無疑是激動人心的技術。