02 整合IDEA+Maven+SSM框架的高併發的商品秒殺項目之Service層

来源:https://www.cnblogs.com/nnngu/archive/2018/01/29/8375748.html
-Advertisement-
Play Games

作者: "nnngu" 項目源代碼:https://github.com/nnngu/nguSeckill 首先在編寫 層代碼前,我們應該首先要知道這一層到底是乾什麼的。 層主要負責業務模塊的邏輯應用設計。同樣是首先設計介面,再設計其實現的類,接著在 的配置文件中配置其實現的關聯。這樣我們就可以在應 ...


作者:nnngu
項目源代碼:https://github.com/nnngu/nguSeckill


首先在編寫Service層代碼前,我們應該首先要知道這一層到底是乾什麼的。

Service層主要負責業務模塊的邏輯應用設計。同樣是首先設計介面,再設計其實現的類,接著在Spring的配置文件中配置其實現的關聯。這樣我們就可以在應用中調用Service介面來進行業務處理。Service層的業務實現,具體要調用到已定義的dao層的介面,封裝Service層的業務邏輯有利於通用的業務邏輯的獨立性和重覆利用性,程式顯得非常簡潔。

在項目中要降低耦合的話,分層是一種很好的概念,就是各層各司其職,儘量不做不相干的事,所以Service層的話顧名思義就是業務邏輯,處理程式中的一些業務邏輯,以及調用dao層的代碼,這裡我們的dao層就是連接資料庫的那一層,調用關係可以這樣表達:

View(頁面) > Controller(控制層) > Service(業務邏輯) > Dao(數據訪問) > Database(資料庫)

首先還是介面的設計,設計秒殺商品的介面,在com.nnngu.service.interfaces包下建立SeckillService.java介面文件,如下圖:

SeckillService.java文件裡面的內容請參照項目的源代碼。

建立好介面之後我們要寫實現類了,在寫實現類的時候我們肯定會碰到一個這樣的問題,你要向前端返回json數據的話,你是返回什麼樣的數據好?直接返回一個數字狀態碼或者文字?這樣設計肯定是不好的,所以我們應該向前端返回一個實體信息json,裡面包含了一系列的信息,無論是哪種狀態都應該可以應對,既然是與資料庫欄位無關的類,那就不是PO了,所以我們建立一個DTO數據傳輸類。關於常見的幾種對象我的解釋如下:

  • PO:也就是我們為每一張資料庫表寫一個實體類

  • VO:對某個頁面或者展現層所需要的數據,封裝成一個實體類

  • BO:業務對象

  • DTO:跟VO的概念有點混淆,也是相當於頁面需要的數據封裝成一個實體類

  • POJO:簡單的無規則java對象

在com.nnngu下建立dto包,然後建立Exposer類,這個類是秒殺時資料庫那邊處理的結果的對象

Exposer.java文件裡面的內容請參照項目的源代碼。

定義秒殺中可能會出現的異常

定義一個基礎的異常,所有的子異常繼承這個異常SeckillException

package com.nnngu.exception;

/**
 *  秒殺基礎的異常
 * Created by nnngu
 */
public class SeckillException extends RuntimeException {
    // 代碼省略,請參照項目的源代碼
    ... ...
}

可能會出現秒殺關閉後被秒殺情況,所以建立秒殺關閉異常SeckillCloseException,需要繼承我們前面寫的基礎異常

package com.nnngu.exception;

/**
 * 秒殺已經關閉異常,當秒殺結束就會出現這個異常
 * Created by nnngu
 */
public class SeckillCloseException extends SeckillException{
    // 代碼省略,請參照項目的源代碼
    ... ...
}

定義重覆秒殺異常RepeatKillException

package com.nnngu.exception;

/**
 * 重覆秒殺異常,不需要我們手動去try catch
 * Created by nnngu
 */
public class RepeatKillException extends SeckillException{
    // 代碼省略,請參照項目的源代碼
    ... ...
}

實現Service介面

com.nnngu.service包下創建SeckillServiceImpl.java類,具體代碼請參照項目的源代碼。

在這裡我們捕獲了運行時異常,這樣做的原因就是Spring的事務預設發生了RuntimeException才會回滾,可以檢測出來的異常是不會導致事務的回滾的,這樣的目的就是你明知道這裡會發生異常,所以你一定要進行處理。如果只是為了讓編譯通過的話,那捕獲異常也沒意思,所以這裡要註意事務的回滾。

然後我們還發現這裡存在硬編碼的現象,就是返回各種字元常量,例如秒殺成功,秒殺失敗等等,這些字元串是可以被重覆使用的,而且這樣維護起來也不方便,要到處去類裡面尋找這樣的字元串,所有我們使用枚舉類來管理這樣狀態,在con.nnngu包下建立enums包,專門放置枚舉類,然後再建立SeckillStatEnum枚舉類。

枚舉類SeckillStatEnum.java的代碼請參照項目的源代碼。

註入Service

resources/spring下建立applicationContext-service.xml文件,用來配置Service

applicationContext-service.xml的代碼請參照項目的源代碼。

在這裡開啟了基於註解的事務,常見的事務操作有以下幾種方法:

  • 在Spring早期版本中是使用ProxyFactoryBean+XMl方式來配置事務。

  • 在Spring配置文件使用tx:advice+aop命名空間,好處就是一次配置永久生效,你無須去關心中間出的問題,不過出錯了你很難找出在哪裡出了問題。

  • 註解@Transactional的方式,註解可以在方法定義,介面定義,類定義。可以在public方法上,但是不能註解在private、final、static等方法上,因為Spring的事務管理預設是使用cglib動態代理的:
  • private方法因為訪問許可權限制,無法被子類覆蓋
  • final方法無法被子類覆蓋
  • static時類級別的方法,無法被子類覆蓋
  • protected方法可以被子類覆蓋,因此可以被動態位元組碼增強

不能被Spring AOP事務增強的方法

序號 動態代理策略 不能被事務增強的方法
1 基於JDK的動態代理 除了public以外的所有方法,並且 public static 的方法也不能被增強
2 基於cglib的動態代理 privatestaticfinal 的方法

Service層的測試

添加測試類SeckillServiceImplTest.java,如下圖:

SeckillServiceImplTest.java的代碼請參照項目的源代碼。

測試結果:

測試的方法:public void getSeckillList()

測試結果如下圖:

到此,我們成功完成了Service層開發及測試。

下一篇:03 Java高併發秒殺項目之web層


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

-Advertisement-
Play Games
更多相關文章
  • 最近想找換一份工作,於是去面試了一家比較大的公司,以下是面試官問的幾個關於技術的面試題。 一.css裡面有個position,你知道它都有那幾個值嗎,以及它們的作用是什麼? 這個我回答的是: position一共有absolute,fixed,relative,static,inherit這幾個值, ...
  • A代碼編輯器,線上模版編輯,仿開發工具編輯器,pdf線上預覽,文件轉換編碼 B 集成代碼生成器 [正反雙向](單表、主表、明細表、樹形表,快速開發利器)+快速表單構建器 freemaker模版技術 ,0個代碼不用寫,生成完整的一個模塊,帶頁面、建表sql腳本,處理類,service等完整模塊 C 集 ...
  • 前文涉及到了很多與Leader相關的演算法,大家有木有想過,王侯將相,寧有種乎,既然Leader這麼麻煩,乾脆還是採用P2P模型吧,來個大家平等的架構。本篇需要和大家探討的就是多副本下實現民主政治的 Quorum機制 。至於它是怎麼樣解決我們在前文提及的各種問題的,接著這篇文章我們繼續聊聊~~ 1. ...
  • Redis的使用難嗎?不難,Redis用好容易嗎?不容易。Redis的使用雖然不難,但與業務結合的應用場景特別多、特別緊,用好並不容易。我們希望通過一篇文章及Demo,即可輕鬆、快速入門並學會應用。 一、Redis 簡介 Redis是一個開源的Key-Value存儲,但又不僅僅是Key-Value存 ...
  • server下的方法:bind() , listen(), accept(), recv(), send(bytes(String)), sendall(), client的方法:connect(), recv(), send(), sendall()### 建立通信的過程:創建socket,綁定i ...
  • 這個消息比較實用也很關鍵,它代表非顯示區域命中測試。這個消息優先於所有其他的顯示區域和非顯示區域滑鼠消息。其中lParam參數含有滑鼠位置的x和y屏幕坐標,wParam 這裡沒有用。 Windows應用程式通常把這個消息傳送給DefWindowProc,然後Windows用WM_NCHITTEST消 ...
  • 1、connect描述:實例連接到一個Redis.參數:host: string,port: int返回值:BOOL 成功返回:TRUE;失敗返回:FALSE示例:$redis = new redis(); $result = $redis->connect('127.0.0.1', 6379); ...
  • 因為每個枚舉常量只有一個實例,所以如果在比較兩個參考值,至少有一個涉及到枚舉常量時,允許使用“==”代替equals() ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...