跳至主要內容

Maven综合案例

Ek0wraith大约 6 分钟

一、 Maven中的依赖、继承、聚合三大工程关系

Maven工具基于POM(Project Object Model)项目对象模型模式实现,在Maven中每个项目都相当于是一个对象,对象(项目)和对象(项目)之间是有关系的,关系包含了:依赖、继承和聚合。通过Maven可以更加方便的实现导包、拆分项目等效果。

1、依赖

​ A工程在开发或运行的过程中需要B工程提供支持,这就叫A工程依赖B工程。在这种情况下,需要在A工程的pom.xml文件中增加配置定义依赖关系,通俗理解就是在A中导入B工程jar包。B工程既可以是自己的项目打的jar包,也可以是中央仓库的jar包。

如何在项目中注入依赖?

​ 在pom.xml文件:根元素project下的 dependencies标签中,配置依赖信息,标签内可以包含多个 dependence元素,以声明多个依赖。每个依赖dependence标签都应该包含以下元素:groupId, artifactId, version : 依赖的基本坐标, 对于任何一个依赖来说,基本坐标是最重要的, Maven根据坐标才能找到需要的依赖。

依赖的传递性

​ 传递性依赖是Maven2.0的新特性。假设你的项目依赖于一个库,而这个库又依赖于其他库。你不必自己去找出所有这些依赖,你只需要加上你直接依赖的库,Maven会隐式的把这些库间接依赖的库也加入到你的项目中。这个特性是靠解析从远程仓库中获取的依赖库的项目文件实现的。一般的,这些项目的所有依赖都会加入到项目中,或者从父项目继承,或者通过传递性依赖。也就是说如果A依赖了B,那么C依赖A时会自动把A和B都导入进来。

2、继承

​ 如果projectB继承projectA,则代表projectB默认依赖projectA依赖的所有资源,且可以应用projectA中定义的所有资源信息,而被继承的工程(B工程)只能是POM工程。注意,在父项目中放在dependencyManagement中的内容时不被子项目继承,不可以直接使用。放在dependencyManagement中的内容主要目的是进行版本管理。里面的内容在子项目中依赖时坐标只需要填写group id和artifact id即可,如果子项目不希望使用父项目的版本,可以明确配置version。

​ 子工程通过parent标签指向父工程,就可以直接将父工程中定义好的jar包的版本拿来使用。但是此时作为子工程来讲,jar包的版本可用可不用父工程中管理的。针对此情况,父工程可用使用import范围来强制指定子工程必须使用父工程中管理的版本,不可自作主张随意使用版本。

3、聚合

​ 当我们开发的工程拥有2个以上模块的时候,每个模块都是一个独立的功能集合。比如某大学系统中拥有搜索平台,学习平台,考试平台等。开发的时候每个平台都可以独立编译,测试,运行。这个时候我们就需要一个聚合工程。在创建聚合工程的过程中,总的工程必须是一个POM工程(Maven Project)(聚合项目必须是一个pom类型的项目,jar项目war项目是没有办法做聚合工程的),各子模块可以是任意类型模块(Maven Module)。

​ 聚合包含了继承的特性,聚合时多个项目的本质还是一个项目。这些项目被一个大的父项目包含。且这时父项目类型为pom类型。同时在父项目的pom.xml中出现modules表示包含的所有子模块。

二、 Maven综合案例

1. 项目需求和结构分析

Maven_Test_1

需求案例:搭建一个电商平台项目,该平台包括用户服务、订单服务、通用工具模块等。

项目架构:

  1. 用户服务:负责处理用户相关的逻辑,例如用户信息的管理、用户注册、登录等。
    • spring-context 6.0.6
    • spring-core 6.0.6
    • spring-beans 6.0.6
    • common-service
  2. 订单服务:负责处理订单相关的逻辑,例如订单的创建、订单支付、退货、订单查看等。
    • spring-context 6.0.6
    • spring-core 6.0.6
    • spring-beans 6.0.6
    • spring-security 6.0.6
    • common-service
  3. 通用模块:负责存储其他服务需要通用工具类,其他服务依赖此模块。
    • commons-io 2.11.0
    • junit 5.9.2

2. 项目搭建和统一构建

① 父模块 (micro-shop)

创建工程:

Maven_Test_2

pom.xml配置:(打包方式 pom 包,properties 标签下前几个 xxx.version 用于控制版本)

<?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>

    <groupId>org.Ek0wraith</groupId>
    <artifactId>micro-shop</artifactId>
    <version>1.0-SNAPSHOT</version>
    <!--知识点:父工程的打包方式为pom-->
    <packaging>pom</packaging>
    <modules>
        <module>common-service</module>
    </modules>

    <properties>
        <spring.version>6.0.6</spring.version>
        <jackson.version>2.15.0</jackson.version>
        <commons.version>2.11.0</commons.version>
        <junit.version>5.9.2</junit.version>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <!-- 依赖管理 -->
    <dependencyManagement>
        <dependencies>
            <!-- spring-context会依赖传递core/beans -->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-context</artifactId>
                <version>${spring.version}</version>
            </dependency>

            <!-- jackson-databind会依赖传递core/annotations -->
            <dependency>
                <groupId>com.fasterxml.jackson.core</groupId>
                <artifactId>jackson-databind</artifactId>
                <version>${jackson.version}</version>
            </dependency>

            <!-- commons-io -->
            <dependency>
                <groupId>commons-io</groupId>
                <artifactId>commons-io</artifactId>
                <version>${commons.version}</version>
            </dependency>

            <!-- junit-jupiter-api -->
            <dependency>
                <groupId>org.junit.jupiter</groupId>
                <artifactId>junit-jupiter-api</artifactId>
                <version>${junit.version}</version>
                <scope>test</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>


</project>

② 通用模块 (common-service)

创建工程:

Maven_Test_3

Maven_Test_4

pom.xml 配置:(打包为 jar 包,parent 标签为父工程的位置,dependencies 中各 jar 包版本继承父工程的)

<?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.Ek0wraith</groupId>
        <artifactId>micro-shop</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>

    <artifactId>common-service</artifactId>
    <!--知识点:打包方式默认就是jar,因此可以省略-->
    <packaging>jar</packaging>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <!-- 配置spring-context,继承父工程版本,自动传递 core / beans -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
        </dependency>
        <!-- 配置jackson-databind,继承父工程版本,自动传递 core / annotations -->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
        </dependency>
        <!-- 配置commons-io,继承父工程版本 -->
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
        </dependency>
        <!-- 配置junit,继承父工程版本 -->
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-api</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

</project>

③ 用户模块 (user-service)

创建工程(同上):

Maven_Test_5

pom.xml配置:

<?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.Ek0wraith</groupId>
        <artifactId>micro-shop</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>

    <artifactId>user-service</artifactId>
    <!-- web工程打包方式为war -->
    <packaging>war</packaging>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <!-- 配置common-service,所需依赖会传递到当前工程(仅限compile范围) -->
        <dependency>
            <groupId>org.Ek0wraith</groupId>
            <artifactId>common-service</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
    </dependencies>

</project>

依赖传递结果:

Macen_Test_6

④ 订单模块 (order-service)

创建工程(同上):

Maven _Test_7

pom.xml 配置:

<?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.Ek0wraith</groupId>
        <artifactId>micro-shop</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>

    <artifactId>order-service</artifactId>
    <!-- web工程打包方式为war -->
    <packaging>war</packaging>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.Ek0wraith</groupId>
            <artifactId>common-service</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
    </dependencies>

</project>

此时,查看父工程micro-shop的pom.xml,会发现其中已经自动聚合了子工程:

<modules>
    <module>common-service</module>
    <module>user-service</module>
    <module>order-service</module>
</modules>