多模塊 SpringBoot 種子工程搭建 (一)

1. 搭建準(zhǔn)備&使用場景

  • IDE: InteliJ IDEA
  • JDK: 1.8
  • SpringBoot: 2.0.3.RELEASE
  • 使用場景: 中小型項(xiàng)目, API 和后臺管理 分開部署

2. 模塊說明

@模塊依賴關(guān)系圖 | center | 400x200
  • config: 配置中心模塊
  • bizz-support: 業(yè)務(wù)支持模塊, 存放根據(jù)表生成的通用 Service, Mapper
  • framework-support: 框架支持模塊
  • api: API 接口模塊
  • manage: 后臺管理模塊

3. 模塊搭建

3.1 parent

  1. 使用 IDEA 或者 官網(wǎng)的 Spring initializr創(chuàng)建一個空項(xiàng)目multi-module-springboot, 刪除多余文件.
  2. pom.xml 中將 packaging 改成 pom 提供 依賴版本管理
  3. <dependencies> 標(biāo)簽外面嵌套一層 <dependencyManagement>
  4. 刪除 <build>

3.2 api

1. Spring initializr 創(chuàng)建一個項(xiàng)目, 父模塊引入 spring-boot-starter-web, api 對應(yīng)配置

且設(shè)置父模塊為multi-module-springboot

2. 新建 Controller


@RestController
@RequestMapping("/api")
public class HelloRestfulController {

    @GetMapping({"/", "index", "index.html"})
    public Map adminIndex() throws Exception {

        return new HashMap(3) {{
            put("code", 0);
            put("message", "成功");
            put("data", "Hello World!");
        }};
}

3. 測試完成

$ curl http://localhost:8766/api/
{"message":"成功","data":"Hello World!","code":0}

3.3 manage

1. 如創(chuàng)建 3.2 api 模塊一樣創(chuàng)建 manage 模塊

2. 添加 thymeleaf 依賴

<springboot.version>2.0.3.RELEASE</springboot.version>
<nekohtml.version>1.9.22</nekohtml.version>
<thymeleaflayout.version>2.3.0</thymeleaflayout.version>
<thymeleaf.version>3.0.9.RELEASE</thymeleaf.version>
 <!--<editor-fold desc="THYMELEAF 頁面模板引擎">-->
 <dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-thymeleaf</artifactId>
     <version>${springboot.version}</version>
     <!-- 排除掉默認(rèn)的版本 -->
     <exclusions>
         <exclusion>
             <groupId>org.thymeleaf</groupId>
             <artifactId>thymeleaf</artifactId>
         </exclusion>
         <exclusion>
             <groupId>org.thymeleaf</groupId>
             <artifactId>thymeleaf-spring5</artifactId>
         </exclusion>
     </exclusions>
 </dependency>
 <dependency>
     <groupId>net.sourceforge.nekohtml</groupId>
     <artifactId>nekohtml</artifactId>
     <version>${nekohtml.version}</version>
 </dependency>
 <dependency>
     <groupId>nz.net.ultraq.thymeleaf</groupId>
     <artifactId>thymeleaf-layout-dialect</artifactId>
     <version>${thymeleaflayout.version}</version>
 </dependency>
 <dependency>
     <groupId>org.thymeleaf</groupId>
     <artifactId>thymeleaf-spring5</artifactId>
     <version>${thymeleaf.version}</version>
 </dependency>
 <dependency>
     <groupId>org.thymeleaf</groupId>
     <artifactId>thymeleaf</artifactId>
     <version>${thymeleaf.version}</version>
 </dependency>
 <!--</editor-fold>-->

3. resources 下面新建 templates/home.html

4. application.properties 配置 thymeleaf

spring.thymeleaf.cache=false
spring.thymeleaf.prefix=classpath:/templates/
spring.thymeleaf.suffix=.html
spring.thymeleaf.mode=HTML
spring.resources.chain.strategy.content.enabled=true
spring.resources.chain.strategy.content.paths=/**

5. 新建 Controller

package com.logictech.manage;

import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping;

/**
 * @author JG.Hannibal
 * @since 2018/7/4 14:25
 */
@Controller
public class HelloViewController {

    @GetMapping({"/hello"})
    public String adminIndex(ModelMap model) throws Exception {
        model.addAttribute("text", "Hello World!");
        return "home";
    }

}

6. 測試完成

$ curl http://localhost:8765/hello
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div>Hello World!</div>
<div>Hello World!</div>
</body>
</html>

3.4 config

1. 工程右鍵, 新建 Maven 子模塊 config (該次不是Spring initializr), 因?yàn)樵摴こ套鳛?resources root, 所以將除了pom.xml 的文件全部刪除.

2. 新建 profile 文件夾, 便于不同環(huán)境的發(fā)布部署

cd config
vi src/main/resources/dev/application.properties src/main/resources/prod/application.properties src/main/resources/test/application.properties

3. 每個application中加入配置內(nèi)容

#每個配置文件自己的 profile, 例: env=dev
env=* 
#這邊端口每個配置文件不一樣就可以
server.port=876* 
# 之前配置的模板引擎的配置一致
spring.thymeleaf.cache=false
spring.thymeleaf.prefix=classpath:/templates/
spring.thymeleaf.suffix=.html
spring.thymeleaf.mode=HTML
spring.resources.chain.strategy.content.enabled=true
spring.resources.chain.strategy.content.paths=/**

該版本對其他編輯器支持度太差,優(yōu)化為由Maven實(shí)現(xiàn)該功能。詳細(xì)見4.
4. IDEA設(shè)置為 resources root

Alt text

4.使用 maven-remote-resources-plugin 進(jìn)行Maven的配置文件模塊分離

4.1 config模塊內(nèi)pom.xml添加 maven-remote-resources-plugin 插件,配置如下:

<build>
        <plugins>
            <plugin>
                <artifactId>maven-remote-resources-plugin</artifactId>
                <version>1.7.0</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>bundle</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <includes>
                        <include>**/*.properties</include>
                        <include>**/*.yml</include>
                    </includes>
                </configuration>
            </plugin>
        </plugins>
    </build>

在config目錄下執(zhí)行命令mvn clean package,見編譯后的文件是否有/classes/META-INF/maven/remote-resources.xml,有則添加插件成功。最終編譯目錄如下:

├── classes
│   ├── META-INF
│   │   └── maven
│   │       └── remote-resources.xml
│   ├── dev
│   │   ├── application.properties
│   │   ├── log4j2.yml
│   │   └── message
│   │       └── messages.properties
│   ├── prod
│   │   ├── application.properties
│   │   ├── log4j2.yml
│   │   └── message
│   │       └── messages.properties
│   └── test
│       ├── application.properties
│       ├── log4j2.yml
│       └── message
│           └── messages.properties

4.2 apimanage 模塊進(jìn)行 遠(yuǎn)程配置模塊 消費(fèi)的配置,在對應(yīng)模塊下pom.xml添加以下內(nèi)容,resourceBundle 的值為你的config包的groupId:artifactId:version(應(yīng)該不會有人把我寫的老老實(shí)實(shí)填進(jìn)去吧...)


            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-remote-resources-plugin</artifactId>
                <version>1.7.0</version>
                <configuration>
                    <resourceBundles>
                        <resourceBundle>com.logictech:config:${project.version}</resourceBundle>
                    </resourceBundles>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>process</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>

隨后,還是走一步測一步 mvn clean package,見編譯后目錄,若含有maven-shared-archive-resources 目錄則添加插件成功,然后查看classes目錄,也可以看見 config下的resources也添加進(jìn)來了。結(jié)果如下圖

/Users/JG.Hannibal/Projects/multi-module-springboot/manage/target
├── classes
│   ├── dev
│   │   ├── application.properties
│   │   ├── log4j2.yml
│   │   └── message
│   ├── prod
│   │   ├── application.properties
│   │   ├── log4j2.yml
│   │   └── message
│   ├── templates
│   │   └── home.html
│   └── test
│       ├── application.properties
│       ├── log4j2.yml
│       └── message

這邊存在一個問題,springboot 默認(rèn)是使用classpath下面路徑下的配置文件的,這邊比標(biāo)準(zhǔn)工程多了一級${profile},這邊處理方案很多,不認(rèn)為我的方案為最佳方案,所以這里還是存疑,歡迎討論建議,有最終答案后會再更新文章!

5. 測試, 將 api 工程中resources/application.properties 刪除, 依賴引入 config, 改寫 Controller, 將 env 打印出來.

@RestController
@RequestMapping("/api")
public class HelloRestfulController {

    @Value("${env}")
    private String env;


    @GetMapping({"/", "index", "index.html"})
    public Map adminIndex() throws Exception {

        return new HashMap(3) {{
            put("code", 0);
            put("message", "成功");
            put("data", "This Active Profile is: [" + env + "]");
        }};
    }

}

6. 修改啟動環(huán)境變量, 將 config 路徑配置到我們的子模塊內(nèi),測試完成.

java -jar api-0.0.1-SNAPSHOT.jar --spring.profiles.active=dev 
--spring.config.location=classpath:${spring.profiles.active}/
$ curl http://localhost:8765/api/
{"message":"成功","data":"This Active Profile is: [dev]","code":0}

manage 模塊的改造和 api 一致

存在一個問題, 即 運(yùn)行 api 模塊時, Maven 找不到 config-0.0.1-SNAPSHOT.jar
只需要到 Maven 界面, 將 Nexus的勾選去掉即可.

3.5 framework-support

1. 新建 Maven 子模塊 framework-support, 添加spring-boot-starter-web依賴, config 依賴

這邊我們先實(shí)現(xiàn) Controller 的一個 AOP, 所以引入spring-aop 包括AspectJ

<!--<editor-fold desc="AOP">-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
    <version>${springboot.version}</version>
</dependency>
<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjrt</artifactId>
    <version>${aspectj.version}</version>
</dependency>
<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
    <version>${aspectj.version}</version>
</dependency>
<!--</editor-fold>-->

2. 編寫 ControllerLoggerAop

3. 將 framework-support 的包 添加 到 API 的主函數(shù)ComponentScan 里去, API 添加 framework-support依賴.

4. 測試完成

$ curl http://localhost:8766/api/
{"message":"成功","data":"This Active Profile is: [prod]","code":0}
##########|    URL : http://localhost:8766/api/
##########|    HTTP_METHOD : GET
##########|    IP : 127.0.0.1
##########|    CLASS_METHOD : com.logictech.api.HelloRestfulController.adminIndex
##########|    ARGS : []
====================================================
##########|    RESPONSE : {message=成功, data=This Active Profile is: [prod], code=0}
====================================================

3.6 bizz-support

1. 創(chuàng)建Maven子模塊 bizz-support, 根據(jù)需要創(chuàng)建依賴

2. 創(chuàng)建 CommonConst

public class CommonConst {
    public static final String PROJECT_NAME = "MULTI_MODULE_SPRING_BOOT";
}
    

3. api 模塊改寫 Controller, 測試完成

@RestController
@RequestMapping("/api")
public class HelloRestfulController {

    @Value("${env}")
    private String env;


    @GetMapping({"/", "index", "index.html"})
    public Map adminIndex() throws Exception {

        return new HashMap(3) {{
            put("code", 0);
            put("message", "成功");
            put("data", "This Active Profile is: [" + env + "], Project Name: [" + PROJECT_NAME + "]");
        }};
    }

}
$ curl http://localhost:8766/api/
{"message":"成功","data":"This Active Profile is: [prod], Project Name: [MULTI_MODULE_SPRING_BOOT]","code":0}

4. 總結(jié)

@模塊依賴關(guān)系圖 | center | 400x200

還是就最開始那張圖來講, 該工程分為大體分為三塊:

  • config: 配置中心, 可供后期改造成分布式的配置中心
  • support: 支持中心, 核心模塊, framework-support 和 bizz-support 其實(shí)可以放一起
    但是更清晰一點(diǎn),后期可以把 bizz-support 改造成 rbc服務(wù).
  • business: 業(yè)務(wù)模塊, 展現(xiàn)層

相同的層級的配置可以類比配置.
另外, 寫得沒有面面俱到, 多模塊工程V0.0.1版本, 后期會繼續(xù)完善.


倉庫地址: https://github.com/NibiewJ/multi-module-springboot

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容