溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

如何手?jǐn)]SpringBoot 腳手架!

發(fā)布時(shí)間:2021-09-29 15:27:03 來(lái)源:億速云 閱讀:131 作者:柒染 欄目:開(kāi)發(fā)技術(shù)

這篇文章給大家介紹如何手?jǐn)]SpringBoot 腳手架!,內(nèi)容非常詳細(xì),感興趣的小伙伴們可以參考借鑒,希望對(duì)大家能有所幫助。

一、前言

為什么我們要去造輪子?

造輪子的核心目的,是為了解決通用共性問(wèn)題的凝練和復(fù)用。

雖然市面上已經(jīng)有了大量成熟穩(wěn)定用于支撐系統(tǒng)建設(shè)的輪子,也就是服務(wù)、框架、組件、工具等,但對(duì)于一些較大型的公司來(lái)說(shuō),這些輪子可能并不一定能很好的支撐起系統(tǒng)需要承載的服務(wù)體量,這個(gè)時(shí)候就需要自建一些輪子。

而提倡的不重復(fù)造輪子,新造輪子不一定能保證穩(wěn)定性。一般用在以官網(wǎng)推出的核心輪子上是適合的,比如 SpringBoot、Netty、HBase  等。但對(duì)于一些特殊場(chǎng)景的解決方案工具型組件,通常是沒(méi)有完全符合的輪子的,就像 SpringBoot 腳手架。

其實(shí)每個(gè)較大型的公司都會(huì)有很多同類技術(shù)服務(wù)的組件,例如  RPC、數(shù)據(jù)庫(kù)路由、注冊(cè)中心、分布式任務(wù)、MQ隊(duì)列消息等,而這時(shí)候腳手架的開(kāi)發(fā)就需要適配這些組件,搭建出符合自己公司技術(shù)棧實(shí)現(xiàn)需要的系統(tǒng)架構(gòu)。這不同于一些較小的互聯(lián)網(wǎng)公司,可以完全使用  SpringBoot 提供的一整套解決方案

另外,造輪子是個(gè)人技術(shù)沉淀、也是薪資待遇的積累!別說(shuō)造不了飛機(jī),只是你沒(méi)有提供場(chǎng)地!

有什么場(chǎng)景還能造輪子?

如何手?jǐn)]SpringBoot 腳手架!

用于架構(gòu)基建下的所有模塊都可以成為輪子,通常我們都是在這些場(chǎng)景下:負(fù)載均衡、服務(wù)網(wǎng)關(guān)、服務(wù)治理、框架語(yǔ)言、服務(wù)組件、數(shù)據(jù)承載、框架結(jié)構(gòu)、部署方式、工具插件,建設(shè)需要的輪子。

其實(shí)一個(gè)較成熟的互聯(lián)網(wǎng)公司,大部分場(chǎng)景下的輪子,已基本建造完了。剩下的一般是用于解決業(yè)務(wù)場(chǎng)景下非業(yè)務(wù)邏輯的通用性組件,例如,高并發(fā)下的緩存熱Key、Redis  層路由、活動(dòng)邀請(qǐng)的不唯一短碼生成,等等類似這樣的場(chǎng)景。但此類場(chǎng)景的輪子建設(shè)也是非常有價(jià)值的,在公司層面使用穩(wěn)定后,還可以推廣到市場(chǎng)獲得一定的認(rèn)可,以及更好的會(huì)被收入到  Apache 項(xiàng)目。

二、什么是腳手架呢?

What is scaffolding? Is it a term for a particular platform?

Scaffolding is a  meta-programming method of building database-backed software applications. It is  a technique supported by some model-view-controller frameworks, in which the  programmer may write a specification that describes how the application database  may be used. The compiler uses this specification to generate code that the  application can use to create, read, update and delete database entries,  effectively treating the template as a "scaffold" on which to build a more  powerful application.

  • https://stackoverflow.com/questions/235018/what-is-scaffolding-is-it-a-term-for-a-particular-platform

如何手?jǐn)]SpringBoot 腳手架!

結(jié)合 stackoverflow  上的回答,腳手架是一種元編程方法,用于構(gòu)建基于數(shù)據(jù)的應(yīng)用。創(chuàng)建系統(tǒng)架構(gòu)的程序員編寫一份規(guī)格說(shuō)明書(shū),用于描述怎么去使用數(shù)據(jù)庫(kù)。而腳手架可以根據(jù)這份規(guī)則說(shuō)明書(shū)生成相應(yīng)的框架代碼。我們把這種模式成為腳手架,在腳手架上更高效的構(gòu)建出powerful  的應(yīng)用!

說(shuō)白了就是簡(jiǎn)化具有共性重復(fù)操作的簡(jiǎn)單工作,不再需要程序員還得一點(diǎn)點(diǎn)粘貼復(fù)制,克隆出一個(gè)已經(jīng)存在的架構(gòu)。只需要在界面或者公用接口上,傳入必要的參數(shù),就可以創(chuàng)建出一個(gè)應(yīng)用開(kāi)發(fā)框架。

三、誰(shuí)提供了腳手架?

1、Spring 官網(wǎng)腳手架

如何手?jǐn)]SpringBoot 腳手架!

  • 推薦:????

  • 鏈接:https://start.spring.io

  • 源碼:https://github.com/spring-io/start.spring.io

  • 描述:Spring Initializr 本質(zhì)上也是一個(gè) Web 應(yīng)用,它可以通過(guò) Web 界面、Spring Tool Suite、IntelliJ  IDEA 等方式,構(gòu)建出一個(gè)基本的 Spring Boot 項(xiàng)目結(jié)構(gòu)。同時(shí)可以使用它的源碼進(jìn)行本地部署

2、阿里云腳手架

如何手?jǐn)]SpringBoot 腳手架!

  • 推薦:????

  • 鏈接:https://start.spring.io

  • 描述:Aliyun Java Initializr 和 Spring Initializr 是同類的 Web  服務(wù),是代碼框架生成器,一鍵生成你的代碼框架,有完善的工具鏈,免費(fèi)的IDEA插件,方便直接在IDE中生成,完善的工具鏈,免費(fèi)的IDEA插件,方便直接在IDE中生成,同時(shí)也非常適合國(guó)內(nèi)用戶的網(wǎng)絡(luò)環(huán)境。

其實(shí),這兩個(gè)腳手架都能很好的生成項(xiàng)目結(jié)構(gòu),讓程序員可以在統(tǒng)一的標(biāo)準(zhǔn)下快速的進(jìn)入開(kāi)發(fā)環(huán)境。只是依賴于自身選擇的支撐服務(wù),選擇不同的框架就可以了。

四、手?jǐn)]一個(gè)腳手架!

都有腳手架了,那為什么要自己擼一個(gè)呢?

腳手架的目的是為了在統(tǒng)一的標(biāo)準(zhǔn)下快速建設(shè)系統(tǒng)框架,把系統(tǒng)開(kāi)發(fā)過(guò)程中需要的配置、組件、服務(wù)、測(cè)試,一并通過(guò)配置引入到系統(tǒng)開(kāi)發(fā)中。

但有些時(shí)候在互聯(lián)網(wǎng)公司通用的腳手架是不太合適使用的,因?yàn)樗鼪](méi)有把公司內(nèi)的一些自研性質(zhì)的組件引入進(jìn)去,也不能很好的融合。如果已經(jīng)用腳手架生成后還得需要研發(fā)人員自己大量復(fù)制進(jìn)去一些特定的組件,就破壞了腳手架本身能力,也是破壞了準(zhǔn)則和規(guī)范。

所以,需要結(jié)合腳手架的開(kāi)發(fā)能力,包裝各類特定組件、服務(wù)、配置,實(shí)現(xiàn)符合公司領(lǐng)域的統(tǒng)一腳手架。

那么,本章節(jié)就帶著大家看看一個(gè)腳手架,該如何開(kāi)發(fā)實(shí)現(xiàn)。其實(shí)并沒(méi)有太負(fù)責(zé),我們可以使用 freemarker 的能力,構(gòu)建系統(tǒng)框架。

1. 工程框架

EasyRiggerInitializr └── src     ├── main     │   ├── java     │   │   └── cn.bugstack.initializr.rigger     │   │       ├── application     │   │       │  └── IProjectGenerator.java     │   │       ├── domain     │   │       │  ├── model     │   │       │  │   └── ApplicationInfo.java          │   │       │  │   └── ProjectInfo.java      │   │       │  └── service     │   │       │      ├── module     │   │       │      │   ├── impl     │   │       │      │   │   ├── GenerationApplication.java     │   │       │      │   │   ├── GenerationIgnore.java     │   │       │      │   │   ├── GenerationPackageInfo.java     │   │       │      │   │   ├── GenerationPom.java     │   │       │      │   │   ├── GenerationTest.java         │   │       │      │   │   └── GenerationYml.java          │   │       │      │   └── BaseModule.java         │   │       │      └── ProjectGeneratorImpl.java     │   │       └── RiggerApplication.java     │   └── resources      │       ├── generator     │       │   ├── application.ftl     │       │   ├── ignore.ftl      │       │   ├── package-info.ftl      │       │   ├── pom.ftl      │       │   ├── test.ftl          │       │   └── yml.ftl         │       └── application.yml     └── test          └── java              └── cn.bugstack.initializr.rigger.test                  └── ApiTest.java

如何手?jǐn)]SpringBoot 腳手架!

整個(gè)用于創(chuàng)建腳手架的工程并不復(fù)雜,主要就是通過(guò) freemarker 對(duì)各類定義的 ftl  模板文件,生成對(duì)應(yīng)的系統(tǒng)框架結(jié)構(gòu)。這里包括:工程主體、框架結(jié)構(gòu)、啟動(dòng)類、配置文件、測(cè)試類等,也可以結(jié)合自身需求把對(duì)應(yīng) ORM 的類和映射關(guān)系生成出來(lái)。

整個(gè)工程結(jié)構(gòu)偏 DDD 層次結(jié)構(gòu),domain 領(lǐng)域中建設(shè)了所有的生成方式,resources/generator  定義生成模板,其他地方就沒(méi)有太大的差異了。

接下來(lái)簡(jiǎn)單介紹下這個(gè)工程的代碼,讓大家可以理解這樣的工程是如何開(kāi)發(fā)的,也可以通過(guò)這樣工程繼續(xù)完善成自己需要的結(jié)構(gòu)。

2. 應(yīng)用層定義生成類接口

  • cn.bugstack.initializr.rigger.application.IProjectGenerator.java

public interface IProjectGenerator {      void generator(ProjectInfo projectInfo) throws Exception;  }

DDD 的分層結(jié)構(gòu),通常都會(huì)在 application 這個(gè)比較薄的層定義接口,再有 domain 領(lǐng)域?qū)幼鱿鄳?yīng)的實(shí)現(xiàn)。

這個(gè)接口的定義主要是為了,讓外部調(diào)用方可以通過(guò)此接口創(chuàng)建工程框架。

3. FTL 模板定義

什么是 FreeMarker?

如何手?jǐn)]SpringBoot 腳手架!

FreeMarker 是一款 模板引擎:即一種基于模板和要改變的數(shù)據(jù),  并用來(lái)生成輸出文本(HTML網(wǎng)頁(yè),電子郵件,配置文件,源代碼等)的通用工具。它不是面向最終用戶的,而是一個(gè)Java類庫(kù),是一款程序員可以嵌入他們所開(kāi)發(fā)產(chǎn)品的組件。

模板編寫為FreeMarker Template Language (FTL)。它是簡(jiǎn)單的,專用的語(yǔ)言, 不是  像PHP那樣成熟的編程語(yǔ)言。那就意味著要準(zhǔn)備數(shù)據(jù)在真實(shí)編程語(yǔ)言中來(lái)顯示,比如數(shù)據(jù)庫(kù)查詢和業(yè)務(wù)運(yùn)算,  之后模板顯示已經(jīng)準(zhǔn)備好的數(shù)據(jù)。在模板中,你可以專注于如何展現(xiàn)數(shù)據(jù), 而在模板之外可以專注于要展示什么數(shù)據(jù)。

FreeMarker 在線手冊(cè):http://freemarker.foofun.cn

3.1 application.ftl

package ${packageName};  import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;  @SpringBootApplication public class ${className} {      public static void main(String[] args) {         SpringApplication.run(${className}.class, args);     }  }

3.2 pom.ftl

<?xml version="1.0" encoding="UTF-8"?> <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/xsd/maven-4.0.0.xsd">     <modelVersion>4.0.0</modelVersion>     <parent>         <groupId>org.springframework.boot</groupId>         <artifactId>spring-boot-starter-parent</artifactId>         <version>2.1.6.RELEASE</version>         <relativePath/> <!-- lookup parent from repository -->     </parent>     <groupId>${groupId}</groupId>     <artifactId>${artifactId}</artifactId>     <version>${version}</version>     <name>${name}</name>     <description>${description}</description>      </project>

3.3 yml.ftl

server:   port: 8081

以上,只是用于生成框架文件的基礎(chǔ) ftl 文件,有需要一些特殊判斷和邏輯的,可以參考FreeMarker 在線手冊(cè),編寫自己需要的 ftl 文件。

4. FTL 生成文件

cn.bugstack.initializr.rigger.domain.service.module.impl.GenerationApplication.java

@Service public class GenerationApplication extends BaseModule {      private Logger logger = LoggerFactory.getLogger(GenerationApplication.class);      public void doGeneration(ProjectInfo projectInfo, String projectsRoot, String lastPackageName, StringBuffer applicationJavaName) throws Exception {          ApplicationInfo applicationInfo = new ApplicationInfo(                 projectInfo.getGroupId() + "." + lastPackageName,                 applicationJavaName.toString()         );          String packagePath = applicationInfo.getPackageName().replace(".", "/") + "/";          File file = new File(projectsRoot + projectInfo.getArtifactId() + "/src/main/java/" + packagePath,                 applicationInfo.getClassName() + ".java");          // 寫入文件         super.writeFile(file, "application.ftl", applicationInfo);          logger.info("創(chuàng)建主入口類 Application.java {}", file.getPath());     }  }
  • 關(guān)于 ftl 文件的使用,無(wú)論在用于生成那一層的文件,基本都是通用。這里只展示一下關(guān)于 Application.java 的創(chuàng)建。

  • 主要包括了,定義入?yún)?ApplicationInfo、定義文件位置 /src/main/java/、以及寫入到文件  super.writeFile,這三方面。

5. 創(chuàng)建框架入口

cn.bugstack.initializr.rigger.domain.service.ProjectGeneratorImpl.java

@Service public class ProjectGeneratorImpl implements IProjectGenerator {      private Logger logger = LoggerFactory.getLogger(ProjectGeneratorImpl.class);      @Resource     private GenerationApplication generationApplication;     @Resource     private GenerationYml generationYml;     @Resource     private GenerationPom generationPom;     @Resource     private GenerationTest generationTest;     @Resource     private GenerationIgnore generationIgnore;     @Resource     private GenerationPackageInfo generationPackageInfo;      @Override     public void generator(ProjectInfo projectInfo) throws Exception {          URL resource = this.getClass().getResource("/");         String projectsRoot = resource.getFile() + "/projects/";          String lastPackageName = projectInfo.getArtifactId().replaceAll("-", "").toLowerCase();         //啟動(dòng)類名稱         String[] split = projectInfo.getArtifactId().split("-");         StringBuffer applicationJavaName = new StringBuffer();         Arrays.asList(split).forEach(s -> {             applicationJavaName.append(s.substring(0, 1).toUpperCase() + s.substring(1));         });         applicationJavaName.append("Application");          // 1. 創(chuàng)建  Application.java         generationApplication.doGeneration(projectInfo, projectsRoot, lastPackageName, applicationJavaName);          // 2. 生成 application.yml         generationYml.doGeneration(projectInfo, projectsRoot);          // 3. 生成 pom.xml         generationPom.doGeneration(projectInfo, projectsRoot);          // 4. 創(chuàng)建測(cè)試類 ApiTest.java         generationTest.doGeneration(projectInfo, projectsRoot, lastPackageName, applicationJavaName);          // 5. 生成 .gitignore         generationIgnore.doGeneration(projectInfo, projectsRoot);          // 6. DDD 四層描述文件         generationPackageInfo.doGeneration(projectInfo, projectsRoot, lastPackageName, applicationJavaName);      }  }

ProjectGeneratorImpl 類,就是應(yīng)用層接口 IProjectGenerator 在領(lǐng)域?qū)拥木唧w實(shí)現(xiàn)。這里包括了如下內(nèi)容:

  • 創(chuàng)建 Application.java

  • 生成 application.yml

  • 生成 pom.xml

  • 創(chuàng)建測(cè)試類 ApiTest.java

  • 生成 .gitignore

  • DDD 四層描述文件

綜上,就是整個(gè)腳手架生成的簡(jiǎn)要介紹,其實(shí)并沒(méi)有多復(fù)雜,主要就是 ftl 文件的定義和使用,這種創(chuàng)建腳手架的方式還是很方便的。

6. 測(cè)試驗(yàn)證

單元測(cè)試@Testpublic void test_IProjectGenerator() throws Exception { ProjectInfo  projectInfo = new ProjectInfo( "cn.bugstack.demo", "web-test", "1.0.0-SNAPSHOT",  "web-test", "Demo project for Spring Boot" );  iProjectGenerator.generator(projectInfo);}

測(cè)試結(jié)果


如何手?jǐn)]SpringBoot 腳手架!

腳手架把創(chuàng)建出來(lái)的工程生成到 test-classes 下,這個(gè)路徑也可以配置到其他路徑里。

有了新生成的工程就可以通過(guò) IDEA 打開(kāi)了,與我們手動(dòng)創(chuàng)建的工程是一樣的。

五、源碼下載

如何手?jǐn)]SpringBoot 腳手架!

  • 源碼下載:關(guān)注公眾號(hào):bugstack蟲(chóng)洞棧,回復(fù):腳手架

  • 項(xiàng)目介紹:SpringBoot  腳手架,簡(jiǎn)化項(xiàng)目構(gòu)建。目前的項(xiàng)目工程還比較簡(jiǎn)單,非常適合新人學(xué)習(xí)使用。后續(xù)我們會(huì)在這個(gè)版本的基礎(chǔ)上陸續(xù)完善一些功能,把RPC、MQ、注冊(cè)中心、網(wǎng)關(guān)、等各類組件融合進(jìn)來(lái),方便選擇性的構(gòu)建和擴(kuò)展。

六、總結(jié)

  • 站在公司角度不重復(fù)造輪子是為了各部門職責(zé)和資源的成本,但對(duì)個(gè)人來(lái)說(shuō),不能因?yàn)橐痪洳恢貜?fù)造輪子,就放棄了對(duì)知識(shí)棧深入學(xué)習(xí)的機(jī)會(huì)。

  • 沒(méi)有這些根基的學(xué)習(xí),也壓根不會(huì)理解技術(shù)的遷移、服務(wù)的提取、組件的凝練。反反復(fù)復(fù)的總是做一些 API 的應(yīng)用包殼,對(duì)個(gè)人技術(shù)上也就沒(méi)有什么成長(zhǎng)。

  • 最后說(shuō)回來(lái),哪怕公司不需要你造輪子,沒(méi)關(guān)系,你可以造給自己,可以分享到 Github  社區(qū)。一方面是自己的學(xué)習(xí)匯總,另一方面也是對(duì)技術(shù)的沉淀和貢獻(xiàn)。

關(guān)于如何手?jǐn)]SpringBoot 腳手架!就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,可以學(xué)到更多知識(shí)。如果覺(jué)得文章不錯(cuò),可以把它分享出去讓更多的人看到。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI