【重学maven】构建标准清晰地java工程

2022年05月14日 阅读数:3
这篇文章主要向大家介绍【重学maven】构建标准清晰地java工程,主要内容包括基础应用、实用技巧、原理机制等方面,希望对大家有所帮助。

intro

今天 跑了一个项目 maven 这里出了各类 各样的项目
配了半天 仍是 重学一下 maven 让本身能 标准的操做一个 java 工程html

经常使用的 代码构建工具 有 ant,maven和gradle
我本身认为 目前比较主流的构建工具 仍是 maven 然鹅 我司使用的构建工具是 gradle
Gradle与Maven相比更为灵活,
Hibernate就将本身的项目从Maven迁移到了Gradle,Google官方Android开发的IDE Android Studio也默认使用了Gradle进行构建。
将来可能就是 gradle 的天下了 不过 maven 目前仍是主流 还须要好好了解一下 maven 至少如今宝刀未老 还有很强大的生命力java

【重学maven】构建标准清晰地java工程_面试复习
推荐两个网站 搜索 maven 依赖mysql

  • 【最全最多】mvnrepository https://mvnrepository.com/
  • 【国内加速】阿里镜像源 https://maven.aliyun.com/mvn/guide
  • 【maven官网】 https://maven.apache.org/

构建工具:解放程序员的双手

先不局限在构建工具 maven自身,先了解下什么是构建工具
构建工具是指一个可以自动完成和软件项目构建相关的全部操做的工具。程序员

构建一个软件项目一般包含下面的一步或多步。

  • 生成源码。
  • 生成源码中定义的文档。
  • 编译源码。
  • 将编译后的源码打包为 JAR 或 ZIP 格式文件。
  • 将源码打包成 JAR,运行在服务器、仓库或者其余位置。
  • 自动完成这些构建操做的好处是减小了手动操做时引起错误的风险,另外,自动构建每每比人手动操做要快捷许多。

Maven 的好处

Maven 最主要的目的是让开发人员花少许时间就能理解一个开发工做的完整状态。
为了达到这个目标,Maven 在如下几个方面作出了优化和改进。web

  • 简化项目构建的流程。
    虽然使用 Maven 并不是彻底不须要了解其底层机制,
    但 Maven 屏蔽了许多的细节,
    让咱们经过简单的命令就能使用。
  • 提供一个统一的构建系统。
    Maven 经过其项目对象模型(POM)和能够被全部项目共享的插件来为项目提供统一的构建机制。
    你只要熟悉一个 Maven 项目的构建流程,
    你就了解了全部 Maven 项目的构建流程,
    这为你在浏览其余许多项目时节省了大量的时间。
  • 提供完备的项目信息。
    Maven 提供了大量有用的项目信息,
    这些信息部分来自于项目的 POM 文件,
    部分来自于项目的源代码。

Maven 可以提供的信息以下。

  • 直接从代码管理软件中建立的更新日志。
  • 代码交叉引用。
  • 项目中管理的邮件列表。
  • 项目的依赖列表。
  • 单元测试报告以及覆盖率。

随着 Maven 的不断改进,这些信息的展现都会继续优化,对开发者而言都会是透明的。面试

同时,其余第三方产品也能够提供 Maven 插件来让他们项目的相关信息与 Maven 提供的信息一同展示出来,这也是基于 POM 的。sql

为各类项目开发提供最佳实践的引导。数据库

Maven 旨在聚集全部开发的最佳实践来使新项目的引导指南更加简洁。
例如,单元测试的规范、执行和报告是使用 Maven 进行标准构建的一部分,
目前的单元测试最佳实践以下。apache

  • 将单元测试的代码与源代码分离,存放在同一级目录下。
  • 使用测试用例命名规范来定位和执行测试。
  • 让测试用例自行初始化其运行环境而不是依赖于自定义的构建。
  • Maven 还旨在协助项目工做流,例如项目的发布及问题的管理。

最后,Maven 也对项目的目录结构制定了相关的规范,
这样,开发者能够很轻松地掌握其余遵照了这一规范的项目的目录结构,省下大量的时间。bash

让开发者能够无感知升级来适配新特性。

Maven 提供了一个简单的方式来让 Maven 客户端进行更新和升级,
使开发者们能够不作任何改动就能享受到 Maven 的新特性。
安装其余第三方插件也所以变得简单了许多。

Maven的命根子pom.xml文件

Maven 的核心是 POM 文件,
POM 文件是一个用来表示项目资源的 XML 格式的文件,
它包含了项目的源码,测试代码和项目依赖(使用到的外部 JAR)等资源的引用。

【重学maven】构建标准清晰地java工程_java_02

Maven 如何使用 POM 文件?

  • Maven 读取 pom.xml 文件。
  • 下载项目的依赖到本地仓库。
  • 执行构建的生命周期中,包括构建阶段和构建目标。
  • 执行插件。

POM 文件

当你执行 Maven 命令时,你须要告诉 Maven 根据哪一个 POM 文件来执行。
Maven 会对你所指定的 POM 文件中的资源来执行相应的命令。

构建生命周期、构建阶段、构建目标

在 Maven 中,构建阶段被分为 1.构建生命周期、2.构建阶段和3.构建目标。
一个构建生命周期由一系列构建阶段组成,而每个构建阶段都由一系列构建目标组成。
当你使用 Maven 执行一条命令时,这条命令应是一构建生命周期、构建阶段或构建目标。
若是是执行一个构建生命周期,则该生命周期中全部的构建阶段都会被执行。
若是是执行一个构建阶段,那么在此构建阶段被执行以前,它前面的全部阶段都会被依次执行。

依赖和仓库

Maven 最早执行的构建目标就是检查你项目的全部依赖,依赖就是项目中使用的外部 JAR 文件。
若是依赖在本地仓库中没有找到,那么 Maven 就会从中央从库中进行下载,并把下载下来的依赖放到本地仓库中(固然,你能够经过配置跳过该步骤)。
此外,你也能够指定 Maven 来使用哪一个中央仓库进行下载(Maven 默认使用的中央仓库服务器在国外,下载速度较慢,能够换成清华或阿里的中央仓库)。

构建插件

构建插件用来向一个构建阶段添加额外的构建目标。
若是你须要让 Maven 在执行构建阶段时执行一些额外的构建目标,
你能够在 POM 文件中添加一个插件来达到此目的,
Maven 为咱们提供了一些标准插件供咱们使用,你也可使用 Java 来编写你本身的插件。

提示:运行 Maven 须要 Java 环境的支持。

构建配置文件

构建配置文件可让你以多种方式来构建你的项目。
例如,你可能会想要在本地构建你的项目来进行开发和测试,
同时你又可能须要把项目部署到远程的生产环境。
这两种状况下的构建流程极可能是不一样的,
为了实现这个目标,
你只需向你的 POM 文件中添加不一样的构建配置文件,
并在使用 Maven 执行构建时选择使用与环境对应的配置文件进行构建便可。

pom.xml文件案例

<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.codehaus.mojo</groupId>
  <artifactId>my-project</artifactId>
  <version>1.0</version>
</project>

以上是一个 POM 文件的最小配置,
groupId:artifactId:version 这三个标签是必需的。
这三个标签结合起来能够实现一个地址和一个时间戳的做用,
它在 Maven 仓库中定义了一个惟一的坐标,
经过这个坐标,咱们能够准确的找到 Maven 仓库中的任何 JAR 包。

<project>:
	该标签是 POM 文件的根标签,它定义了 POM 文件的命名空间,即其子标签的引用来源。

<groupId>:
	表明组织和整个项目的惟一标志。应遵循 Java 包命名规范。如全部 Apache 基金会的 groupId 为 org.apache。

<artifactId>:
	表明该项目的全局惟一 Id,即项目的名称。

<version>:
	指定项目的版本。

<packaging>:
	定义项目以何种方式进行打包,可选值有:pom, jar, maven-plugin, ejb, war, war, ear, rar。

<parent>:
	POM 文件是能够继承的,该标签用于指定父 POM 的相关配置。

<properties>:
	用于声明一些常量,例如上述代码中的源码编码为 UTF-8,输出代码也为 UTF-8,Java 版本为 1.8。

<dependencies>:
	依赖的根元素,里面能够包含多个 dependency 元素,dependency 里具体为各个依赖 Jar 的 3 个坐标,即 groupId、artifactId 和 version。若是缺乏 version,Maven 会尝试从父 POM 中获取该依赖的 version。

<modules>:
	定义项目的子项目(子模块)。

<dependencyManagement>:
	用来管理项目子模块的依赖版本。

<properties>:
	Maven properties 是值占位符,在该标签下定义子标签,以后能够在 POM 的任何位置经过 ${} 的形式来引用其子标签的值。

Maven的目录结构

标准的 maven 项目的目录结构

basedir
|-- pom.xml
|-- src
|   |-- main
|   |   `-- java
|   |   `-- resources
|   |   `-- filters
|   `-- test
|   |   `-- java
|   |   `-- resources
|   |   `-- filters
|   `-- it
|   `-- assembly
|   `-- site
`-- LICENSE.txt
`-- NOTICE.txt
`-- README.txt

目录 描述
src/main/java 项目源代码目录
src/main/resources 项目资源文件目录
src/main/filters 项目资源过滤文件目录
src/main/webapp Web 应用源代码目录
src/test/java 项目测试代码目录
src/test/resources 项目测试代码资源目录
src/test/filters 项目测试代码资源过滤文件目录
src/it 集成测试代码目录(主要供插件使用)
src/assembly 组件描述符目录
src/site 站点文件目录
LICENSE.txt 项目的许可文件
NOTICE.txt 项目的注意事项文件
README.txt 项目的介绍文件

标准的maven项目目录结构不须要咱们本身去建立 ,经过 maven工具进行生成 就能够快速建立出 这种文件结构

Maven 的生命周期

构建生命周期

Maven 有 3 个内置的生命周期,以下。

  1. default
  2. clean
  3. site
    每一个构建生命周期关注整个软件项目构建的不一样方面。
    所以,每一个构建生命周期都被独立执行,不依赖其余生命周期。
    你可让 Maven 执行多个构建生命周期,但它们会按规定的顺序分别执行。
  • default 生命周期用于处理项目的编译和打包。
  • clean 生命周期用于将临时文件从输出文件夹中清除,包括编译后的源代码,文档以及以前打包的 JAR 文件。
  • site 生命周期用于生成项目的文档文件。实际上,site 能够为项目的文档生成整个网站。

构建阶段

每一个构建生命周期都被划分为一系列的构建阶段,每个构建阶段又被划分为一系列的构建目标。
所以,整个构建流程就是一系列的构建生命周期、构建阶段和构建目标。

你能够执行一整个构建生命周期如(default,clean 或 site),
或者执行一个构建阶段(如 default 生命周期的一个构建阶段 install),
又或者是执行一个构建目标(如 dependency:copy-dependencies)。

default 生命周期是最重要的,由于在这个生命周期中构建了项目的源代码。
因为咱们不能直接执行生命周期,所以咱们须要执行该生命周期中的一个构建阶段或是构建目标。
default 生命周期有许多的构建阶段和构建目标,这里只列出最多见的几个构建阶段。

构建阶段 描述
validate 检查项目配置是否正确,完成构建的全部必要信息是否可以获取到。同时确认依赖是否已经下载,若是没有,将会进行下载。
compile 编译项目源代码。
test 使用合适的单元测试框架对编译后的代码进行测试。测试不须要源代码已打包或部署。
pakcage 打包编译好的源代码为其可发行的格式,如一个 JAR 文件。
install 安装包到本地的仓库,方便其余项目在本地使用。
deploy 拷贝打包好的程序到远程仓库,供其余开发者和项目共享。

当你执行一个构建阶段时,该构建阶段以前的全部构建阶段都会被从上到下按顺序执行。例如上表,在执行 package 构建阶段时,Maven 首先按顺序执行 validate、compile 和 test 三个构建阶段。

构建目标

构建目标是 Maven 构建项目中的最小单位,一个目标能够和任意个构建阶段绑定。
若是一个目标没有和任何构建阶段绑定,你能够在执行 mvn 命令时传递构建目标名来执行它。
若是一个构建目标和一个或多个构建阶段绑定,那么每次这些构建阶段被执行时它都会被执行。

Maven 项目快速建立

使用「原型(Archetype)」快速 建立 Maven 项目

连接 :maven 安装 菜鸟教程

安装Maven 后在命令行输入

mvn archetype:generate

在控制台中输入 maven-archetype-quickstart 的序号 7(默认为咱们选择的就是 7),

而后控制台中会依次让咱们填写项目的 groupId、artifactId、version 以及 package,version 和 package 有默认值,不填写并回车就会使用默认值

也能够不使用交互直接配置好 命令

mvn archetype:generate 
	-DgroupId=com.hanxu51
	-DartifactId=maven-demo 
	-DarchetypeArtifactId=maven-archetype-quickstart 
	-DinteractiveMode=false

各个参数表明的含义

  • mvn:使用 Maven 来执行命令。全部 Maven 相关的命令都须要使用 mvn 来执行
  • archetype:generate:使用该 Maven 插件来基于原型建立 Maven 工程
  • DgroupId:定义项目的 groupId。此处为 com.hanxu51
  • DartifactId:定义项目的 artifactId。此处为 maven-demo
  • DarchetypeArtifactId:指定使用的原型。此处为 maven-archetype-quickstart
  • DinteractiveMode:是否开启交互模式。此处为 false,即关闭交互模式。关闭交互模式以后,在命令参数上没有指定的内容,如此处的 version 和 package,都将使用默认值

运行 maven 项目

# 进入 Maven 工程的根目录
cd maven-demo
# 使用 Maven 命令运行程序
mvn clean compile exec:java -Dexec.mainClass=com.hanxu51.App
  • compile:将程序源代码进行编译,并输出到 target 目录下。

  • clean:清理上次编译输出的文件。

  • exec:java:使用该插件来执行咱们程序中的主函数(main())。程序只有被编译为 .class 文件以后才能被执行,但不须要每次都对源代码进行编译,通常只在第一次编译程序和对代码进行修改以后才对源代码进行编译。

注:编译时最好使用 mvn clean compile 而不是 mvn compile,多一个 clean 构建阶段能够将以前编译输出的代码清理掉,避免形成这次编译的文件与上一次的文件混乱。

  • Dexec.mainClass:指定 exec:java 执行哪个 Java 文件的主函数。必须是 Java 文件的全限定类名(全限定类名 = 包名(com.shiyanlou) + “.” + 类名(App)。

对任何 Maven 项目执行命令时,Maven 默认会在执行命令的当前目录下寻找 pom.xml 配置文件来执行。若是没有找到配置文件,Maven 命令将没法正常执行。因此这里咱们须要进入到 Maven 工程的根目录(/home/project/maven-demo)。若是当前目录下找不到 pom.xml 文件,执行会报错,

若是不想每次进入到目录再执行 Maven 命令,可使用 -f 选项来为 Maven 命令指定使用的 pom.xml 文件位置。如 mvn exec:java -Dexec.mainClass=com.hanxu51.App -f /home/project/maven-demo/pom.xml

Maven pom快速配置

  • 【最全最多的中央仓库】mvnrepository https://mvnrepository.com/

中央仓库 搜索 mysql8.0 得到角标
好比加入 mysql8.0 的 依赖 能够直接在 pom.xml 加入这些角标

<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.18</version>
</dependency>

【重学maven】构建标准清晰地java工程_java_03

首先 mvn clean compile 这条命令做用是先清理程序以前编译的结果,而后将咱们 src 目录下的源代码进行编译。
「当你执行一个构建阶段时,该构建阶段以前的全部构建阶段都会被从上到下按顺序执行」,这里 Maven 执行的 compile 构建阶段以前的构建阶段有:

  • validate,该构建阶段将「检查项目配置是否正确,完成构建的全部必要信息是否可以获取到。
    同时确认依赖是否已经下载,若是没有,将会进行下载」。
    因此能够确定,当执行完 mvn compile 以后,项目所依赖的 mysql-connector-java 依赖已经被下载到本地仓库了。

  • mvn exec:java -Dexec.mainClass=com.hanxu51.App -Dexec.cleanupDaemonThreads=false 命令以前已经介绍过了,它是用来执行程序中的主函数的。这里咱们多设置了一个参数

  • Dexec.cleanupDaemonThreads=false,这是由于在使用 mysql-connector-java 进行数据库链接时,程序中不止有一个线程在运行,还有守护线程在运行,而主函数退出以后,exec 插件开始强制退出这些线程,若是线程没有及时退出,就会报错,这里咱们使用 -Dexec.cleanupDaemonThreads=false 来禁止强制退出,避免报错

注意,当咱们修改源码以后,在运行代码以前须要从新使用 mvn clean compile 命令编译源代码,否侧 exec:java 仍是会运行以前编译的代码。

Maven 自动化单元测试

Maven 作了许多的工做并高度整合 junit 框架来让开发人员可以专一于编写测试代码,而不用关心环境相关的问题。咱们只须要在 src/test 目录下建立测试类,编写测试方法,就可以快速对咱们的代码进行单元测试。

修改 pom.xml 引入角标

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

全局控制版本号

<properties>
    <junit.version>4.12</junit.version>
</properties>

<dependency>
  <groupId>junit</groupId>
  <artifactId>junit</artifactId>
  <version>${junit.version}</version>
  <scope>test</scope>
</dependency>

运行

mvn test -Dtest=com.hanxu51.AppTest#testGetConnection

Maven 打包

mvn clean package

跳过测试

 mvn clean package -Dmaven.test.skip=true