本人JavaWeb学习笔记中的 在IDEA中配置Maven项目

依赖配置:依赖指当前项目运行需要的jar,一个项目可以设置多个依赖

依赖传递

直接依赖:在当前项目中通过依赖配置建立的依赖关系

间接依赖:直接依赖所依赖的资源

依赖冲突

  • 路径优先:当依赖中出现相同的资源时,层级越深,优先级越低,层级越浅,优先级越高(类似就近原则)
  • 声明优先:当资源在相同层级被依赖时,配置顺序靠前的覆盖配置顺序靠后的
  • 特殊优先:当同级配置了相同资源的不同版本,后配置的覆盖先配靠的(应避免这种无意义冲突)

可选依赖(隐藏依赖):对外隐藏当前所依赖的资源。配置方式:在引入依赖时将 <optional> 设置为true

排除依赖:主动断开依赖的资源,被排除的资源无需指定版本。配置方式:在引入依赖时在 <exclusions> 指定组织编号和项目名

隐藏依赖是不让其他项目来引用(我不给),排除依赖是主动不要引入的某个资源(我不要)

依赖范围

依赖的jar默认情况可以在任何地方使用,在引入依赖时通过 <scope> 标签设定其作用范围

  • 主程序范围有效(src/main文件夹范围内)
  • 测试程序范围有效(src/test文件夹范围内)
  • 是否参与打包(package指令范围内)
  • compile(默认,在主程序、测试代码、打包都有效)
scope 主代码 测试代码 打包 范例
compile(默认) log4j
test junit
provided servlet-api
runtime jdbc

解读:

  1. 某个引入的jar包作用范围是程序员根据,业务的实际需要来设置的,不要认为是固定的。比如log4j jar包,在主程序,测试代码,打包都是需要的,因此作用范围应当设置为complie
  2. junit只是测试代码需要,因此作用范围设置为test合适,但是如果程序员认为在主程序和打包就是要junit,仍然可以设置为默认compile
  3. 比如servlet-api是tomcat自己带的,当把程序打包放到生产环境时,用生产环境tomcat的servlet-api 即可,所以设置为provided合适,这样就防止servlet-api版本冲突
  4. 比如jdbc,是第三方的jar,打包放在生产环境,就应当在自已的包提供jdbc驱动包,否则程序会因为少驱动包,运行失败
  5. 细节:设置了scope属性后,该依赖无法传递到其他项目中

手动实现Maven项目

  1. 创建 D:\MyMaven 目录,子目录java-project-maven的结构如下:

    • \src\main\java
    • \src\main\resources
    • \src\test\java
    • \src\test\resources
  2. 创建 src\main\java\org\exerciese\Hello.java

    1
    2
    3
    4
    5
    6
    7
    8
    package org.exercise;

    public class Hello {
    public String sum(int n1, int n2) {
    return "sum=" + (n1 + n2);
    }
    }

  3. 创建 src\test\java\org\exerciese\TestHello.java

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    package org.exercise;

    import org.junit.Assert;
    import org.junit.Test;

    public class TestHello {
    @Test
    public void testSum() {
    Hello hello = new Hello();
    String res = hello.sum(10, 50);
    //Assert 是一个断言类,(就是判断实际返回的值和期望值是否相同)
    Assert.assertEquals("sum=60", res);

    }
    }

  4. 创建 \pom.xml 文件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    <?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
    1. 描述这个pom文件/pom模型遵循的哪个版本
    2. 对应maven2 和 maven3 而言, 这里的modelVersion只能是4.0.0
    -->
    <modelVersion>4.0.0</modelVersion>

    <!--
    解读: 下面是指定该项目的坐标, 是创建项目时,程序员指定
    1. groupId: 组织名
    2. artifactId: 项目名
    3. version: 版本
    -->
    <groupId>org.exercise</groupId>
    <artifactId>java-project-maven</artifactId>
    <version>1.0-SNAPSHOT</version>
    <!--
    老师解读
    1. 这里就是引入项目需要的jar包, 类似传统项目的import jar的作用
    2. 在 dependencies标签内, 可以指定多个需要依赖的jar /导入jar
    3. 引入的jar包需要一个完整的jar包坐标, 从mvn仓库查询得到
    -->
    <dependencies>
    <dependency>
    <!-- 依赖jar的 groupId : 组织名-->
    <groupId>junit</groupId>
    <!-- 依赖jar的 artifactId : 项目名-->
    <artifactId>junit</artifactId>
    <!-- 依赖jar的 version : 版本-->
    <version>4.12</version>
    <!-- 该jar包的作用范围, 这里就是说引入的junit包,作用范围在 src/test。。目录下,
    关于scope后面我们还会详解.
    -->
    <scope>test</scope>
    </dependency>
    </dependencies>
    </project>

生命周期

  1. 编译

    • 在项目根目录下进入cmd,输入如下指令

      1
      mvn compile
    • 完成后会得到新建的 /target/classes 和 /target/maven-status 目录

  2. 测试

    • 在项目根目录下进入cmd,输入如下指令

      1
      mvn test
    • 命令行中会得到测试的总体报告、每个测试用例的报告,得到新建的 /test-classes 目录和 /target/surefire-reports 目录(输出运行结果)

  3. 打包

    • 在项目根目录下进入cmd,输入如下指令

      1
      mvn package
    • 完成后会得到 /target/maven-archiver 目录和打包的 /target/项目名-版本号.jar 文件

  4. 安装

    • 在项目根目录下进入cmd,输入如下指令

      1
      mvn install
    • 会把打包得到的 .jar,提交到本地仓库(如果修改了 settings.xml 配置的默认仓库路径,生成的 .jar 会在指定的仓库路径下),之后该 jar 也可以被本地其他 maven 项目使用

  5. 清理

    • 在项目根目录下进入cmd,输入如下指令

      1
      mvn clean
    • 会清除target目录

    • 应用场景:比如我们希望把源码进行拷贝或移植,或者希望来一次全新的bulid,就可以先进行clean

  6. 总结

    Maven构建命令使用mvn开头,后面添加功能参数,可以一次执行多个命令,使用空格分隔

    1
    2
    3
    4
    5
    mvn compile #编译
    mvn clean #清理
    mvn test #测试
    mvn package #打包
    mvn install #安装

Maven项目构建

生命周期的三大阶段

生命周期Lifecycle:一次构建过程经历了多少个事件,通过插件plugin实现

clean:清理工作

生命周期 对应事件
pre-clean 执行一些需要在clean之前完成的工作
clean 移除所有上一次构建生成的文件
post-clean 执行一些需要在clean之后立刻完成的工作

default:核心工作,例如编译,测试,打包,部署等

生命周期 对应事件
validate(校验) 校验项目是否正确并且所有必要的信息,可以完成项目的构建过程
initialize(初始化) 初始化构建状态,比如设置属性值。
generate-sources(生成源代码) 生成包含在编译阶段中的任何源代码
process-sources(处理源代码) 处理源代码,比如过滤任意值
generate-resources(生成资源文件) 生成将会包含在项目包中的资源文件
process-resources(处理资源文件) 复制和处理资源到自标自录,为打包阶段最好准备。
compile(编译) 编译项自的源代码
process-classes(处理类文件) 处理编译生成的文件,比如说对javaclass文件做字节码改善优化。
generate-test-sources(生成测试源代码) 生成包含在编译阶段中的任何测试源代码。
process-test-sources(处理测试源代码) 处理测试源代码,比如说,过滤任意值。
generate-test-resources(生成测试资源文件) 为测试创建资源文件。
process-test-resources(处理测试资源文件) 复制和处理测试资源到目标目录
test-compile(编译测试源码) 编译测试源代码到测试目标目录
process-test-classes(处理测试类文件) 处理测试源码编译生成的文件
test(测试) 使用合适的单元测试框架运行测试(Juint是其中之一)
prepare-package(准备打包) 在实际打包之前,执行任何的必要的操作为打包做准备。
package(打包) 将编译后的代码打包成可分发格式的文件,比如JAR、WAR或者EAR文件
pre-integration-test(集成测试前) 在执行集成测试前进行必要的动作。比如说,搭建需要的环境
integration-test(集成测试) 处理和部署项自到可以运行集成测试环境中,
post-integration-test(集成测试后) 在执行集成测试完成后进行必要的动作。比如说,清理集成测试环境
verify(验证) 运行任意的检查来验证项目包有效且达到质量标准。
install(安装) 安装项自包到本地仓库,这样项自包可以用作其他本地项自的依赖
deploy(部署) 将最终的项目包复制到远程仓库中与其他开发者和项目共享。

site:产生报告,发布站点等

生命周期 对应事件
pre-site 执行一些需要在生成站点文档之前完成的工作
site 生成项目的站点文档
post-site 执行一些需要在生成站点文档之后完成的工作,并直为部署做准备
site-deploy 将生成的站点文档部署到特定的服务器上

生命周期的分阶段执行

  • 项目构建生命周期分很多阶段,并不是每次都完整执行,而是根据用户的要求来执行的
  • 比如执行compile,那么就执行到compile这个阶段;如果执行install,则会执行compile→test→package→install

插件

官方文档:Maven – Available Plugins (可用插件)

插件与生命周期内的某个阶段绑定,在执行到对应生命周期时,由对应插件来完成任务/功能

使用方式:在pom.xml文件的 <build>→<plugin> 标签中引入

除了插件的坐标外,通过 <executions> 标签中的 <execution> 配置执行的操作内容:<phase> 指定调用阶段,<goals>指定执行结果(可在 Goals Overview 查看相关说明)

说明:

  • 项目对象模型POM,主要作用是依赖Dependency管理

  • 在maven项目构建生命周期中,每个阶段的执行都有相应的插件完成

  • 各个插件执行过程中,会附带输出内容,比如jar/war/xml/源码

  • 程序员可以使用maven默认的插件,也可以自定义插件,完成定制任务