2、Maven 核心概念

学习资源:动力节点《2020最新Maven教程-Maven基础篇之Maven实战入门》



1、约定的目录结构

Maven约定的目录结构, 约定是大家都遵循的一个规则,所以并不是强制遵守的,每一个 Maven 项目在磁盘中都是一个文件夹,

Maven Java 工程约定的目录结构:

image-20200825103455563

目录结构说明:

  • Hello:根目录,也就是工程名
    • src:源代码
      • main:主程序
        • java: 主程序的 java 源码和配置文件
        • resources: 主程序的配置文件
      • test:测试程序(可以没有)
        • java:测试程序的 java 源码
        • resources:测试程序的配置文件
    • pom.xml:Maven 工程的核心配置文件

image-20200825182811684

一般情况下,我们习惯上采取的措施是:约定 > 配置 > 编码。Maven 的 pom.xml 记录的关于构建项目的各个方面的设置,Maven 从 pom.xml 文件开始,按照助约定的 Maven 工程目录编译,测试,打包,部署,发布项目。


2、Maven 的生命周期

对项目的构建是建立在生命周期模型上的,它明确定义项目生命周期各个阶段,并且对于每一个阶段提供相对应的命令,对开发者而言仅仅需要掌握一小堆的命令就可以完成项目各个阶段的构建工作。构建项目时按照生命周期顺序构建,每一个阶段都有特定的插件来完成。不论现在要执行生命周期中的哪个阶段,都是从这个生命周期的最初阶段开始的。

对于我们程序员而言,无论我们要进行哪个阶段的构建,直接执行相应的命令即可,无需担心它前边阶段是否构建, Maven 都会自动构建。这也就是 Maven 这种自动化构建工具给我们带来的好处。


3、Maven 的常用命令

Maven 对所有的功能都提供相对应的命令,要想知道 maven 都有哪些命令,那要看 maven 有哪些功能。一开始就跟大家说了, Maven 三大功能: 管理依赖构建项目管理项目信息。 管理依赖,只需要进行依赖声明就可以自动到仓库下载;管理项目信息其实就是生成一个站点文档,一个命令就可以解决,最后再说;那 Maven 功能的主体其实就是项目构建。

Maven 提供一个项目构建的模型,把编译、测试、打包、部署等都对应成一个个的生命周期阶段, 并对每一个阶段提供相应的命令,程序员只需要掌握一小堆命令,就可以完成项目的构建过程。

  • mvn clean:清理(会删除原来编译和测试的目录,即 target 目录,但是已经 install 到仓库里的包不会删除)
  • mvn compile:编译主程序,main/java下的程序(会在当前目录下生成一个 target,里边存放编译主程序之后生成的字节码文件和资源、配置文件)
    初次使用这个命令,会下载很多插件到本机仓库

image-20200825183027034

  • mvn test-compile:编译测试程序 -- test/java下的程序(会在当前目录下生成一个 target,里边存放编译测试程序之后生成的字节码文件)
  • mvn test:测试(会生成一个目录 surefire-reports ,保存测试结果)
  • mvn package:打包主程序,输出到当前目录的 target 路径下,包名 = artifactId + version(打包过程会进行编译、编译测试、测试、并且按照 pom.xml 中的配置把主程序打包生成 jar 包或者 war ),项目所需要用到的 jar 会打包到 WEB-INF\lib 下
  • mvn install:安装主程序(会把本工程打包,并且按照本工程的 gav 坐标保存到本地仓库中)
  • mvn deploy:部署主程序(会把本工程打包,按照本工程的坐标保存到本地库中,并且还会保存到私服仓库中。还会自动把项目部署到 web 容器中)

注意:执行以上命令必须在命令行进入 pom.xml 所在目录!


4、插件

Maven 过程构建周期, 实际上是由 Maven 的插件 plugin 来执行完成。

  1. clean 插件 maven-clean-plugin:2.5:clean 阶段是独立的一个阶段,功能就是清除工程目前下的 target 目录
  2. resources 插件 maven-resources-plugin:2.6:resource 插件的功能就是把项目需要的配置文件拷贝到指定的目当,默认是拷贝 src\main\resources 目录下的件到 classes 目录下
  3. compile 插件 maven-compiler-plugin:

5、POM 文件

即 Project Object Model 项目对象模型。 Maven 把一个项目的结构和内容抽象成一个模型,在 xml 文件中进行声明,以方便进行构建和描述, pom.xml 是 Maven 的灵魂。所以, Maven 环境搭建好之后,所有的学习和操作都是关于 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">
    
    // 父工程
    <parent>
        <artifactId>xxxxxxxx</artifactId>
        <groupId>xxxxxxxx</groupId>
        <version>xxxxxxxx</version>
    </parent>
    
    <modelVersion>4.0.0</modelVersion>

    // 此处是这个Maven工程的gav
    <groupId>org.example</groupId>
    <artifactId>maven_1</artifactId>
    <version>1.0-SNAPSHOT</version>

    <packaging>jar</packaging>
    
    <dependencies>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.21</version>
        </dependency>
    </dependencies>
    
    <properties>
        <!--maven构建项目使用的是utf-8 ,避免中文的乱码-->
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <!--编译java代码使用的jdk版本-->
        <maven.compiler.source>1.8</maven.compiler.source>
        <!--你的java项目应该运行在什么样的jdk版本-->
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>
    
    <!--控制配置maven构建项目的参数设置,设置jdk的版本-->
	<build>
        <!--配置插件-->
        <plugins>
            <!--配置具体的插件-->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <!--插件的名称-->
                <artifactId>maven-compiler-plugin</artifactId>
                <!--插件的版本-->
                <version>3.8.1</version>
                <!--配置插件的信息-->
                <configuration>
                    <!--告诉maven我们的写的代码是在jdk1.8上编译的-->
                    <source>1.8</source>
                    <!--我们的程序应该运行在jdk1.8上-->
                    <target>1.8</target>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

pom.xml中的标签:

  • modelVersion:Maven 模型的版本,对于 Maven2 和 Maven3 来说,它只能是 4.0.0
  • gav:由 groupId 、 artifactId 、 version 三个元素,生成了一个 Maven 项目的基本坐标,在众多的 Maven 项目中可以唯一定位到某一个项目,坐标也决定着将来项目在仓库中的路径及名称。
    • groupId:组织 id,一般是公司域名的倒写。 格式可以为:
      • 域名倒写。 例如 com.baidu
      • 域名倒写+项目名。例如 com.baidu.appolo
    • artifactId:项目名称,也是模块名称,对应 groupId 中 项目中的 子项目
    • version:项目的版本号。如果项目还在开发中,是不稳定版本, 通常在版本后带-SNAPSHOT version 使用三位数字标识,例如 1.1.0
  • packaging:项目打包的类型,可以使 jar、 war、 rar、 ear、 pom,默认是 jar
  • dependencies,dependency:导入依赖,Maven 的一个重要作用就是管理 jar 包,为了一个项目可以构建或运行,项 目中不可避免的,会依赖很多其他的 jar 包,在 Maven 中,这些 jar 就被称 为依赖,使用标签 dependency 来配置。 而这种依赖的配置正是通过坐标来 定位的,由此我们也不难看出, maven 把所有的 jar 包也都视为项目存在了。
  • properties:配置属性,properties 是用来定义一些配置属性的,例如 project.build.sourceEncoding(项目构建源码编码方式),可以设置为 UTF-8,防止中文乱码,也可定义相关构建版本号,便于日后统一升级。
  • build:build 表示与构建相关的配置, 例如设置编译插件的 jdk 版本
  • parent:继承,在 Maven 中,如果多个模块都需要声明相同的配置,例如: groupId、 version、 有相同的依赖、或者相同的组件配置等, 也有类似 Java 的继承机 制, 用 parent 声明要继承的父工程的 pom 配置。
  • modules:聚合,在 Maven 的多模块开发中,为了统一构建整个项目的所有模块,可以提供一 个额外的模块,该模块打包方式为 pom,并且在其中使用 modules 聚合的 其它模块,这样通过本模块就可以一键自动识别模块间的依赖关系来构建所有 模块,叫 Maven 的聚合。

6、仓库

6.1、仓库的概念

现在我们对 Maven 工程有一个大概的认识了,那现在思考一个问题, Maven 怎么就这么神奇,我们写完的工程交给它之后,它就能够自动帮我们管理,我们依赖的jar包它从哪儿获取呢? 有同学说已经安装了,在它的安装包里啊,大家可以看一下 Maven下载下来8M,我们需要的 jar 包有时候都几百M甚至几个G,它从哪儿弄去呢?

其实, Maven 有仓库的概念。 在Maven中,任何一个依赖、插件或者项目构建的输出,都可以称之为构件。 Maven 核心程序仅仅定义了自动化构建项目的生命周期,但具体的构建工作是由特定的构件完成的。而且为了提高构建的效率和构件复用, Maven 把所有的构件统一存储在某一个位置,这个位置就叫做仓库


6.2、仓库存什么

  1. Maven 的插件,插件也是一些 jar,这些 jar 可以完成一定的功能。
  2. 我们自己开发项目的模块
  3. 第三方框架或工具类的 jar 包

6.3、仓库的类别

根据仓库存储的位置,把仓库分为本地仓库和远程仓库。

本地仓库,存在于当前电脑上,默认存放在 ~\.m2\repository(~ 是用户的主目录, windows系统中是 c: /user/登录系统的用户名) 中,为本机上所有的 Maven 工程服务。你也可以通过 Maven 的配置文件 Maven_home/conf/settings.xml 中修改本地仓库所在的目录。

远程仓库,分为为全世界范围内的开发人员提供服务的中央仓库、为全世界范围内某些特定的用户提供服务的中央仓库镜像、为本公司提供服务自己架设的私服。中央仓库是 Maven 默认的远程仓库,其地址是:http://repo.maven.apache.org/maven2/

中央仓库, 包含了绝大多数流行的开源Java构件,以及源码、作者信息、许可证信息等。一般来说,简单的 Java 项目依赖的构件都可以在这里下载得到。

私服,是一种特殊的远程仓库,它是架设在局域网内的仓库服务,私服代理广域网上的远程仓库,供局域网内的Maven用户使用。当 Maven 需要下载构件的时候,它从私服请求,如果私服上不存在该构件,则从外部的远程仓库下载,缓存在私服上之后,再为 Maven 的下载请求提供服务。我们还可以把一些无法从外部仓库下载到的构件上传到私服上。

分类说明:

  1. 本地仓库: 本机当前电脑上的资源存储位置,为本机上所有 Maven工程提供服务
  2. 远程仓库:不在本机上, 通过网络才能使用。多电脑共享使用的。
    1. 中央仓库: 通过Internet访问,为全世界所有 Maven工程服务。 最权威的。
    2. 中央仓库的镜像:架设在不同位置,欧洲,美洲,亚洲等每个洲都有若干的服务器,为中央仓库分担流量。减轻中央仓库的访问,下载的压力。所在洲的用户首先访问的是本洲的镜像服务器。
    3. 私服: 在局域网环境中部署的服务器,为当前局域网范围内的所有 Maven工程服务。 公司中常常使用这种方式

image-20200825111718542

6.4、Maven 对仓库的使用

在 Maven 构建项目的过程中如果需要某些插件,只需要在 pom.xml 中引入相关的然后Maven会自动地:

  1. 首先会到 Maven 的本地仓库中查找,如果找到则可以直接使用
  2. 如果找不到,它会自动连接外网,到远程中央仓库中查找
  3. 如果远程仓库中能找到,则先把所需要的插件下载到本地仓库,然后再使用,并且下次再用到相同的 jar 也可以直接使用本地仓库的
  4. 如果没有外网或者远程仓库中也找不到,则构建失败。

Maven 资源搜索地址: https://mvnrepository.com/


7、坐标(gav)

Maven 把任何一个插件都作为仓库中的一个项目进行管理, 用一组(三个)向量组成的坐标来表示。 坐标在仓库中可以唯一定位一个 Maven 项目。

  • groupId: 组织名,通常是公司或组织域名倒序+项目名
  • artifactId: 模块名,通常是工程名
  • version: 版本号

需要特别指出的是, 项目在仓库中的位置是由坐标来决定的: groupId、 artifactId 和 version 决定项目在仓库中的路径, artifactId 和 version 决定 jar 包的名称


8、依赖(dependency)

一个 Maven 项目正常运行需要其它项目的支持, Maven 会根据坐标自动到本地仓库中进行查找。对于程序员自己的 Maven 项目需要进行安装,才能保存到仓库中。

不用 Maven 的时候所有的 jar 都不是你的,需要去各个地方下载拷贝,用了 Maven 所有的 jar 包都是你的,想要谁,写出谁的名字就行, Maven 帮你下载。

pom.xml 加入依赖的方式:

<!--log4j 日志依赖-->
<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.17</version>
</dependency>

<!--junit 单元测试依赖-->
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.11</version>
</dependency>

9、单元测试

Maven使用 junit 进行方法的测试, junit 是一个专门测试的框架(工具)。

junit 测试的内容:测试的是类中的方法, 每一个方法都是独立测试的,方法是测试的基本单位(单元)。

Maven借助单元测试,批量的测试你类中的大量方法是否符合预期的。

使用步骤:

  1. 在 pom.xml 加入单元测试依赖
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
    <scope>test</scope>
</dependency>
  1. 在 Maven 项目中的 src/test/java目录下,创建测试程序。推荐的创建类和方法的提示:
    • 测试类的名称创建为:Test + 要测试的类名
    • 测试的方法名称创建为:Test + 方法名称

示例:

public class HelloWorld{
    
    public int add(int a, int b){
        return a+b;
    }
    
    public int sub(int a, int b){
        return a-b;
    }
}

public class TestHelloWorld{
    
    @Test
    public void testAdd(int a, int b){
    
        // 测试
    }
    
    @Test
    public void testSub(int a, int b){
    
        // 测试
    }
}
posted @ 2020-08-26 21:22  卡文迪雨  阅读(154)  评论(0编辑  收藏  举报