1.事由:
經常看到GitHub上的一些官方demo,為了展示很多功能,項目是由多模塊的形式組織的,基于maven構建的形式為根文件夾下有個pom.xml,每個功能文件夾下又有pom.xml。
剛開始傻傻不會用的時候,直接引入子文件夾下的pom.xml為maven項目。然后有需要看另一個功能又打開了一個子模塊,因為IDE用的是idea,變成了多窗口。后來發現直接打開父模塊接可以了,各個子模塊可以在同一個窗口下切換和啟動。
2.準備
以下最簡單的建一個多模塊項目,為了學習微服務,將建兩個springboot web的子模塊,服務提供者provider和消費者consumer。
兩個服務在同個idea窗口中開發和啟動,測試調用consumer的服務,consumer內部會調用provider。
3.新建父模塊的pom.xml
- new Project -> spring initializr快速構建SpringBoot,artifactId為springbootmodules
- 因為父模塊只是為了組織子模塊用,刪除src等沒用的文件,刪除pom.xml中maven依賴等信息。
- 父模塊打包類型packaging從jar調整為pom
-
添加兩個module:provider和consumer
parent pom.jpg
4.新建子模塊:
new Module - > spring initializr,分別新增artifactId為provider和consumer,放在springbootmodules目錄之下:
結構如下,父pom.xml中的module也不會報錯了
5.更改application.properties
因為兩個SpringBoot項目都默認是8080端口,為了能同時啟動,調整consumer的端口為8081,在consumer的application.properties中添加server.port=8081
6.新增Controller api:
在provider和consumer分別新增兩個controller: ProviderController和ConsumerController,返回最簡單的字符串。
ProviderController.java:
package com.xd.provider.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class ProviderController {
@GetMapping("/provider")
public String provider() {
return "provider";
}
}
ConsumerController中為了調用provider(http://localhost:8081/provider),使用了spring的RestTemplate做http客戶端,多配置了RestTemplate的Bean
package com.xd.consumer;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
@SpringBootApplication
public class ConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(ConsumerApplication.class, args);
}
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
package com.xd.consumer.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
@RestController
public class ConsumerController {
@Autowired
private RestTemplate restTemplate;
@GetMapping("/consumer")
public String consumer() {
return "consumer";
}
@GetMapping("/consumerUseProvider")
public String consumerUseProvider() {
return "consumer use " + this.restTemplate.getForObject("http://localhost:8081/provider", String.class);
}
}
7.啟動服務和測試
8.調整pom.xml
父pom.xml現在只有管理兩個子模塊的作用,可以抽取子模塊統一的配置信息和依賴版本控制放父模塊中管理。
父pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
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>
<groupId>com.xd</groupId>
<artifactId>springbootmodules</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<modules>
<module>provider</module>
<module>consumer</module>
</modules>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<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>
</dependency>
</dependencies>
</project>
子模塊pom.xml,設置parent為springbootmodules:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
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>
<groupId>com.xd</groupId>
<artifactId>provider</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>provider</name>
<description>Demo project for Spring Boot</description>
<parent>
<!--<groupId>org.springframework.boot</groupId>-->
<!--<artifactId>spring-boot-starter-parent</artifactId>-->
<!--<version>2.1.1.RELEASE</version>-->
<!--<relativePath/> <!– lookup parent from repository –>-->
<groupId>com.xd</groupId>
<artifactId>springbootmodules</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<!--<properties>-->
<!--<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>-->
<!--<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>-->
<!--<java.version>1.8</java.version>-->
<!--</properties>-->
<!--<dependencies>-->
<!--<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>-->
<!--</dependency>-->
<!--</dependencies>-->
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
9.打包jar測試
使用mvn clean package命令,或點擊idea maven窗口功能,把兩個子模塊打成jar包:
使用java -jar命令啟動兩個服務:
java -jar /Users/TryXD/code/try/springbootmodules/provider/target/provider-0.0.1-SNAPSHOT.jar
java -jar /Users/TryXD/code/try/springbootmodules/consumer/target/consumer-0.0.1-SNAPSHOT.jar
兩個服務都正常啟動,并且服務消費者consumer調用服務提供者provider正常: