MVN3️⃣依赖管理 & 生命周期及插件

1、依赖管理

依赖:当前项目运行所需要的 jar 包。

  • 一个项目可以导入多个依赖,项目本身也可作为依赖被导入。
  • 示例:项目 A 可通过项目 B 的 GAV 坐标将其导入,而不必将两个项目写在一起。

1.1、配置

  • 配置方式:dependencies - dependency - gav。

    <!-- 项目依赖 -->
    <dependencies>
        <!--具体依赖 -->
        <dependency>
            <!-- GAV 坐标 -->
            <groupId></groupId>>
            <artifactId></artifactId>
            <version></version>
        </dependency>
    </dependencies>
    
  • 查看 Maven 依赖关系:Maven - Show Dependencies。

    image

1.2、特点(❗)

1.2.1、传递

依赖具有传递性

相对于当前项目,分为直接传递和间接传递。

  • 直接传递:通过依赖配置建立的依赖关系(A 导入 B,则 AB 是直接传递)

  • 间接传递:通过依赖配置间接建立的依赖关系(A 导入 B、B 导入 C,则 AC 是间接传递)

    image

依赖中出现相同资源时,存在冲突问题。

冲突解决策略:按以下顺序处理

  1. 路径优先:资源相同,优先使用层级浅的。

    image

  2. 声明优先:层级相同,优先使用先声明的。

    image

  3. 特殊情况:一个项目中直接导入了相同资源的不同版本,使用后声明的。

    示例:项目中同时导入 JUnit 的两个版本,优先使用 4.12)

    <dependencies>
        <!-- 先声明 -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.27</version>
        </dependency>
        <!-- 后声明👍 -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
    </dependencies>
    

1.2.2、可选(optional)

(不开放,不给用)

开启 optional,对外隐藏当前所依赖的资源。

示例:A 导入 B,B 导入 C。

  • 根据传递性,C 会被导入 A。

  • 若 B 导入 C 时开启了 optional,则 C 不会被导入 A。

    <!-- B的pom.xml -->
    <dependency>
        <groupId>indi.jaywee</groupId>
        <artifactId>projectC</artifactId>
        <version>1.0</version>
        <!-- true 表示生效 -->
        <optional>true</optional>
    </dependency>
    

1.2.3、排除(exclude)

(不需要,不使用)

指定 GA,排除依赖的资源。

示例:A 导入 B,B 导入 C。

  • 根据传递性,C 会被导入 A。

  • 若 A 导入 B 时通过 exclude 配置了 C 的 GA,则 C 不会被导入 A。

    <!-- A的pom.xml -->
    <dependency>
        <groupId>indi.jaywee</groupId>
        <artifactId>projectB</artifactId>
        <version>1.0</version>
        <exclusions>
            <exclusion>
                <!-- 指定 GA -->
                <groupId>indi.jaywee</groupId>
                <artifactId>projectC</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    

可选 vs 排除

叛逆的 optional 嫌弃的 exclude
谁来配置? 被使用者 B 使用者 A
什么效果? B 被导入时,C 不给 A 用 B 被导入时,A 不想用 C
A 知道 C 的存在?

1.3、依赖范围

1.3.1、scope(❗)

scope:指定依赖(jar 包)的作用范围

  • 作用范围

    • main 可用
    • test 可用
    • 参与打包
  • scope 取值:默认 compile。

    main 可用 test 可用 参与打包 示例
    compile log4j
    provided servlet-api
    runtime jdbc
    test junit

示例

<dependency>
	<groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
    <scope>test</scope>
</dependency>

1.3.2、依赖范围传递

发生依赖的间接传递时,不同的 scope 会导致不同的结果。

示例:A 导入 B,B 导入 C。

  • 传递前提:当前项目导入依赖的 scope 必须支持打包,才会被间接传递。

    (B 导入的 C 必须是 compile/runtime,才会被导入 A)

    <!-- 项目B -->
    <dependency>
    	<groupId>indi.jaywee</groupId>
        <artifactId>projectC</artifactId>
        <version>1.0</version>
        <!-- compile/runtime -->
        <scope>?</scope>
    </dependency>
    
  • 确定最终作用域

    1. 优先取 A:A 导入 B 配置的 scope

    2. 何时取 B:A 的 scope 支持打包,且 B 的 scope 不支持打包(需同时成立)。

      B - compile B - runtime(不支持打包)
      A - compile compile runtime(仅此取 B)
      A - provided provided provided
      A - runtime runtime runtime
      A - test test test

2、生命周期及插件

2.1、生命周期

生命周期:描述项目构建过程中经历的阶段,每个阶段对应插件功能。

  1. clean:清理工作
  2. default:核心工作
  3. site:生成站点文档

2.1.1、clean

执行 clean 命令时,依次执行以下插件。

  1. pre-clean
  2. clean:清理上次构建生成的文件。
  3. post-clean

2.1.2、default(❗)

Hint:执行某一插件时,会按顺序先执行前面所有插件。

插件 作用 备注
validate 校验项目正确,信息完备
initialize 初始化构建状态 如设置属性值
generate-sources 生成编译阶段中的源码 main\java
process-sources 处理源码 如过滤任意值
generate-resources 生成资源文件 main\resources
process-resources 复制并处理资源文件 到 target 目录
compile 编译项目源码,生成字节码文件 到 target\classes 目录
process-classes 处理编译生成的字节码文件 如优化字节码文件
generate-test-sources 生成编译阶段中的测试源码 test\java
process-test-sources 处理测试源码 如过滤任意值
generate-test-resources 创建测试资源文件 test\resources
process-test-resources 复制并处理测试资源文件 到 target 目录
test-compile 编译测试源码,生成字节码文件 到 target\test-classes 目录
process-test-classes 处理编译生成的字节码文件 如优化字节码文件
test 使用合适的单元测试框架(如 JUnit),执行测试用例,生成测试报告 到 target\surefilereports
prepare-package 打包前的准备工作
package 将编译后的代码打包成可分发格式的文件 根据 POM 定义的打包方式,如 JAR,WAR,EAR
pre-integration-test 集成测试前的准备工作 如搭建环境
integration-test 处理和部署项目到可以运行集成测试环境中
post-integration-test 集成测试后的工作 如清理环境
verify 执行任意检查工作,验证项目包有效且达到质量标准
install 安装项目包到本地仓库 此后该项目可作为依赖,被其它本地项目导入
deploy 将项目包部署(复制)到远程仓库 同上,可在远程仓库的使用者中共享

2.1.3、site

  • pre-site
  • site:生成项目的站点文档。
  • post-site
  • site-deploy:将站点文档部署到特定服务器上。

2.2、插件

2.2.1、说明

  • 插件与生命周期的阶段绑定,在对应阶段执行对应的若干个插件功能。
  • 执行构建命令时,若本地没有命令对应的插件,Maven 会自动下载
  • Maven 为每个阶段预设了插件功能(👉见 2.1),也可自定义插件功能。

2.2.2、自定义插件

示例:自定义 maven-source-plugin 插件。

指定以下功能:

  • 当执行到 generate-test-resources 阶段时。

  • 使用 maven-source-plugin 插件将项目源码打成 jar 包。

    <build> 
        <plugins>
            <plugin> 
                <!-- 插件 GAV 坐标-->
                <groupId>org.apache.maven.plugins</groupId> 
                <artifactId>maven-source-plugin</artifactId> 
                <version>2.2.1</version>
                <!-- 执行功能 -->
                <executions>
                    <execution>
                        <!-- 执行目标 -->
                        <goals>
                            <goal>jar</goal> 
                        </goals>
                        <!-- 执行阶段 -->
                        <phase>generate-test-resources</phase>
                    </execution>
                </executions> 
            </plugin>
        </plugins> 
    </build>
    
posted @ 2022-09-02 18:10  Jaywee  阅读(239)  评论(0编辑  收藏  举报

👇