創(chuàng)建項(xiàng)目
創(chuàng)建一個(gè) SpringBoot 項(xiàng)目非常的簡(jiǎn)單,簡(jiǎn)單到這里根本不用再提阎肝。你可以在使用 IDEA 新建項(xiàng)目時(shí)直接選擇 Spring Initlalize創(chuàng)建一個(gè) Spring Boot 項(xiàng)目挤渔,也可以使用 Spring 官方提供的 Spring Boot 項(xiàng)目生成頁(yè)面得到一個(gè)項(xiàng)目。
下面介紹一下使用 Spring 官方生成的方式风题,如果你已經(jīng)有了一個(gè) Spring Boot 項(xiàng)目判导,這部分可以直接跳過(guò)嫉父。
打開(kāi) https://start.spring.io/
-
填寫(xiě) group 和 Artifact 信息,選擇依賴(lài)(我選擇了 Spring Web 和 Lombok )眼刃。
點(diǎn)擊Generate按鈕下載項(xiàng)目绕辖。
打開(kāi)下載的項(xiàng)目,刪除無(wú)用的 .mvn文件夾擂红,mvnw 仪际、 mvnw.cmd 、HELP.md文件昵骤。
到這里已經(jīng)得到了一個(gè) Spring Boot 初始項(xiàng)目了树碱,我們直接導(dǎo)入到 IDEA 中,看一眼 pom.xml 的內(nèi)容变秦。
<?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 https://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.2.5.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.wdbyte</groupId>
<artifactId>springboot-module-demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>springboot-module-demo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
把目錄結(jié)構(gòu)調(diào)整成自己想要的結(jié)構(gòu)成榜,然后添加 controller和 entity用于測(cè)試。
ProductController 類(lèi)源代碼蹦玫。
|@RestController
@RequestMapping("/product")
public class ProductController {
/**
* 獲取商品列表
*
* @return
*/
@GetMapping("/list")
public Map list() {
// 模擬查詢商品邏輯
Product product = new Product();
product.setProductName("小米粥");
product.setProductPrice(new BigDecimal(2.0));
product.setProductStock(100);
Map<String, Object> resultMap = new HashMap<>();
resultMap.put("code", 000);
resultMap.put("message", "成功");
resultMap.put("data", Arrays.asList(product));
return resultMap;
}
}
Product 類(lèi)源代碼赎婚。
@Data
public class Product {
/** 商品名稱(chēng). */
private String productName;
/** 商品價(jià)格. */
private BigDecimal productPrice;
/** 商品庫(kù)存。 */
private int productStock;
}
模塊化
借助 IDEA 工具可以快速的把項(xiàng)目改造成 maven 多模塊钳垮,這里我們把準(zhǔn)備測(cè)試 demo 拆分為 common 和 web 兩個(gè)模塊惑淳,common 模塊存放實(shí)體類(lèi)。web 模塊存放 controller 層(這里項(xiàng)目雖小饺窿,拆分只是為了演示)歧焦。話不多說(shuō),直接開(kāi)始肚医。
- 配置主 pom.xml 打包方式 為 pom
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<!-- 配置主 pom 打包方式為 pom -->
<packaging>pom</packaging>
....
....
-
創(chuàng)建 common 模塊
項(xiàng)目直接 new -> module绢馍。
選擇 maven -> next,填寫(xiě)模塊名稱(chēng)肠套。
繼續(xù) next 完成模塊創(chuàng)建舰涌。 -
創(chuàng)建 web 模塊
web 模塊的創(chuàng)建和 common 模塊如出一轍,不再贅述你稚。完成兩個(gè)模塊的創(chuàng)建之后瓷耙,你會(huì)發(fā)現(xiàn)你的主 pom.xml 文件里自動(dòng)添加了 module 部分。
<modules>
<module>product-common</module>
<module>product-web</module>
</modules>
-
移動(dòng)代碼到指定模塊
移動(dòng) Product.java 到product-common模塊刁赖,其他部分代碼和 resource 部分直接移動(dòng)到product-web 模塊搁痛,移動(dòng)完后你的代碼結(jié)構(gòu)是這個(gè)樣子。
到這里宇弛,多模塊已經(jīng)拆分完成了鸡典, 但是 ProductController代碼里的紅色警告讓你發(fā)現(xiàn)事情還沒(méi)有結(jié)束。
依賴(lài)管理
處理依賴(lài)問(wèn)題
你發(fā)現(xiàn)了代碼里的紅色警告枪芒,不過(guò)你也瞬間想到了是因?yàn)榘?strong>Product 類(lèi)移動(dòng)到了 product-common 模塊彻况,導(dǎo)致這里引用不到了谁尸。
然后你查看了下product-common 模塊的 pom.xml 里的內(nèi)容。
<?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">
<parent>
<artifactId>springboot-module-demo</artifactId>
<groupId>com.wdbyte</groupId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>product-common</artifactId>
</project>
機(jī)智的在 Product-web模塊的 pom.xml 里引入 product-common纽甘,手起鍵落良蛮,輕松搞定。
<?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">
<parent>
<artifactId>springboot-module-demo</artifactId>
<groupId>com.wdbyte</groupId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>product-web</artifactId>
<dependencies>
<dependency>
<groupId>com.wdbyte</groupId>
<artifactId>product-common</artifactId>
</dependency>
</dependencies>
</project>
滿心歡喜的你快速的點(diǎn)擊 Build-> Build Project悍赢,得到的 Error 警告刺痛了頂著黑眼圈的你背镇。
不過(guò)你還是迅速定位了問(wèn)題,查看 maven 依賴(lài)泽裳,你發(fā)現(xiàn)是因?yàn)闆](méi)有指定 product-common依賴(lài)的版本號(hào)。
原來(lái)如此破婆,因?yàn)闆](méi)有指定版本號(hào)涮总,我們指定上不就完事了嘛。在最外層的主 pom.xml 中添加 <dependencyManagement>
添加上指定依賴(lài)和要指定的版本號(hào)祷舀。
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.wdbyte</groupId>
<artifactId>product-common</artifactId>
<version>0.0.1-SNAPSHOT</version><!-- maven 打包默認(rèn) 0.0.1-SNAPSHOT 版本 -->
</dependency>
</dependencies>
</dependencyManagement>
刷新 maven 瀑梗,發(fā)現(xiàn)項(xiàng)目已經(jīng)不報(bào)錯(cuò)了,編譯成功裳扯,運(yùn)行啟動(dòng)類(lèi)抛丽,熟悉的 Spring logo 又出現(xiàn)在眼前。
優(yōu)化依賴(lài)
是的饰豺,Spring Boot 應(yīng)用在改造成多模塊后成功運(yùn)行了起來(lái)亿鲜,但是你貌似發(fā)現(xiàn)一個(gè)問(wèn)題,模塊 common 和模塊 web 都繼承了主 pom 冤吨,主 pom 中有 Lombok 蒿柳、Spring Boot Web 和 Spring Boot Test 依賴(lài),而 common模塊里只用到了 Lombok 啊漩蟆,卻一樣繼承了 Spring Boot 其他依賴(lài)垒探,看來(lái)還是要改造一把。
- 只有 common 模塊用到的依賴(lài)移動(dòng)到 common 模塊怠李。
<?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">
<parent>
<artifactId>springboot-module-demo</artifactId>
<groupId>com.wdbyte</groupId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>product-common</artifactId>
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
</project>
- 只有 web模塊用到的依賴(lài)移動(dòng)到 web 模塊圾叼。
<?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">
<parent>
<artifactId>springboot-module-demo</artifactId>
<groupId>com.wdbyte</groupId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>product-web</artifactId>
<dependencies>
<dependency>
<groupId>com.wdbyte</groupId>
<artifactId>product-common</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
</project>
-
抽取用到的版本號(hào)到 <properties>,這里抽取 common模塊的依賴(lài)版本捺癞。
到這里最外層主 pom 的內(nèi)容是這樣的夷蚊。
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<packaging>pom</packaging>
<modules>
<module>product-common</module>
<module>product-web</module>
</modules>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.5.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.wdbyte</groupId>
<artifactId>springboot-module-demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>springboot-module-demo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<product-common.version>0.0.1-SNAPSHOT</product-common.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.wdbyte</groupId>
<artifactId>product-common</artifactId>
<version>${product-common.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
看似完美,重新 Build-> Build Project 翘簇,發(fā)現(xiàn)一切正常撬码,運(yùn)行發(fā)現(xiàn)一切正常,訪問(wèn)正常版保。
打包編譯
好了呜笑,終于到了最后一步了夫否,你感覺(jué)到勝利的曙光已經(jīng)照到了頭頂,反射出耀眼的光芒叫胁。接著就是 mvn package凰慈。
[INFO] springboot-module-demo ............................. SUCCESS [ 2.653 s]
[INFO] product-common ..................................... FAILURE [ 2.718 s]
[INFO] product-web ........................................ SKIPPED
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 6.084 s
[INFO] Finished at: 2020-03-19T08:15:52+08:00
[INFO] Final Memory: 22M/87M
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.springframework.boot:spring-boot-maven-plugin:2.2.5.RELEASE:repackage (repackage) on project product-common: Execution repackage of goal org.springframework.boot:spring-boot-m
aven-plugin:2.2.5.RELEASE:repackage failed: Unable to find main class -> [Help 1]
[ERROR]
ERROR 讓你傷心了,但是你還是從報(bào)錯(cuò)中尋找到了一些蛛絲馬跡驼鹅,你看到是 spring-boot-maven-plugin 報(bào)出的錯(cuò)誤微谓。重新審視你的主 pom 發(fā)現(xiàn) <build>編譯插件用到了 spring-boot-maven-plugin。
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
略加思索后將這段移動(dòng)到 web模塊的 pom输钩,因?yàn)檫@是 Spring Boot 的打包方式豺型,現(xiàn)在放在主 pom 中所有的模塊都會(huì)繼承到,那么對(duì)于common 模塊來(lái)說(shuō)是肯定不需要的买乃。
移動(dòng)后重新打包姻氨,不管你是運(yùn)行命令mvn package還是雙擊 IDEA 中的 maven 管理中的 package ,想必這時(shí)候你都已經(jīng)打包成功了
在 web
模塊下的目錄 target 里也可以看到打包后的 jar 文件 product-web-0.0.1-SNAPSHOT.jar剪验‰群福可以使用 java 命令直接運(yùn)行。
$ \springboot-module-demo\product-web\target>java -jar product-web-0.0.1-SNAPSHOT.jar
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.2.5.RELEASE)
2020-03-19 08:33:03.337 INFO 15324 --- [ main] com.wdbyte.Application : Starting Application v0.0.1-SNAPSHOT on DESKTOP-8SCFV4M with PID 15324 (C:\Users\83981\Desktop\springboot-mod
ule-demo\product-web\target\product-web-0.0.1-SNAPSHOT.jar started by 83981 in C:\Users\83981\Desktop\springboot-module-demo\product-web\target)
2020-03-19 08:33:03.340 INFO 15324 --- [ main] com.wdbyte.Application : No active profile set, falling back to default profiles: default
2020-03-19 08:33:04.410 INFO 15324 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http)
2020-03-19 08:33:04.432 INFO 15324 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2020-03-19 08:33:04.432 INFO 15324 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.31]
2020-03-19 08:33:04.493 INFO 15324 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2020-03-19 08:33:04.493 INFO 15324 --- [ main] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 1107 ms
2020-03-19 08:33:04.636 INFO 15324 --- [ main] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService 'applicationTaskExecutor'
2020-03-19 08:33:04.769 INFO 15324 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''
2020-03-19 08:33:04.772 INFO 15324 --- [ main] com.wdbyte.Application : Started Application in 1.924 seconds (JVM running for 2.649)
2020-03-19 08:33:07.087 INFO 15324 --- [extShutdownHook] o.s.s.concurrent.ThreadPoolTaskExecutor : Shutting down ExecutorService 'applicationTaskExecutor'
想必少了點(diǎn)什么功戚,多模塊不僅為了結(jié)構(gòu)清晰娶眷,更是為了其他項(xiàng)目可以復(fù)用模塊(如 common 模塊),現(xiàn)在這個(gè)時(shí)候如果你新打開(kāi)了一個(gè)項(xiàng)目啸臀,依賴(lài) common 發(fā)現(xiàn)是引用不到的届宠,因?yàn)槟阈枰涯K安裝到本地倉(cāng)庫(kù)】枪荆可以點(diǎn)擊 IDEA -> Maven -> install席揽,也可以通過(guò) maven 命令。
# -Dmaven.test.skip=true 跳過(guò)測(cè)試
# -U 強(qiáng)制刷新
# clean 清理緩存
# install 安裝到本地倉(cāng)庫(kù)
$ \springboot-module-demo> mvn -Dmaven.test.skip=true -U clean install
重新引入發(fā)現(xiàn)沒(méi)有問(wèn)題了谓厘。
文中代碼已經(jīng)上傳到 Github: https://github.com/niumoo/springboot
最后
感謝大家的閱讀幌羞,喜歡的話建議轉(zhuǎn)發(fā)收藏,后續(xù)會(huì)持續(xù)為大家更新更多的內(nèi)容竟稳,感謝支持属桦。
本文作者: 未讀代碼
本文鏈接: https://www.wdbyte.com/2020/03/springboot/springboot-18-module/