什么是Maven? 使用Apache Maven构建和依赖项管理
通过优锐课java架构学习中,学到了不少干货,整理分享给大家学习。
开始使用最流行的Java构建和依赖管理工具Maven
Apache Maven是Java开发的基石,也是Java使用最广泛的构建管理工具。 Maven简化的基于XML的配置模型使开发人员能够快速描述或掌握任何基于Java的项目的轮廓,这使得启动和共享新项目变得很容易。 Maven还支持测试驱动的开发,长期项目维护,其声明性配置和广泛的插件使其成为CI / CD的流行选择。 本文是对Apache Maven的快速介绍,包括Maven POM和目录结构,以及用于构建第一个Maven项目的命令。
请注意,撰写本文时最新的Maven版本是Maven 3.6.3。
Maven vs Ant and Gradle
尽管Maven是最受欢迎的工具,但它并不是Java生态系统中唯一的构建工具。 Ant是较早的基于XML的配置工具,它缺乏Maven的标准化,基于约定的实践和依赖管理,但是确实提供了Maven所没有的灵活性。 Gradle是一种较新的工具,可在Maven生态系统之上运行(使用Maven的存储库),但支持使用基于Groovy或Kotlin的DSL进行配置。 这三个都是独立的好构建工具,每个都可以集成到CI / CD流程中。 重要的是为你的需求选择合适的,并知道如何正确使用它。
Maven是如何工作的
像许多出色的工具一样,Maven可以将曾经过于复杂的内容(配置地狱)简化为易于消化的部分。 Maven包含三个组件:
- ·POM:描述Maven项目及其依赖项的文件。
- ·目录:用于描述POM中的Maven项目的标准化格式。
- ·存储库:存储和发现第三方软件的位置。
Maven POM:每个使用Maven的Java项目在其根目录中都有一个POM(项目对象模型)文件。 pom.xml描述了项目的依赖关系,并告诉你如何构建它。 (依赖关系是项目所需的第三方软件。一些常见的示例是JUnit和JDBC。有关所有可用工具和流行依赖关系的列表,请参见Maven中央存储库。)
Maven目录:Maven目录实现了所谓的基于配置的约定,这是对配置地狱的优雅解决方案。 Maven不需要开发人员为每个新项目定义布局和手动配置组件(makefile和Ant就是这种情况),而是建立了通用的项目结构并提供了描述其工作方式的标准文件格式。你只需插入需求,Maven就会调用依赖项并为你配置项目。
集中式存储库:最后,Maven使用集中式存储库来发现和发布作为依赖项的项目包。当你在项目中引用依赖项时,Maven会在集中式存储库中发现它,将其下载到本地存储库,然后将其安装到你的项目中。在大多数情况下,作为开发人员,所有这些都不可见。
访问Maven依赖项
默认情况下,Maven从Maven中央存储库解析依赖关系。一个常见的替代方案是JCenter,它具有更多可用软件包集。组织还发布和托管内部存储库,这些存储库可以是公共的或私有的。为了访问存储库,你可以在Maven POM中指定其URL,也可以指示Maven在其他存储库中查找。
安装Maven
Maven是一个Java项目,因此在安装它之前,需要在开发环境中安装JDK。 (有关下载和安装JDK的更多信息,请参见“什么是JDK?Java开发工具包简介”。)
设置Java开发环境后,只需几个步骤即可安装Maven:
1.下载最新的Maven版本(截至撰写本文时,Maven 3.6.3)。
2.将apache.maven.zip文件解压缩到方便的位置。
3.将该文件放在路径上。 例如,在Unix或Linux系统上:export PATH = $ PATH:/ home / maven /。
你现在应该可以访问mvn命令了。 键入mvn -v以确保已成功安装Maven。
Maven POM
每个Maven项目的根目录都是pom.xml文件。 尽管XML以其乏味而著称,但在此用例中,XML实际上效果很好。 Maven的POM易于阅读,并揭示了项目中正在发生的许多事情。 (如果你使用过JavaScript,则pom.xml的用途类似于Node NPM的package.json文件。)
清单1显示了一个非常简单的Maven pom.xml。
清单1.简单的Maven POM
<?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/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.javaworld</groupId> <artifactId>what-is-maven</artifactId> <version>1.0-SNAPSHOT</version> <name>Simple Maven Project</name> <packaging>jar</packaging> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> </dependencies></project>
了解Maven POM
一旦掌握了它,POM就不会神秘了。 首先,你可以浏览XML序言,该序言仅引用正式的POM模式。 但是请注意XML以modelVersion开头。 这告诉Maven使用什么版本的POM,在本例中为Maven POM 4.0.0。
接下来,你有groupId,artifactId和version。 这三个属性一起唯一地标识了存储库中每个Maven管理的资源。 文件顶部的这些属性描述了你的Maven项目。
现在,看看POM的依赖项部分,我们在其中描述项目的依赖项。 在这种情况下,到目前为止,我们仅引入了一种依赖关系,即JUnit。 请注意,JUnit也根据其groupId,artifactId和版本进行描述。
无论你是描述自己的项目还是项目依赖项,这些值始终告诉Maven在Maven存储库中找到项目的位置以及可以使用的版本。
将项目托管在Maven存储库中
请记住,POM定义了项目需要运行的所有内容,但同时也将项目描述为潜在的依赖项。 如果你要构建一个将成为依赖项的项目(例如,创建供其他项目使用的库),则需要通过以下四种方式之一使它可用:
- 1.使其在本地可用。
- 2.发布到私有管理的远程存储库。
- 3.发布到基于云的私有存储库。
- 4.发布到公共存储库(如Maven Central)。
在第一种情况下,根本不使用远程存储库。 相反,其他开发人员将使用mvn install命令将你的项目本地下载并安装到其Maven存储库中。
在第二种情况下,你使用托管的Maven存储库,使用私有控制的服务器发布和下载依赖项。 为此,你需要一个仓库管理器,例如Apache Archiva。
较新的替代方法是使用私有远程存储库,但依靠基于云的服务来管理它,例如Cloudsmith。 这带来了远程托管的依赖项的好处,而无需建立回购服务器。 当然,这项服务是收费的。
最后,一小部分项目将最终存储在Central Maven存储库或JCenter中,这些存储库旨在用于广泛使用的公共软件包。 如果要创建供其他人使用的开源依赖项,则需要这些集中存储库之一才能使你的工作对全世界可用。
- ·了解有关在Maven存储库中托管项目的更多信息,并获取可用存储库的列表。
- ·请参阅有关Maven发行插件的官方Maven文档,该文档用于准备和管理发布到Maven存储库的软件。
编译Maven包
如果你从清单1创建pom.xml并将其放在目录中,则可以对其执行Maven命令。 Maven有许多命令,并且可以通过插件使用更多命令,但是你只需要知道一些即可启动。
对于第一个命令,请尝试执行mvn软件包。 即使你还没有任何源代码,执行此命令也会告诉Maven下载JUnit依赖项。 你可以检查Maven的日志记录输出以查看依赖项是否已加载。
依赖范围
你可能已经注意到示例POM中的JUnit依赖项被标记为作用域测试。 范围是依赖管理中的一个重要概念,从本质上讲,你可以定义和限制在项目中如何调用和使用每个依赖。 测试范围确保运行测试时依赖项可用,但打包应用程序进行部署时不提供依赖项。
提供了另一个常见的作用域,它告诉框架依赖项是由运行时环境提供的。 部署到Servlet容器时,通常会在Servlet JARS中看到这种情况,因为该容器将提供那些JARS。 请参阅Apache Maven文档以获取Maven依赖范围的完整列表。
Maven的目录结构
完成命令后,请注意Maven已创建一个/ target目录。 这是项目输出的标准位置。 你下载的依赖项将与已编译的应用程序工件一起位于/ target目录中。
接下来,你要添加一个Java文件,该文件将放置在Maven src /目录中。 使用清单2的内容创建一个/src/main/java/com/javaworld/Hello.java文件。
清单2. Hello.java
com.javaworld public class Hello { public static void main(String[] args){ System.out.println("Hello, JavaWorld"); }}
/ src路径是项目源文件的标准位置。 大多数项目将其主文件放在/ src / main /中,而Java文件则放在/ java下的类路径中。 此外,如果要包括非代码资产,例如配置文件或映像,则可以使用/ src / main / resources。 此路径中的资产将添加到主类路径。 测试文件进入/ src / test / java。
作为回顾,以下是Maven项目结构的一些关键部分(由Maven标准目录结构定义):
Maven标准目录结构的关键部分
pom.xml |
项目描述符文件 |
/src/main/java |
源文件的位置 |
/src/main/resources |
非来源资产的位置 |
/src/test/java |
测试源文件的位置 |
/target |
构建输出的位置 |
管理你的Maven项目
mvn软件包命令指示Maven捆绑项目。 准备好将所有项目文件收集到一个位置时,发出此命令。 回想一下在该项目的POM文件中,我们将打包类型设置为jar,因此此命令告诉Maven将应用程序文件打包为JAR。
Maven提供了多种其他选项来控制JAR的管理方式(无论是胖JAR还是瘦JAR),并指定可执行的主类。 请参阅Maven文档以了解有关Maven中文件管理的更多信息。
捆绑项目后,你可能需要发布mvn安装。 此命令将项目推送到本地Maven存储库中。 将其放入本地存储库后,即可用于本地系统中的其他Maven项目。 这对于你和/或你的团队正在创建尚未发布到中央存储库的依赖项JAR的开发场景很有用。
其他Maven命令
准备好运行在/ src / java / test目录中定义的单元测试时,请输入mvn test。
准备编译项目的类文件时,输入mvn compile。 如果你正在运行热部署设置,则此命令将触发热部署类加载器。 (诸如Spring Boot的mvn spring-boot:runcommand之类的热部署工具将监视类文件中的更改,并且编译将导致你的源文件被编译,正在运行的应用程序将反映这些更改。)
开始一个新项目:Maven和Spring中的原型
Maven原型是用于基于各种预定义设置启动新项目的模板。每个原型都提供了预先打包的依赖关系,例如Java EE或Java Web应用程序项目。你还可以从现有项目中创建新的原型,然后使用它来基于这些预定义的布局快速创建新项目。请参阅Maven文档以了解有关Apache Maven原型的更多信息。
与Maven配合良好的Spring框架提供了附加的,复杂的功能,可用于暂存新项目。例如,Spring Initializr是一个工具,可让你非常快速地在新应用中定义所需的元素。 Initializr本质上不是Maven原型,但其目的相同,即基于前期规范生成项目布局。在Initializr中,你可以键入mvn archetype:generate并浏览选项以找到适合你所构建内容的原型。
添加依赖
上一个1 2
在开发或维护软件时,你将需要不时向现有项目中添加新功能。 幸运的是,Maven使添加新功能非常容易。 假设你正在处理清单1中定义的项目,并意识到需要使用Apache Commons Languagelibrary中的一些实用程序。 你可以在JUNit之后轻松地将该依赖项插入到原始POM文件中,如清单3所示。
<dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>3.0</version></dependency>
查找依赖关系也很容易。 为此,你只需在网络浏览器中键入“ maven stringutils”,它就会显示出来。 或者你可以直接搜索Central Maven存储库。 当你在项目主页或其他资源上阅读依赖时,你可能还会找到所需依赖的链接。 只需剪切并粘贴URL,并确保记下正确的版本号,就可以了。
结论
Maven之所以如此常用是因为它运行良好并且足够成熟,可以处理你向它扔的任何东西。 了解Maven并将其用作项目的基础可释放Java生态系统中为你提供的大量功能。 要想尽一切可能,请考虑签出这些项目中的任何一个,这些项目都可以通过Maven核心插件进行访问。
Maven核心插件
maven-sure fire-插件 |
在专用类加载器中运行单元测试。 |
春季启动maven插件 |
允许通过弹簧启动运行弹簧应用程序:运行。 |
maven-部署-插件 |
用于将包发布到远程存储库中。 |
maven-汇编-插件 |
允许构建fat或uber JARs,也就是说,JAR文件包含一个文件中的所有相关性和资产,能够按原样运行。 |
maven-shade-插件 |
允许构建一个胖JAR,允许删除未使用的文件,或者重命名冲突的文件。 |
> 喜欢这篇文章的可以点个赞,欢迎大家留言评论,记得关注我,每天持续更新技术干货、职场趣事、海量面试资料等等
> 如果你对java技术很感兴趣也可以交流学习,共同学习进步。
> 不要再用"没有时间“来掩饰自己思想上的懒惰!趁年轻,使劲拼,给未来的自己一个交代
文章写道这里,欢迎完善交流。最后奉上近期整理出来的一套完整的java架构思维导图,分享给大家对照知识点参考学习。有更多JVM、Mysql、Tomcat、Spring Boot、Spring Cloud、Zookeeper、Kafka、RabbitMQ、RockerMQ、Redis、ELK、Git等Java干货
什么是Maven? 使用Apache Maven构建和依赖项管理的更多相关文章
- Maven:org.apache.maven.archiver.MavenArchiver.getManifest错误
Eclipse导入maven多模块工程时报错org.apache.maven.archiver.MavenArchiver.getManifestorg.apache.maven.archiver.M ...
- Apache Maven 打包可执行jar
在本文的 参考资料 部分,您将发现大量介绍 Maven 的入门教程.本文的 5 个技巧目的是帮助您解决即将出现的一些问题:使用 Maven 管理您的应用程序的生命周期时,将会出现的编程场景. 1. 可 ...
- No implementation for org.apache.maven.model.path.PathTranslator was bound.
2019-12-17 10:19:19,884 [ 688476] INFO - #org.jetbrains.idea.maven - org.apache.maven.model.resoluti ...
- Apache Maven的入门使用之项目的基本构建(1)
前言 最近在研究java框架struts2的相关漏洞,然后就去看了官方给出的文档.在看文档的过程中发现使用到了Apache Maven这个项目管理工具,我在网上搜索了一下,大多数文章都写得不是很系统, ...
- maven构建报错org.apache.maven.lifecycle.LifecycleExecutionException
2017年06月04日 15:03:10 阅读数:7991 maven构建报错 org.apache.maven.lifecycle.LifecycleExecutionException: Fail ...
- 解决maven构建工程错误:Failure to transfer org.apache.maven.plugins:maven-jar-plugin:pom:2.4 from错误
问题描述: mvn archetype:generate -DgroupId=com.mycompany.app -DartifactId=myapp -DarchetypeArtifactId=ma ...
- Apache Maven(二):构建生命周期
Maven 约定的目录结构 我要遵循Maven已经约定好的目录结构,才能让maven在自动构建过程中找到对应的资源进行构建处理.以下是maven约定的目录结构: 项目名称 |-- pom.xml :M ...
- Liferay7 BPM门户开发之38: OSGi模块化Bndtools、Maven、Gradle开发构建入门
前言 OSGi是目前动态模块系统的事实上的工业标准,它适用于任何需要模块化.面向服务.面向组件的应用程序.Eclipse如此庞大和复杂的插件体系,就是基于OSGi.Liferay也是基于OSGi.OS ...
- [Maven]Apache Maven 入门篇
作者:George Ma 上 写这个 maven 的入门篇是因为之前在一个开发者会的动手实验中发现挺多人对于 maven 不是那么了解,所以就有了这个想法.这个入门篇分上下两篇.本文着重动手,用 ma ...
随机推荐
- git免密拉取代码
里介绍通过ssh公钥的方式免密拉取代码 以linux服务器为例,windows方式是一样的 1.用命令生成ssh key ssh-keygen -t rsa -C "xx@xxxcom&qu ...
- dyt说反话(注意字符串输入)
题目内容: dyt喜欢对lrh说的话说反话,现给出lrh说的k句话,输出dyt所说的反话. 输入格式 第一行是样例个数k(k<10) 接下来k行,每行包含lrh说的一句话(每句话长度不超过50, ...
- can总线中什么是远程帧
所谓“远程帧”是一个传统翻译上的误区.Remote Frame实际上它的意义是“遥控帧”,发起方发起特定ID的远程帧,并且只发送ID部分,那么与其ID相符的终端设备就有义务在后半段的数据部分接管总线控 ...
- MODBUS TCP/IP协议规范详细介绍
1.该规范的发展概况 原始版本1997年9月3日作为公共评论的草案. 再版1999年3月29日,即修订版1.0. ...
- Java 读取网络资源文件 获取文件大小 MD5校验值
Java 读取网络资源文件 获取文件大小 MD5校验值 封装一个文件操作工具类: package c; import java.io.*; import java.net.HttpURLConnect ...
- 排查 k8s 集群 master 节点无法正常工作的问题
搭建的是 k8s 高可用集群,用了 3 台 master 节点,2 台 master 节点宕机后,仅剩的 1 台无法正常工作. 运行 kubectl get nodes 命令出现下面的错误 The c ...
- 「CSP-S模拟赛」2019第三场
目录 T1 「POI2007」山峰和山谷 Ridges and Valleys 题目 考场思路(几近正解) 正解 T2 「JOI 2013 Final」 现代豪宅 题目 考场思路(正解) T3 「SC ...
- JetBrains PyCharm 2018.2.1 x64永久激活码
812LFWMRSH-eyJsaWNlbnNlSWQiOiI4MTJMRldNUlNIIiwibGljZW5zZWVOYW1lIjoi5q2j54mIIOaOiOadgyIsImFzc2lnbmVlT ...
- JAXB "有两个名为 "**" 的属性,类的两个属性具有相同名称 "**""解决方案
这里说的名称冲突指的是: JavaBean 属性名称与字段名称之间的名称冲突.在pojo类中的setter和getter方法会导致运行报错:Exception in thread "main ...
- FromBase64String 输入的不是有效的 Base-64 字符串,因为它包含非 Base-64 字符、两个以上的填充字符,或者填充字符间包含非法字符
js前台: <input id="upload_img_input" v-on:change="onFileChange" type="file ...