成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

為什么從 MVC 到 DDD,架構(gòu)的本質(zhì)是什么?

開發(fā) 架構(gòu)
DDD 架構(gòu)的一種分層結(jié)構(gòu),也可以有其他種方式,核心的重點(diǎn)在于適合你所在場景的業(yè)務(wù)開發(fā)。以下的分層結(jié)構(gòu),是小傅哥在使用 DDD 架構(gòu)多種的方式開發(fā)代碼后,做了簡化和處理的。右側(cè)的連線是各個模塊的依賴關(guān)系。

今天要分享的是 MVC 和 DDD 的架構(gòu)本質(zhì),通過由淺入深的介紹講解和視頻帶著手把手操作創(chuàng)建工程架構(gòu)。讓無論是學(xué)習(xí) MVC 的小白碼農(nóng)還是希望了解更多關(guān)于 DDD 內(nèi)容的老白碼農(nóng),都可以學(xué)習(xí)到一點(diǎn)自己需要的內(nèi)容。

一、MVC 架構(gòu)

如果我們嘗試把編程的復(fù)雜架構(gòu)縮小到最容易理解的程度,那么編程開發(fā)其實(shí)只做3件事:”定義屬性、創(chuàng)建方法、調(diào)用展示“。但因?yàn)橥愃璧膬?nèi)容較多,如一系列的屬性,一堆的方法實(shí)現(xiàn),一組的接口封裝,那么就需要合理的把這些內(nèi)容分配到不同的層次中去實(shí)現(xiàn),因此有了分層架構(gòu)的設(shè)計(jì)。

那么本文小傅哥會向大家介紹一套MVC架構(gòu)的分層設(shè)計(jì)以及如何創(chuàng)建使用,并提供相應(yīng)的簡單的案例。你可以復(fù)制這套架構(gòu)在自己的場景中使用,也更能方便編程的小白可以更快的上手開發(fā)。

注意:此套MVC架構(gòu)模型適合提供HTTP服務(wù)的工程架構(gòu),適合簡單的小場景開發(fā)使用。特點(diǎn);輕便、簡單、學(xué)習(xí)成本低。

1. 編程三步

如果說你是一個特別小的玩具項(xiàng)目,你甚至可以把編程的3步寫到一個類里。但因?yàn)槟阕龅氖钦?jīng)項(xiàng)目,你的各種類;對象類、庫表類、方法類,就會成群結(jié)隊(duì)的來。如果你想把這些成群結(jié)隊(duì)的類的內(nèi)容,都寫到一個類里去,那么就是幾萬行的代碼了。—— 當(dāng)然你也可以吹牛逼,你一個人做過一個項(xiàng)目,這項(xiàng)目大到啥程度呢。就是有一個類里有上萬行代碼。

圖片圖片

所以,為了不至于讓一個類撐到爆??,需要把黃色的對象、綠色的方法、紅色的接口,都分配到不同的包結(jié)構(gòu)下。這就是你編碼人生中所接觸到的第一個解耦操作。

2. 分層框架

MVC 是一種非常常見且常用的分層架構(gòu),主要包括;M - mode 對象層,封裝到 domain 里。V - view 展示層,但因?yàn)槟壳岸际乔昂蠖朔蛛x的項(xiàng)目,幾乎不會在后端項(xiàng)目里寫 JSP 文件了。C - Controller 控制層,對外提供接口實(shí)現(xiàn)類。DAO 算是單獨(dú)拿出來用戶處理數(shù)據(jù)庫操作的層。

圖片圖片

  • 如圖,在 MVC 的分層架構(gòu)下。我們編程3步的所需各類對象、方法、接口,都分配到 MVC 的各個層次中去。
  • 因?yàn)檫@樣分層以后,就可以很清晰明了的知道各個層都在做什么內(nèi)容,也更加方便后續(xù)的維護(hù)和迭代。
  • 對于一個真正的項(xiàng)目來說,是沒有一錘子買賣的,最開始的開發(fā)遠(yuǎn)不是成本所在。最大的開發(fā)成本是后期的維護(hù)和迭代。而架構(gòu)設(shè)計(jì)的意義更多的就是在解決系統(tǒng)的反復(fù)的維護(hù)和迭代時,如何降低成本,這也是架構(gòu)分層的意義所在。

3. 調(diào)用流程

接下來我們再看下一套 MVC 架構(gòu)中各個模塊在調(diào)用時的串聯(lián)關(guān)系;

圖片圖片

  • 以用戶發(fā)起 HTTP 請求開始,Controller 在接收到請求后,調(diào)用由 Spring 注入到類里的 Service 方法,進(jìn)入 Service 方法后有些邏輯會走數(shù)據(jù)庫,有些邏輯是直接內(nèi)部自己處理后就直接返回給 Controller 了。最后由 Controller 封裝結(jié)果返回給 HTTP 響應(yīng)。
  • 同時我們也可以看到各個對象在這些請求間的一個作用,如;請求對象、庫表對象、返回對象。

4. 架構(gòu)源碼

4.1 環(huán)境

  • JDK 1.8
  • Maven 3.8.6 - 下載安裝maven后,本地記得配置阿里云鏡像,方便快速拉取jar包。源碼中 docs/maven/settings.xml 有阿里云鏡像地址。
  • SpringBoot 2.7.2
  • MySQL 5.7 - 如果你使用 8.0 記得更改 pom.xml 中的 mysql 引用

4.2 架構(gòu)

  • 源碼:https://gitcode.net/KnowledgePlanet/road-map/xfg-frame-mvc
  • 樹形:安裝 brew install tree IntelliJ IDEA Terminal 使用 tree
.
├── docs
│   └── mvc.drawio - 架構(gòu)文檔
├── pom.xml
├── src
│   ├── main
│   │   ├── java
│   │   │   └── cn
│   │   │       └── bugstack
│   │   │           └── xfg
│   │   │               └── frame
│   │   │                   ├── Application.java
│   │   │                   ├── common
│   │   │                   │   ├── Constants.java
│   │   │                   │   └── Result.java
│   │   │                   ├── controller
│   │   │                   │   └── UserController.java
│   │   │                   ├── dao
│   │   │                   │   └── IUserDao.java
│   │   │                   ├── domain
│   │   │                   │   ├── po
│   │   │                   │   │   └── User.java
│   │   │                   │   ├── req
│   │   │                   │   │   └── UserReq.java
│   │   │                   │   ├── res
│   │   │                   │   │   └── UserRes.java
│   │   │                   │   └── vo
│   │   │                   │       └── UserInfo.java
│   │   │                   └── service
│   │   │                       ├── IUserService.java
│   │   │                       └── impl
│   │   │                           └── UserServiceImpl.java
│   │   └── resources
│   │       ├── application.yml
│   │       └── mybatis
│   │           ├── config
│   │           │   └── mybatis-config.xml
│   │           └── mapper
│   │               └── User_Mapper.xml
│   └── test
│       └── java
│           └── cn
│               └── bugstack
│                   └── xfg
│                       └── frame
│                           └── test
│                               └── ApiTest.java
└── road-map.sql

以上是整個??工程架構(gòu)的 tree 樹形圖。整個工程由 SpringBoot 驅(qū)動。

  • Application.java 是啟動程序的 SpringBoot 應(yīng)用
  • common 是額外添加的一個層,用于定義通用的類
  • controller 控制層,提供接口實(shí)現(xiàn)。
  • dao 數(shù)據(jù)庫操作層
  • domain 對象定義層
  • service 服務(wù)實(shí)現(xiàn)層

5. 測試驗(yàn)證

  • 首先;整個工程由 SpringBoot 驅(qū)動,提供了 road-map.sql 測試 SQL 庫表語句。你可以在自己的本地mysql上進(jìn)行執(zhí)行。它會創(chuàng)建庫表。
  • 之后;在 application.yml 配置數(shù)據(jù)庫鏈接信息。
  • 之后就可以打開 ApiTest 進(jìn)行測試了。你可以點(diǎn)擊 Application 類的綠色箭頭啟動工程,使用 UserController 類提供接口的方式調(diào)用程序;http://localhost:8089/queryUserInfo

圖片圖片

- 如果你正常獲取了這樣的結(jié)果信息,那么說明你已經(jīng)啟動成功。接下來就可以對照著MVC的結(jié)構(gòu)進(jìn)行學(xué)習(xí),以及使用這樣的工程結(jié)構(gòu)開發(fā)自己的項(xiàng)目。

二、DDD 架構(gòu)

從最早接觸 DDD 架構(gòu),到后來用 DDD 架構(gòu)不斷的承接項(xiàng)目開發(fā),一次次在項(xiàng)目開發(fā)中的經(jīng)驗(yàn)積累。對 DDD 有了不少的理解。DDD 是一種思想,落地的形態(tài)和結(jié)構(gòu)會有不同的方式,甚至在編碼上也會有風(fēng)格的差異。但終期目標(biāo)就一個;”提供代碼的可維護(hù)性,降低迭代開發(fā)成本。“也是康威定律所述:”任何組織在設(shè)計(jì)一套系統(tǒng)時,所交付的設(shè)計(jì)方案在結(jié)構(gòu)上都與該組織的溝通結(jié)構(gòu)保持一致。“

但 DDD 與 MVC 相比的概率較多,貿(mào)然用理論驅(qū)動代碼開發(fā),會讓整個工程變得非常混亂,甚至可能雖然是用的 DDD 但最后寫出來了一片四不像的 MVC 代碼。所以對于程序員??????來說,先能上手一個工程,在從工程了解理論會更加容易。為此小傅哥想以此文,通過實(shí)戰(zhàn)編碼的方式向大家分享 DDD 架構(gòu),并能讓大家上手的 DDD 架構(gòu)。

1. 問題碰撞

你用 MVC 寫代碼,遇到過最大的問題是什么???

簡單、容易、好理解,是 MVC 架構(gòu)的特點(diǎn),但也正因?yàn)楹唵蔚姆謱舆壿嫞谶m配較復(fù)雜的場景并且需要長周期的維護(hù)時,代碼的迭代成本就會越來越高。如圖;

圖片圖片

  • 如果你接觸過較大型且已經(jīng)長期維護(hù)項(xiàng)目的 MVC 架構(gòu),你就會發(fā)現(xiàn)這里的 DAO、PO、VO 對象,在 Service 層相互調(diào)用。那么長期開發(fā)后,就導(dǎo)致了各個 PO 里的屬性字段數(shù)量都被撐的特別大。這樣的開發(fā)方式,將”狀態(tài)”、“行為“分離到不同的對象中,代碼的意圖漸漸模糊,膨脹、臃腫和不穩(wěn)定的架構(gòu),讓迭代成本增加。
  • 而 DDD 架構(gòu)首先以解決此類問題為主,將各個屬于自己領(lǐng)域范圍內(nèi)的行為和邏輯封裝到自己的領(lǐng)域包下處理。這也是 DDD 架構(gòu)設(shè)計(jì)的精髓之一。它希望在分治層面合理切割問題空間為更小規(guī)模的若干子問題,而問題越小就容易被理解和處理,做到高內(nèi)聚低耦合。這也是康威定律所提到的,解決復(fù)雜場景的設(shè)計(jì)主要分為:分治、抽象和知識。

2. 簡化理解

在給大家講解 MVC 架構(gòu)的時候,小傅哥提到了一個簡單的開發(fā)模型。開發(fā)代碼可以理解為:“定義屬性 -> 創(chuàng)建方法 -> 調(diào)用展示” 但這個模型結(jié)構(gòu)過于簡單,不太適合運(yùn)用了各類分布式技術(shù)棧以及更多邏輯的 DDD 架構(gòu)。所以在 DDD 這里,我們把開發(fā)代碼可以抽象為:“觸發(fā) -> 函數(shù) -> 連接” 如圖;

圖片圖片

  • DDD 架構(gòu)常用于微服務(wù)場景,因此也一個系統(tǒng)的調(diào)用方式就不只是 HTTP 還包括;RPC 遠(yuǎn)程、MQ 消息、TASK 任務(wù),因此這些種方式都可以理解為觸發(fā)。
  • 通過觸發(fā)調(diào)用函數(shù)方法,我們這里可以把各個服務(wù)都當(dāng)成一個函數(shù)方法來看。而函數(shù)方法通過連接,調(diào)用到其他的接口、數(shù)據(jù)庫、緩存來完成函數(shù)邏輯。

接下來,小傅哥在帶著大家把這些所需的模塊,拆分到對應(yīng)的DDD系統(tǒng)架構(gòu)中。

3. 架構(gòu)分層

如下是 DDD 架構(gòu)的一種分層結(jié)構(gòu),也可以有其他種方式,核心的重點(diǎn)在于適合你所在場景的業(yè)務(wù)開發(fā)。以下的分層結(jié)構(gòu),是小傅哥在使用 DDD 架構(gòu)多種的方式開發(fā)代碼后,做了簡化和處理的。右側(cè)的連線是各個模塊的依賴關(guān)系。接下來小傅哥就給大家做一下模塊的介紹。

圖片圖片

  • 接口定義 - xfg-frame-api:因?yàn)槲⒎?wù)中引用的 RPC 需要對外提供接口的描述信息,也就是調(diào)用方在使用的時候,需要引入 Jar 包,讓調(diào)用方好能依賴接口的定義做代理。
  • 應(yīng)用封裝 - xfg-frame-app:這是應(yīng)用啟動和配置的一層,如一些 aop 切面或者 config 配置,以及打包鏡像都是在這一層處理。你可以把它理解為專門為了啟動服務(wù)而存在的。
  • 領(lǐng)域封裝 - xfg-frame-domain:領(lǐng)域模型服務(wù),是一個非常重要的模塊。無論怎么做DDD的分層架構(gòu),domain 都是肯定存在的。在一層中會有一個個細(xì)分的領(lǐng)域服務(wù),在每個服務(wù)包中會有【模型、倉庫、服務(wù)】這樣3部分。
  • 倉儲服務(wù) - xfg-frame-infrastructure:基礎(chǔ)層依賴于 domain 領(lǐng)域?qū)樱驗(yàn)樵?domain 層定義了倉儲接口需要在基礎(chǔ)層實(shí)現(xiàn)。這是依賴倒置的一種設(shè)計(jì)方式。
  • 領(lǐng)域封裝 - xfg-frame-trigger:觸發(fā)器層,一般也被叫做 adapter 適配器層。用于提供接口實(shí)現(xiàn)、消息接收、任務(wù)執(zhí)行等。所以對于這樣的操作,小傅哥把它叫做觸發(fā)器層。
  • 類型定義 - xfg-frame-types:通用類型定義層,在我們的系統(tǒng)開發(fā)中,會有很多類型的定義,包括;基本的 Response、Constants 和枚舉。它會被其他的層進(jìn)行引用使用。
  • 領(lǐng)域編排【可選】 - xfg-frame-case:領(lǐng)域編排層,一般對于較大且復(fù)雜的的項(xiàng)目,為了更好的防腐和提供通用的服務(wù),一般會添加 case/application 層,用于對 domain 領(lǐng)域的邏輯進(jìn)行封裝組合處理。

4. 架構(gòu)源碼

4.1 環(huán)境

  • JDK 1.8
  • Maven 3.8.6
  • SpringBoot 2.7.2
  • MySQL 5.7 - 如果你使用 8.0 記得更改 pom.xml 中的 mysql 引用

4.2 架構(gòu)

  • 源碼:https://gitcode.net/KnowledgePlanet/road-map/xfg-frame-ddd
  • 樹形:安裝 brew install tree IntelliJ IDEA Terminal 使用 tree
.
├── README.md
├── docs
│   ├── dev-ops
│   │   ├── environment
│   │   │   └── environment-docker-compose.yml
│   │   ├── siege.sh
│   │   └── skywalking
│   │       └── skywalking-docker-compose.yml
│   ├── doc.md
│   ├── sql
│   │   └── road-map.sql
│   └── xfg-frame-ddd.drawio
├── pom.xml
├── xfg-frame-api
│   ├── pom.xml
│   ├── src
│   │   └── main
│   │       └── java
│   │           └── cn
│   │               └── bugstack
│   │                   └── xfg
│   │                       └── frame
│   │                           └── api
│   │                               ├── IAccountService.java
│   │                               ├── IRuleService.java
│   │                               ├── model
│   │                               │   ├── request
│   │                               │   │   └── DecisionMatterRequest.java
│   │                               │   └── response
│   │                               │       └── DecisionMatterResponse.java
│   │                               └── package-info.java
│   └── xfg-frame-api.iml
├── xfg-frame-app
│   ├── Dockerfile
│   ├── build.sh
│   ├── pom.xml
│   ├── src
│   │   ├── main
│   │   │   ├── bin
│   │   │   │   ├── start.sh
│   │   │   │   └── stop.sh
│   │   │   ├── java
│   │   │   │   └── cn
│   │   │   │       └── bugstack
│   │   │   │           └── xfg
│   │   │   │               └── frame
│   │   │   │                   ├── Application.java
│   │   │   │                   ├── aop
│   │   │   │                   │   ├── RateLimiterAop.java
│   │   │   │                   │   └── package-info.java
│   │   │   │                   └── config
│   │   │   │                       ├── RateLimiterAopConfig.java
│   │   │   │                       ├── RateLimiterAopConfigProperties.java
│   │   │   │                       ├── ThreadPoolConfig.java
│   │   │   │                       ├── ThreadPoolConfigProperties.java
│   │   │   │                       └── package-info.java
│   │   │   └── resources
│   │   │       ├── application-dev.yml
│   │   │       ├── application-prod.yml
│   │   │       ├── application-test.yml
│   │   │       ├── application.yml
│   │   │       ├── logback-spring.xml
│   │   │       └── mybatis
│   │   │           ├── config
│   │   │           │   └── mybatis-config.xml
│   │   │           └── mapper
│   │   │               ├── RuleTreeNodeLine_Mapper.xml
│   │   │               ├── RuleTreeNode_Mapper.xml
│   │   │               └── RuleTree_Mapper.xml
│   │   └── test
│   │       └── java
│   │           └── cn
│   │               └── bugstack
│   │                   └── xfg
│   │                       └── frame
│   │                           └── test
│   │                               └── ApiTest.java
│   └── xfg-frame-app.iml
├── xfg-frame-ddd.iml
├── xfg-frame-domain
│   ├── pom.xml
│   ├── src
│   │   └── main
│   │       └── java
│   │           └── cn
│   │               └── bugstack
│   │                   └── xfg
│   │                       └── frame
│   │                           └── domain
│   │                               ├── order
│   │                               │   ├── model
│   │                               │   │   ├── aggregates
│   │                               │   │   │   └── OrderAggregate.java
│   │                               │   │   ├── entity
│   │                               │   │   │   ├── OrderItemEntity.java
│   │                               │   │   │   └── ProductEntity.java
│   │                               │   │   ├── package-info.java
│   │                               │   │   └── valobj
│   │                               │   │       ├── OrderIdVO.java
│   │                               │   │       ├── ProductDescriptionVO.java
│   │                               │   │       └── ProductNameVO.java
│   │                               │   ├── repository
│   │                               │   │   ├── IOrderRepository.java
│   │                               │   │   └── package-info.java
│   │                               │   └── service
│   │                               │       ├── OrderService.java
│   │                               │       └── package-info.java
│   │                               ├── rule
│   │                               │   ├── model
│   │                               │   │   ├── aggregates
│   │                               │   │   │   └── TreeRuleAggregate.java
│   │                               │   │   ├── entity
│   │                               │   │   │   ├── DecisionMatterEntity.java
│   │                               │   │   │   └── EngineResultEntity.java
│   │                               │   │   ├── package-info.java
│   │                               │   │   └── valobj
│   │                               │   │       ├── TreeNodeLineVO.java
│   │                               │   │       ├── TreeNodeVO.java
│   │                               │   │       └── TreeRootVO.java
│   │                               │   ├── repository
│   │                               │   │   ├── IRuleRepository.java
│   │                               │   │   └── package-info.java
│   │                               │   └── service
│   │                               │       ├── engine
│   │                               │       │   ├── EngineBase.java
│   │                               │       │   ├── EngineConfig.java
│   │                               │       │   ├── EngineFilter.java
│   │                               │       │   └── impl
│   │                               │       │       └── RuleEngineHandle.java
│   │                               │       ├── logic
│   │                               │       │   ├── BaseLogic.java
│   │                               │       │   ├── LogicFilter.java
│   │                               │       │   └── impl
│   │                               │       │       ├── UserAgeFilter.java
│   │                               │       │       └── UserGenderFilter.java
│   │                               │       └── package-info.java
│   │                               └── user
│   │                                   ├── model
│   │                                   │   └── valobj
│   │                                   │       └── UserVO.java
│   │                                   ├── repository
│   │                                   │   └── IUserRepository.java
│   │                                   └── service
│   │                                       ├── UserService.java
│   │                                       └── impl
│   │                                           └── UserServiceImpl.java
│   └── xfg-frame-domain.iml
├── xfg-frame-infrastructure
│   ├── pom.xml
│   ├── src
│   │   └── main
│   │       └── java
│   │           └── cn
│   │               └── bugstack
│   │                   └── xfg
│   │                       └── frame
│   │                           └── infrastructure
│   │                               ├── dao
│   │                               │   ├── IUserDao.java
│   │                               │   ├── RuleTreeDao.java
│   │                               │   ├── RuleTreeNodeDao.java
│   │                               │   └── RuleTreeNodeLineDao.java
│   │                               ├── package-info.java
│   │                               ├── po
│   │                               │   ├── RuleTreeNodeLineVO.java
│   │                               │   ├── RuleTreeNodeVO.java
│   │                               │   ├── RuleTreeVO.java
│   │                               │   └── UserPO.java
│   │                               └── repository
│   │                                   ├── RuleRepository.java
│   │                                   └── UserRepository.java
│   └── xfg-frame-infrastructure.iml
├── xfg-frame-trigger
│   ├── pom.xml
│   ├── src
│   │   └── main
│   │       └── java
│   │           └── cn
│   │               └── bugstack
│   │                   └── xfg
│   │                       └── frame
│   │                           └── trigger
│   │                               ├── http
│   │                               │   ├── Controller.java
│   │                               │   └── package-info.java
│   │                               ├── mq
│   │                               │   └── package-info.java
│   │                               ├── rpc
│   │                               │   ├── AccountService.java
│   │                               │   ├── RuleService.java
│   │                               │   └── package-info.java
│   │                               └── task
│   │                                   └── package-info.java
│   └── xfg-frame-trigger.iml
└── xfg-frame-types
    ├── pom.xml
    ├── src
    │   └── main
    │       └── java
    │           └── cn
    │               └── bugstack
    │                   └── xfg
    │                       └── frame
    │                           └── types
    │                               ├── Constants.java
    │                               ├── Response.java
    │                               └── package-info.java
    └── xfg-frame-types.iml

以上是整個??工程架構(gòu)的 tree 樹形圖。整個工程由  xfg-frame-app 模的 SpringBoot 驅(qū)動。這里小傅哥在 domain 領(lǐng)域模型下提供了 order、rule、user 三個領(lǐng)域模塊。并在每個模塊下提供了對應(yīng)的測試內(nèi)容。這塊是整個模型的重點(diǎn),其他模塊都可以通過測試看到這里的調(diào)用過程。

4.3 領(lǐng)域

一個領(lǐng)域模型中包含3個部分;model、repository、service 三部分;

  • model 對象的定義
  • repository 倉儲的定義
  • service 服務(wù)實(shí)現(xiàn)

以上3個模塊,一般也是大家在使用 DDD 時候最不容易理解的分層。比如 model 里還分為;valobj - 值對象、entity 實(shí)體對象、aggregates 聚合對象;

  • 值對象:表示沒有唯一標(biāo)識的業(yè)務(wù)實(shí)體,例如商品的名稱、描述、價格等。
  • 實(shí)體對象:表示具有唯一標(biāo)識的業(yè)務(wù)實(shí)體,例如訂單、商品、用戶等;
  • 聚合對象:是一組相關(guān)的實(shí)體對象的根,用于保證實(shí)體對象之間的一致性和完整性;

關(guān)于model中各個對象的拆分,尤其是聚合的定義,會牽引著整個模型的設(shè)計(jì)。當(dāng)然你可以在初期使用 DDD 的時候不用過分在意領(lǐng)域模型的設(shè)計(jì),可以把整個 domain 下的一個個包當(dāng)做充血模型結(jié)構(gòu),這樣編寫出來的代碼也是非常適合維護(hù)的。

4.4 環(huán)境(開發(fā)/測試/上線)

源碼:xfg-frame-ddd/pom.xml

<profile>
    <id>dev</id>
    <activation>
        <activeByDefault>true</activeByDefault>
    </activation>
    <properties>
        <profileActive>dev</profileActive>
    </properties>
</profile>
<profile>
    <id>test</id>
    <properties>
        <profileActive>test</profileActive>
    </properties>
</profile>
<profile>
    <id>prod</id>
    <properties>
        <profileActive>prod</profileActive>
    </properties>
</profile>
  • 定義環(huán)境;開發(fā)、測試、上線。

源碼:xfg-frame-app/application.yml

spring:
  config:
    name: xfg-frame
  profiles:
    active: dev # dev、test、prod
  • 除了 pom 的配置,還需要在 application.yml 中指定環(huán)境。這樣就可以對應(yīng)的加載到;application-dev.yml、application-prod.yml、application-test.yml 這樣就可以很方便的加載對應(yīng)的配置信息了。尤其是各個場景中切換會更加方便。

4.5 切面

一個工程開發(fā)中,有時候可能會有很多的統(tǒng)一切面和啟動配置的處理,這些內(nèi)容都可以在 xfg-frame-app 完成。

圖片圖片

源碼:cn.bugstack.xfg.frame.aop.RateLimiterAop

@Slf4j
@Aspect
public class RateLimiterAop {

    private final long timeout;
    private final double permitsPerSecond;
    private final RateLimiter limiter;

    public RateLimiterAop(double permitsPerSecond, long timeout) {
        this.permitsPerSecond = permitsPerSecond;
        this.timeout = timeout;
        this.limiter = RateLimiter.create(permitsPerSecond);
    }

    @Pointcut("execution(* cn.bugstack.xfg.frame.trigger..*.*(..))")
    public void pointCut() {
    }

    @Around(value = "pointCut()", argNames = "jp")
    public Object around(ProceedingJoinPoint jp) throws Throwable {
        boolean tryAcquire = limiter.tryAcquire(timeout, TimeUnit.MILLISECONDS);
        if (!tryAcquire) {
            Method method = getMethod(jp);
            log.warn("方法 {}.{} 請求已被限流,超過限流配置[{}/秒]", method.getDeclaringClass().getCanonicalName(), method.getName(), permitsPerSecond);
            return Response.<Object>builder()
                    .code(Constants.ResponseCode.RATE_LIMITER.getCode())
                    .info(Constants.ResponseCode.RATE_LIMITER.getInfo())
                    .build();
        }
        return jp.proceed();
    }

    private Method getMethod(JoinPoint jp) throws NoSuchMethodException {
        Signature sig = jp.getSignature();
        MethodSignature methodSignature = (MethodSignature) sig;
        return jp.getTarget().getClass().getMethod(methodSignature.getName(), methodSignature.getParameterTypes());
    }

}

使用

# 限流配置
rate-limiter:
  permits-per-second: 1
  timeout: 5
  • 這樣你所有的通用配置,又和業(yè)務(wù)沒有太大的關(guān)系的,就可以直接寫到這里了。—— 具體可以參考代碼。

5. 測試驗(yàn)證

  • 首先;整個工程由 SpringBoot 驅(qū)動,提供了 road-map.sql 測試 SQL 庫表語句。你可以在自己的本地mysql上進(jìn)行執(zhí)行。它會創(chuàng)建庫表。
  • 之后;在 application.yml 配置數(shù)據(jù)庫鏈接信息。
  • 之后就可以打開 ApiTest 進(jìn)行測試了。你可以點(diǎn)擊 Application 類的綠色箭頭啟動工程,使用觸發(fā)器里的接口調(diào)用測試,或者單元測試RPC接口,小傅哥也提供了泛化調(diào)用的方式。

圖片圖片

  • 如果你正常獲取了這樣的結(jié)果信息,那么說明你已經(jīng)啟動成功。接下來就可以對照著DDD的結(jié)構(gòu)進(jìn)行學(xué)習(xí),以及使用這樣的工程結(jié)構(gòu)開發(fā)自己的項(xiàng)目。

三、實(shí)戰(zhàn) - DDD 項(xiàng)目

紙上得來終覺淺,碼農(nóng)學(xué)習(xí)要實(shí)戰(zhàn)!

無論是 MVC 還是各類 DDD 所呈現(xiàn)的架構(gòu),還是需要看到實(shí)際的代碼,以及參與實(shí)戰(zhàn)開發(fā)才能更好的吸收。否則都是理論仍舊難以讓人下手。

所以小傅哥為大家準(zhǔn)備了一些學(xué)習(xí)項(xiàng)目,這些項(xiàng)目都是非常具有架構(gòu)思維以及設(shè)計(jì)模式的應(yīng)用級實(shí)戰(zhàn)項(xiàng)目架構(gòu)設(shè)計(jì)和落地。對于一些小白來說,如果能早早的接觸到這樣的項(xiàng)目,就相當(dāng)于是提前進(jìn)入企業(yè)實(shí)習(xí)了。可以極大的提到編程思維以及開發(fā)能力。

這些項(xiàng)目包括:《Lottery 抽獎系統(tǒng) - 基于領(lǐng)域驅(qū)動設(shè)計(jì)的四層架構(gòu)實(shí)踐》、《API網(wǎng)關(guān):中間件設(shè)計(jì)和落地》、《ChatGPT 微服務(wù)應(yīng)用體系搭建》、《IM 仿微信》、《SpringBoot Starter 中間件設(shè)計(jì)和落地》等。這里小傅哥只列3張圖,你就知道有多牛皮了!

第1張:Lottery

架構(gòu)

圖片圖片

工程

圖片圖片

第2張:API網(wǎng)關(guān)

架構(gòu)

圖片圖片

工程

圖片圖片

第3張:ChatGPT

圖片 圖片

責(zé)任編輯:武曉燕 來源: bugstack蟲洞棧
相關(guān)推薦

2024-04-08 07:05:10

MVCDDD架構(gòu)

2022-06-02 08:37:10

架構(gòu)DDDMVC

2023-11-13 14:44:14

DDD開發(fā)Java

2012-04-16 15:14:47

web設(shè)計(jì)

2021-08-18 07:56:05

Typescript類型本質(zhì)

2013-12-19 15:56:50

去IOE數(shù)據(jù)庫服務(wù)器

2015-08-31 13:43:27

運(yùn)維

2021-11-09 23:15:20

編程語言本質(zhì)

2024-12-13 08:24:23

2021-07-31 23:25:34

CSS布局UI

2020-10-09 08:26:16

架構(gòu)

2010-04-06 12:59:18

MVC

2018-04-04 14:29:33

2018-03-21 09:08:06

超融合架構(gòu)本質(zhì)

2022-05-27 20:53:42

數(shù)字化轉(zhuǎn)型數(shù)字化經(jīng)營消費(fèi)者

2022-02-21 17:10:56

MVC架構(gòu)分布式

2021-09-03 09:12:09

Linux中斷軟件

2017-03-06 17:30:11

微服務(wù)架構(gòu)系統(tǒng)

2017-12-15 14:10:20

深度學(xué)習(xí)本質(zhì)邊緣識別

2021-02-02 09:37:20

CQRS系統(tǒng)數(shù)據(jù)庫
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號

主站蜘蛛池模板: 超碰在线免费公开 | 一区二区三区av | 一区二区三区久久久 | 毛片视频观看 | 一区二区三区亚洲精品国 | 成人一区二区三区在线观看 | 欧美中文字幕在线观看 | 日韩中文不卡 | 给我免费的视频在线观看 | 久久国产精品一区二区三区 | 日韩一区二区福利视频 | 黄色在线免费观看视频 | 欧美日韩在线播放 | 岛国一区 | 激情影院久久 | 国产精品亚洲一区二区三区在线观看 | 免费黄色大片 | 成人在线观看免费 | 日本精品视频在线 | 欧美精品久久久 | www.久久99 | 成人av片在线观看 | 欧美在线a| 狠狠色香婷婷久久亚洲精品 | 国产精品九九视频 | 91在线电影| 9191成人精品久久 | 日韩三级在线观看 | 中文在线a在线 | 黄网站免费在线 | 欧美一区二区三区在线免费观看 | 日韩一区二区在线视频 | 蜜桃视频在线观看免费视频网站www | 91福利网址 | 精品国产乱码久久久 | 国产一级免费在线观看 | 日日骚视频 | 国产欧美日韩一区 | jvid精品资源在线观看 | 亚洲免费视频在线观看 | 亚洲福利在线观看 |