SpringBoot快速開發REST服務最佳實踐

来源:https://www.cnblogs.com/jeffwongishandsome/archive/2018/03/26/quick-develop-rest-api-by-using-spring-boot.html
-Advertisement-
Play Games

一、為什麼選擇SpringBoot Spring Boot是由Pivotal團隊提供的全新框架,被很多業內資深人士認為是可能改變游戲規則的新項目。早期我們搭建一個SSH或者Spring Web應用,需要非常繁瑣的步驟,比如配置web.xml,配置資料庫連接,配置事務,配置日誌,配置Tomcat,裝配 ...


一、為什麼選擇SpringBoot

Spring Boot是由Pivotal團隊提供的全新框架,被很多業內資深人士認為是可能改變游戲規則的新項目。早期我們搭建一個SSH或者Spring Web應用,需要非常繁瑣的步驟,比如配置web.xml,配置資料庫連接,配置事務,配置日誌,配置Tomcat,裝配Bean,聲明和配置切麵等等等等,如果項目過大多人協作各種冗長啰嗦的配置讓人煩不勝煩,這麼多年下來,給人一種Java就是大型配置文件的感覺。

SpringBoot的設計目的是用來簡化新Spring應用的初始搭建以及開發過程,吸引更多開發者的最大亮點之一是集成了自動配置的魔力。SpringBoot的四個主要新特性如下:

1、Spring Boot Starter:它將常用的依賴分組進行了整合, 將其合併到一個依賴中, 這樣就可以一次性添加到項目的Maven或Gradle構建中;Spring Boot通過提供眾多起步依賴降低項目依賴的複雜度。起步依賴本質上是一個Maven項目對象模型(Project Object Model, POM),定義了對其他庫的傳遞依賴,這些東西加在一起即支持某項功能。很多起步依賴的命名都暗示了它們提供的某種或某類功能。Spring Boot經過了足夠的測試,確保引入的全部依賴都能相互相容。這是一種解脫,只需指定起步依賴,不用擔心自己需要維護哪些庫,也不必擔心它們的版本。
2、自動配置:Spring Boot的自動配置特性利用了Spring 4對條件化配置的支持, 合理地推測應用所需的bean並自動化配置它們;最後, Spring Boot沒有引入任何形式的代碼生成,而是利用了Spring 4的條件化配置特性,以及Maven和Gradle提供的傳遞依賴解析,以此實現Spring應用程式上下文里的自動配置。簡而言之, Spring Boot的自動配置是一個運行時(更準確地說,是應用程式啟動時)的過程,考慮了眾多因素,才決定Spring配置應該用哪個,不該用哪個。每當應用程式啟動的時候, Spring Boot的自動配置都要做將近200個這樣的決定,涵蓋安全、集成、持久化、 Web開發等諸多方面。所有這些自動配置就是為了儘量不讓你自己寫配置。
3、命令行介面(Command-line interface, CLI):Spring Boot的CLI發揮了Groovy編程語言的優勢, 並結合自動配置進一步簡化Spring應用的開發;
4、Actuator: 它為Spring Boot應用添加了一定的管理特性。

常見的搭建一個SpringBoot應用只要如下幾步:

1、打開http://start.spring.io/

2、點擊“Switch to the full version,選擇Java版本,如1.8,選擇好構建工具,如Maven或Gradle

4、點擊Generate Project下載項目壓縮包

5、解壓後,使用eclipse或者intellij idea,導入項目即可

當然,對於經驗豐富的老鳥,不需要打開網頁再下載解壓導入文件那麼多步驟,通過Idea也可以一步一步構造SpringBoot項目。

二、工程結構

官方生成的SpringBoot項目,預設結構說明:

1、src/main/java  程式開發以及主程式入口
2、src/main/resources 配置文件
3、src/test/java  測試程式

src/main/java根目錄下麵,有如下Java類和包:

1、Application.java 應用程式入口,包括一個靜態main方法,可以做一些框架配置,比如mybatis、swagger等
2、domain目錄主要用於數據訪問實體(DataObject)與數據訪問層(Repository)
3、service目錄主要是業務邏輯相關的服務介面和實現
4、controller負責頁面訪問控制,對外暴露API

當然,我們需要參考成熟的項目結構或者根據個人經驗來改造項目結構,本文的SpringBootDemo為了方便僅做簡單調整,項目結構如下:

主要包說明:

公共模塊

1、common:公共類,如枚舉,常量、業務無關的通用公共實體等

2、util:常用實用的幫助類,如反射、字元串、集合、枚舉、正則、緩存、隊列等

3、config:自定義的配置項,可從配置文件讀取

表現層

1、controller:負責頁面訪問控制,對外暴露Rest API介面

數據訪問層

1、domain:數據對象實體DO,通常和數據表、視圖或其他業務對象一一對應

2、dao:數據訪問對象,本文demo選擇比較熟悉的mybatis作為ORM工具

業務邏輯層

1、service:服務 contract是介面,impl是服務實現

2、entity:實體 vo是服務可對外公開的實體;dto是數據傳輸對象,可在服務間傳遞;qo:查詢對象,可以認為是查詢條件的封裝

本文demo沒有寫dto和qo示例,很多中小型項目,entity其實是非常混亂的,實體設計和分層抽象有問題,有時候直接影響到業務邏輯複雜程度。

關於工程結構,尤其是應用分層和領域實體抽象(數據訪問對象DO和顯示層對象VO等),強烈推薦大家參考<<阿裡巴巴Java開發手冊>>終極版本的工程結構一章。

 

三、MyBatis使用

Maven依賴:

        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>1.2.0</version>
        </dependency>
View Code

資料庫驅動:

MySQL:

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.39</version>
        </dependency>
View Code

SQLServer:

        <dependency>
            <groupId>com.microsoft.sqlserver</groupId>
            <artifactId>mssql-jdbc</artifactId>
            <version>6.4.0.jre8</version>
        </dependency>
View Code

隆重公告,微軟Microsoft JDBC Driver For SQL Server已發佈到maven中央倉庫,本文的demo選擇的是SQLServer,主要是MySQL很多人都寫了,資料太充足,不如試試不同的風格,而且我在前廠寫的第一個線上SpringBoot應用也是訪問SQLServer,demo就哪個好舉例就用哪個了。

配置文件中的配置:

## MYSQL數據源配置
#spring.datasource.url=jdbc:mysql://localhost:3306/springbootdb?useUnicode=true&characterEncoding=utf8
#spring.datasource.username=root
#spring.datasource.password=123456
#spring.datasource.driver-class-name=com.mysql.jdbc.Driver

## MSSQL數據源配置
spring.datasource.url=jdbc:sqlserver://localhost;databaseName=TestDB
spring.datasource.username=sa
spring.datasource.password=123456
spring.datasource.driverClassName=com.microsoft.sqlserver.jdbc.SQLServerDriver
spring.jpa.show-sql=true
spring.jpa.hibernate.dialect=org.hibernate.dialect.SQLServer2012Dialect
#spring.jpa.hibernate.ddl-auto = create-drop

## Mybatis 配置
mybatis.typeAliasesPackage=com.power.demo.domain
mybatis.mapperLocations=classpath:mapper/*.xml
View Code

Mapper配置:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.power.demo.dao.GoodsDao">
    <resultMap id="BaseResultMap" type="com.power.demo.domain.GoodsDO">
        <result column="GoodsId" property="goodsId"/>
        <result column="GoodsCode" property="goodsCode"/>
        <result column="GoodsName" property="goodsName"/>
        <result column="GoodsType" property="goodsType"/>
        <result column="CreateTime" property="createTime"/>
        <result column="Disabled" property="disabled"/>
    </resultMap>

    <parameterMap id="Goods" type="com.power.demo.domain.GoodsDO"/>

    <sql id="Base_Column_List">
        GoodsId,GoodsCode,GoodsName,GoodsType,CreateTime,Disabled
    </sql>

    <select id="findGoodsByGoodsId" resultType="GoodsDO" parameterType="java.lang.String">
        SELECT
        <include refid="Base_Column_List"/>
        FROM Goods WITH(NOLOCK) WHERE 1=1
        AND Disabled=0
        AND GoodsId = #{goodsId}
    </select>

    <select id="findGoodsByGoodsCode" resultType="GoodsDO" parameterType="java.lang.String">
        SELECT
        <include refid="Base_Column_List"/>
        FROM Goods WITH(NOLOCK) WHERE 1=1
        AND Disabled=0
        AND GoodsCode = #{goodsCode}
    </select>

    <select id="findGoodsByGoodsType" resultType="GoodsDO" parameterType="java.lang.Integer">
        SELECT
        <include refid="Base_Column_List"/>
        FROM Goods WITH(NOLOCK) WHERE 1=1
        AND Disabled=0
        AND GoodsType = #{goodsType}
    </select>

    <select id="findAllGoods" resultType="GoodsDO">
        SELECT
        <include refid="Base_Column_List"/>
        FROM Goods WITH(NOLOCK) WHERE 1=1
    </select>

    <insert id="insertGoods" parameterMap="Goods">

        INSERT INTO Goods (GoodsId,GoodsCode,GoodsName,GoodsType,CreateTime,Disabled)
        VALUES(#{goodsId},#{goodsCode},#{goodsName},#{goodsType},#{createTime},#{disabled})

    </insert>

    <insert id="updateGoods" parameterMap="Goods">

        UPDATE Goods SET Disabled=#{disabled} WHERE GoodsId=#{goodsId}

    </insert>

    <insert id="deleteGoods" parameterType="java.lang.String">

        DELETE FROM Goods WHERE GoodsId=#{goodsId}

    </insert>

</mapper>
View Code

最後,在應用程式入口,添加一行註解:

// mapper 介面類掃描包配置
@MapperScan("com.power.demo.dao")
public class Application {
}

本文demo只提供了簡單的CRUD,但是常見的開發還有很多東西要寫。比如:

如何做多庫配置,如何動態拼接執行複雜SQL,如何批量插入,如何拿到運行時SQL語句,如何使用存儲過程,如何進行數據緩存、如何使用事務等。

這些遺留內容希望有心的你慢慢去發掘嘗試了。

推薦MyBatis代碼生成器:MyBatis Generator

四、API文檔描述

使用應用廣泛的Swagger,生成API文檔。

Maven中添加依賴:

        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>2.2.2</version>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <version>2.2.2</version>
        </dependency>
View Code

需要在應用程式入口Application裡面加一行註解:

@EnableSwagger2
public class Application {
}

 不要忘了Api說明和實體說明配置,demo提供了完整示例。

五、單元測試

使用Junit進行單元測試

/**
 * Created by JeffWong.
 */
@RunWith(SpringRunner.class)
@SpringBootTest
public class CommonTests {


    @Test
    public void testGoodsTypeEnum() throws Exception {

        GoodsType goodsType = GoodsType.Discount;

        System.out.println(GoodsType.Normal.ordinal());//0
        System.out.println(GoodsType.Discount.ordinal());//1

        System.out.println(goodsType.getCode());
        System.out.println(goodsType.getDescription());

        Assert.isTrue(goodsType.getCode() == 1024, "折扣商品Code為1024");


    }
}
View Code

如果需要單元測試的方法需要配置文件,那麼test下也要有resources目錄用於存放資源文件。

本文demo提供了完整的各層單元測試方法,大家可以參考下。

總結:使用SpringBoot全家桶,你可以快速上手開發Java的REST介面應用,配合Java8+的相關新特性,寫Java也越來越省心(雖然Java8的lamda比較難受,Checked Exception層層感染有點受不了,Date非常不好用-_-),聽說Java10要有var,估計還可以少寫很多代碼,而且VS也要支持Java了(不是J#),作為有豐富開發經驗的.NET開發者,也就更加有嘗試的衝動了。

最後提供demo下載

 

參考:

<<阿裡巴巴Java開發手冊>>

<<Spring in Action>>

<<Spring Boot in Action>>

https://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/htmlsingle/

https://www.jianshu.com/u/6a622d516e32

http://spring.io/


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 內容:守護線程、join方法#####################守護線程通過開啟線程之前調用setDaemon()方法,變成後臺線程,前臺線程運行完,後臺線程自動會結束#########例子 class Demo implements Runnable { private boolean fl ...
  • Java過濾器Filter使用詳解 過濾器 過濾器是處於客戶端與伺服器資源文件之間的一道過濾網,在訪問資源文件之前,通過一系列的過濾器對請求進行修改、判斷等,把不符合規則的請求在中途攔截或修改。也可以對響應進行過濾,攔截或修改響應。 如圖,瀏覽器發出的請求先遞交給第一個filter進行過濾,符合規則 ...
  • 1、目錄和文件的操作模塊os.path,在使用之前要先導入:import os.path。它主要有以下幾個重要的功能函數: ...
  • 我的目標是授人以漁,而不是授人以魚,我相信你仔細看完這篇文章,玩轉log4j不成問題 先來一個log4j最簡單的例子 在類路徑(src目錄下)創建log4j的配置文件log4j.properties,裡面的內容 運行一下,你會看到控制台有輸出,這就是一個最簡單的log4j配置的例子 來解釋一下這3行 ...
  • Beat Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 2184 Accepted Submission(s): 1256 Problem De ...
  • 編程語言主要從以下幾個角度為進行分類,編譯型和解釋型、靜態語言和動態語言、強類型定義語言和弱類型定義語言,每個分類代表什麼意思呢,我們一起來看一下。 編譯型vs解釋型 編譯型 優點:編譯器一般會有預編譯的過程對代碼進行優化。因為編譯只做一次,運行時不需要編譯,所以編譯型語言的程式執行效率高。可以脫離 ...
  • 前言: 必需學會SpringBoot基礎知識 簡介: spring cloud 為開發人員提供了快速構建分散式系統的一些工具,包括配置管理、服務發現、斷路器、路由、微代理、事件匯流排、全局鎖、決策競選、分散式會話等等。它運行環境簡單,可以在開發人員的電腦上跑。 工具: JDK8 apache-mave ...
  • 本文內容: 異常的介紹 處理異常 斷言 首發日期:2018-03-26 異常: 異常是程式運行中發生的錯誤,比較常見的比如“除零異常”,如果一個除數為零,那麼會發生這個異常 異常會影響程式的正常運行,所以我們需要處理異常。 所有的異常類是從 java.lang.Exception 類繼承的子類。 異 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...