微服务需要根据业务模块拆分,做到单一职责,不要重复开发相同业务。

父工程

微服务是一种分布式开发,要将一个项目拆分为若干个服务,所以会有很多个服务模块。而要统一管理这些服务模块,可以创建一个父工程来管理。

在Maven中,用来统一管理的父工程是一个不包含实际代码,只含有pom.xml的模块。通过在pom.xml定义一些统一的信息(如依赖、依赖的版本等等),从而来管理整个工程。

父工程Maven依赖(pom.xml):

 1<project xmlns="http://maven.apache.org/POM/4.0.0"
 2         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 3         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 4    <modelVersion>4.0.0</modelVersion>
 5
 6    <groupId>asia.linner.demo</groupId>
 7    <artifactId>cloud-demo</artifactId>
 8    <version>1.0</version>
 9
10    <!-- 声明子模块 -->
11    <modules>
12        <module>user-service</module>
13        <module>order-service</module>
14
15        <!-- ... -->
16    </modules>
17
18    <!-- 打包方式 -->
19    <packaging>pom</packaging>
20
21    <!-- 父工程 -->
22    <parent>
23        <groupId>org.springframework.boot</groupId>
24        <artifactId>spring-boot-starter-parent</artifactId>
25        <version>2.3.9.RELEASE</version>
26        <relativePath/>
27    </parent>
28
29    <properties>
30        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
31        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
32        <java.version>1.8</java.version>
33        <spring-cloud.version>Hoxton.SR10</spring-cloud.version>
34        <mysql.version>5.1.47</mysql.version>
35        <mybatis.version>2.1.1</mybatis.version>
36    </properties>
37
38    <!-- 声明依赖,并不进行导入(子模块依然需要导入,但不用指定版面) -->
39    <dependencyManagement>
40        <dependencies>
41            <!-- SpringCloud依赖库 -->
42            <dependency>
43                <groupId>org.springframework.cloud</groupId>
44                <artifactId>spring-cloud-dependencies</artifactId>
45                <version>${spring-cloud.version}</version>
46                <type>pom</type>
47                <scope>import</scope>
48            </dependency>
49
50            <!-- MySQL驱动 -->
51            <dependency>
52                <groupId>mysql</groupId>
53                <artifactId>mysql-connector-java</artifactId>
54                <version>${mysql.version}</version>
55            </dependency>
56            <!-- MyBatis -->
57            <dependency>
58                <groupId>org.mybatis.spring.boot</groupId>
59                <artifactId>mybatis-spring-boot-starter</artifactId>
60                <version>${mybatis.version}</version>
61            </dependency>
62
63            <!-- ... -->
64        </dependencies>
65    </dependencyManagement>
66
67    <dependencies>
68        <dependency>
69            <groupId>org.projectlombok</groupId>
70            <artifactId>lombok</artifactId>
71        </dependency>
72
73        <!-- ... -->
74    </dependencies>
75</project>

其中主要的有:

  • 父工程:和SpringBoot一样,使用SpringCloud需要导入父工程。

    1<!-- 父工程 -->
    2<parent>
    3    <groupId>org.springframework.boot</groupId>
    4    <artifactId>spring-boot-starter-parent</artifactId>
    5    <version>2.3.9.RELEASE</version>
    6    <relativePath/>
    7</parent>
    
  • SpringCloud依赖:

    1<!-- SpringCloud依赖库 -->
    2<dependency>
    3    <groupId>org.springframework.cloud</groupId>
    4    <artifactId>spring-cloud-dependencies</artifactId>
    5    <version>${spring-cloud.version}</version>
    6    <type>pom</type>
    7    <scope>import</scope>
    8</dependency>
    

    声明在<dependencyManagement><dependencies>中。SpringCloud依赖库定义了SpringCloud的依赖以及它们的版本。

    <dependencyManagement>是对整个项目的依赖版本的管理。在<dependencyManagement>元素中声明所依赖的jar包的版本号等信息,那么所有子项目再次引入此依赖jar包时则无需显式的列出版本号,Maven会沿着父子层级向上寻找拥有<dependencyManagement>元素的项目,然后使用它指定的版本号。

    例如在SpringBoot中,引入了父工程spring-boot-starter-parent,那么引入spring-boot-starter-web这些在父工程中已经将版本定义好了的依赖,就无需在当前工程的pom.xml中指定版本。

    在当前<dependencies>(不是<dependencyManagement>下的<dependencies>中声明的依赖,会直接被导入,并且被子子项目所继承。

  • <modules>:利用<modules>可以很好地进行多模块开发。

    1<!-- 声明模块 -->
    2<modules>
    3    <module>user-service</module>
    4    <module>order-service</module>
    5
    6    <!-- ... -->
    7</modules>
    

    在构建当前项目时,Maven会根据<modules>中的声明,去寻找相应的模块并自动完成构建。

    <modules>的值是对应模块的<artifactId>的值。

微服务拆分

子模块Maven依赖示例(pom.xml):

 1<project xmlns="http://maven.apache.org/POM/4.0.0"
 2         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 3         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 4
 5    <!-- 与父工程中所定义的相对应 -->
 6    <parent>
 7        <groupId>asia.linner.demo</groupId>
 8        <artifactId>cloud-demo</artifactId>
 9        <version>1.0</version>
10    </parent>
11    
12    <modelVersion>4.0.0</modelVersion>
13
14    <artifactId>user-service</artifactId>
15
16    <dependencies>
17        <dependency>
18            <groupId>org.springframework.boot</groupId>
19            <artifactId>spring-boot-starter-web</artifactId>
20        </dependency>
21        <!-- MySQL -->
22        <dependency>
23            <groupId>mysql</groupId>
24            <artifactId>mysql-connector-java</artifactId>
25        </dependency>
26        <!-- MyBatis -->
27        <dependency>
28            <groupId>org.mybatis.spring.boot</groupId>
29            <artifactId>mybatis-spring-boot-starter</artifactId>
30        </dependency>
31    </dependencies>
32
33    <build>
34        <finalName>app</finalName>
35        <plugins>
36            <plugin>
37                <groupId>org.springframework.boot</groupId>
38                <artifactId>spring-boot-maven-plugin</artifactId>
39            </plugin>
40        </plugins>
41    </build>
42</project>

其中,该项目的父工程为

1<parent>
2    <groupId>asia.linner.demo</groupId>
3    <artifactId>cloud-demo</artifactId>
4    <version>1.0</version>
5</parent>

模块声明的父工程对应父工程中定义的<groupId><artifactId><version>。当前项目会继承父工程中定义的版本号和依赖。所以spring-boot-starter-webmysql-connector-javamybatis-spring-boot-starter都无需显式地声明版本。