写点什么

【深入浅出 Maven 开发实战】「入门教程系列」带你零基础学习和开发使用 Maven 开发工具实战指南(实战技术总结)

作者:洛神灬殇
  • 2023-05-25
    江苏
  • 本文字数:8674 字

    阅读完需:约 28 分钟

【深入浅出Maven开发实战】「入门教程系列」带你零基础学习和开发使用Maven开发工具实战指南(实战技术总结)

Maven 介绍

由于 Java 的生态非常丰富,无论你想实现什么功能,都能找到对应的工具类,这些工具类都是以 jar 包的形式出现的,例如 Spring,SpringMVC、MyBatis、数据库驱动,等等,都是以 jar 包的形式出现的,jar 包之间会有关联,在使用一个依赖之前,还需要确定这个依赖所依赖的其他依赖,所以,当项目比较大的时候,依赖管理会变得非常麻烦臃肿,这是 Maven 解决的第一个问题。

为什么使用 Maven

Maven 还可以处理多模块项目。简单的项目,单模块分包处理即可,如果项目比较复杂,要做成多模块项目,例如一个电商项目有订单模块、会员模块、商品模块、支付模块,一般来说,多模块项目,每一个模块无法独立运行,要多个模块合在一起,项目才可以运行,这个时候,借助 Mavn 工具,可以实现项目的一键打包。


Maven 之前,我们更多的是使用 Ant 的项目构建工具,Ant 有一个特点,每次都得写,每次都写的差不多,配置也臃肿。所以,后来搞出来 Maven。Maven 就是最先进的版本构建工具吗?不是的,只不过,目前在 Java 领域 Maven 使用比较多。除了 Maven,还有 Gradle。

Maven 是什么

Maven 是一个项目管理工具,它包含了一个项目对象模型(Project Object Model),反映在配置中,就是一个 pom.xml 文件。是一组标准集合,一个项目的生命周期、一个依赖管理系统,另外还包括定义在项目生命周期阶段的插件(plugin) 以及目标(goal) 。当我们使用 Maven aven 的使用通过一个自定义的项目对象模型,pom.xml 来详细描述我们自己的项目。

两大核心功能

  • 依赖管理:对 jar 的统一管理(Maven 提供了一个 Maven 的中央仓库,https://mvnrepository..com/,当我们在项日中添加完依赖之后,Maven 会自动去中央仓库下载相关的依赖,并且解决依赖的依赖问题)

  • 项目构建:对项目进行编译、测试、打包、部署、上传到私服等

Maven 安装

Maven 是 Java 项目,因此必须先安装 JDK。


下载 Maven

下载地址:http://maven.apache.org/download.cgi


解压并且配置

打开并且解压 maven 的压缩包。 如下图所示。 我的版本是 3.9.2。



配置,只需要配置环境变量即可:


首先配置 MAVEN HOME, 因为我的是 Mac 系统,所以我的一个操作仅限于 Mac 的用户。在 Mac 上配置 Maven 的环境变量,需要按照以下步骤进行操作:

打开终端

输入以下命令来编辑~/.bash_profile 文件:


nano ~/.bash_profile
复制代码


在打开的文件中添加以下内容:


export M2_HOME=/usr/local/apache-maven-3.9.2export PATH=$PATH:$M2_HOME/bin
复制代码


这里假设您安装的 Maven 版本是 3.9.2。如果您使用的是其他版本,请相应地更改路径。按下 Control + X 键然后输入 Y 保存修改,最后按下回车键退出文件。


输入以下命令以重新加载.bash_profile 文件


source ~/.bash_profile
复制代码


检查 Maven 是否已正确安装和配置:


mvn -version
复制代码


如果成功安装和配置,将显示 Maven 版本信息。



如果使用了 Intelli IDEA,可以不用去额外下载 Maven,直接使用 IDEA 中自带的 Maven 插件即可。IntelliJ IDEA 中自带的 Maven 插件在\xxxx\plugins\maven\lib\maven3。

Maven 配置

实际上,没有特殊需求的话,安装好之后直接就可以用了。一般来说,还是需要稍微配置一下,比如中央仓库的问题。默认使用 Maven 自己的中央仓库,使用起来网速比较慢,这个时候,可以通过修改配置文件,将仓库改成国内的镜像仓库,国内仓库使用较多的是阿里巴巴的仓库。

阿里巴巴云效仓库

  • 阿里巴巴云效仓库:https://developer.aliyun.com/mvn/guide


阿里云 Maven 中央仓库为 阿里云云效 提供的公共代理仓库,帮助研发人员提高研发生产效率,使用阿里云 Maven 中央仓库作为下载源,速度更快更稳定。


仓库类型


现在存在 3 个仓库,那么 jar 包如何查找呢?


本地仓库配置

本地仓库默认位置在当前用户名.m2\repository,这个位置可以自定义,但是不建议大家自定义这个地址,有几个原因:


  1. 虽然所有的本地的 jar 都放在这个仓库中,但是并不会占用很大的空间。

  2. 默认的位置比较隐蔽,不容易碰到


技术上来说,当然是可以自定义本地仓库位置的,在 conf/settings.xml 中自定义本地仓库位置:


远程镜像配置

由于默认的中央仓库下载较慢,因此,也可以将远程仓库地址改为阿里巴巴或者其他资源的镜像的仓库地址:


    <mirror>      <!--This sends everything else to /public -->      <id>central-mirror</id>      <mirrorOf>central</mirrorOf>       <url>https://maven.aliyun.com/repository/central</url>    </mirror>    <mirror>      <!--This sends everything else to /public -->      <id>jcenter-mirror</id>      <mirrorOf>jcenter</mirrorOf>       <url>https://maven.aliyun.com/repository/public</url>    </mirror>    <mirror>      <!--This sends everything else to /public -->      <id>public-mirror</id>      <mirrorOf>public</mirrorOf>       <url>https://maven.aliyun.com/repository/public</url>    </mirror>    <mirror>      <!--This sends everything else to /public -->      <id>google-mirror</id>      <mirrorOf>public</mirrorOf>       <url>https://maven.aliyun.com/repository/google</url>    </mirror>    <mirror>      <!--This sends everything else to /public -->      <id>public-mirror</id>      <mirrorOf>public</mirrorOf>       <url>https://maven.aliyun.com/repository/public</url>    </mirror>    <mirror>      <!--This sends everything else to /public -->      <id>gradle-plugin-mirror</id>      <mirrorOf>gradle-plugin</mirrorOf>       <url>https://maven.aliyun.com/repository/gradle-plugin</url>    </mirror>                <mirror>      <!--This sends everything else to /public -->      <id>spring-mirror</id>      <mirrorOf>spring</mirrorOf>       <url>https://maven.aliyun.com/repository/spring</url>    </mirror>                    <mirror>      <!--This sends everything else to /public -->      <id>spring-plugin-mirror</id>      <mirrorOf>spring-plugin</mirrorOf>       <url>https://maven.aliyun.com/repository/spring-plugin</url>    </mirror>                    <mirror>      <!--This sends everything else to /public -->      <id>grails-core-mirror</id>      <mirrorOf>grails-core</mirrorOf>       <url>https://maven.aliyun.com/repository/grails-core</url>    </mirror>                    <mirror>      <!--This sends everything else to /public -->      <id>apache snapshots-mirror</id>      <mirrorOf>apache snapshots</mirrorOf>       <url>https://maven.aliyun.com/repository/apache-snapshots</url>    </mirror>     <mirror>        <id>centit-mirror</id>        <mirrorOf>centit</mirrorOf>        <url>http://develop.centit.com/nexus/content/repositories/centit-releases</url>    </mirror>                 </mirrors>
复制代码


加了这一段配置之后,以后就不会去 Maven 中央仓库上去下载依赖了,而是去阿里巴巴以及其他的仓库下载,这样可以有效提高下载速度。

Maven 指令

虽然还有很多其他的配置,那些东西如果现在跟大家说,大家会蒙圈的, 如果有兴趣的小伙伴可以去看作者的其他的相关 Maven 的文章,有对应的介绍,相信到这里,大家应该大概知道了 Maven 的一个配置的简介和基本的使用。


接下来我们会介绍 maven 的一些基础指令。Maven 中有一些常见的命令,如果使用 Eclipse 需要手动敲命令,如果使用 IDEA 的话,可以不用命令,直接点点点就可以了。


我们主要会针对于以下指令进行分析介绍:



这里需要注意的是,这些命令都不是独立运行的,它有一个顺序。

举个简单例子

我想将 jar 上传到私服,那么就要构建 jar,就需要执行 package 命令,要打包,当然也需要测试,那就要走 mvn test 命令,要测试就要先编译,因此,最终所有的命令都会执行一遍。不过,开发者也可以手动配置不执行某一个命令,这就是跳过。一般来是,除了测试,其他步骤都不建议跳过。


当然,如果开发者使用了 IDEA,这些命令不用手动敲,点一下就行:


通过命令进行构建项目

可以直接通过命令来构建一个 Maven 项目,不过在实际开发中,一般使用 Eclipse 或者 IDEA 就可以直接创建 Maven 项目了。

创建命令

mvn archetype:generate -DgroupId=org.xxx -DartifactId=xxx -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
复制代码


看到如下提示,表示项目创建成功:

打包命令

接下来,我们通过 mvn package 命令可以将刚刚创建的项目打成一个 jar 包。在打包之前,需要配置 DK 的版本至少为 7 以上,因此,我们还需要手动修改一下 pom.xml 文件,即添加如下配置:


  <properties>    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>    <java.version>11</java.version>    <!-- servlet版本 -->    <servlet.api.version>4.0.1</servlet.api.version>    <!-- jackson版本 -->    <jackson.version>2.13.0</jackson.version>    <!-- okhttp3版本 -->    <okhttp.version>3.12.1</okhttp.version>    <!-- google thumbnailator -->    <google-thumbnailator.version>0.4.14</google-thumbnailator.version>    <slf4j-api.version>1.7.32</slf4j-api.version>    <transmittable-thread-local.version>2.12.2</transmittable-thread-local.version>    <maven-javadoc-plugin.version>3.3.1</maven-javadoc-plugin.version>    <maven-gpg-plugin.version>3.0.1</maven-gpg-plugin.version>    <encoding>UTF-8</encoding>  </properties>
复制代码


添加完成后,执行打包命令,注意执行所有命令时,命令行要定位到 pom.xml 文件所在的目录,看到如下提示,表示项目打包成功。


/Library/Java/JavaVirtualMachines/jdk1.8.0_211.jdk/Contents/Home/bin/java -Dmaven.multiModuleProjectDirectory=/Users/alex/Documents/code/mine/develop-admin -Djansi.passthrough=true -Dmaven.home=/Applications/IntelliJ IDEA.app/Contents/plugins/maven/lib/maven3 -Dclassworlds.conf=/Applications/IntelliJ IDEA.app/Contents/plugins/maven/lib/maven3/bin/m2.conf -Dmaven.ext.class.path=/Applications/IntelliJ IDEA.app/Contents/plugins/maven/lib/maven-event-listener.jar -javaagent:/Applications/IntelliJ IDEA.app/Contents/lib/idea_rt.jar=62462:/Applications/IntelliJ IDEA.app/Contents/bin -Dfile.encoding=UTF-8 -classpath /Applications/IntelliJ IDEA.app/Contents/plugins/maven/lib/maven3/boot/plexus-classworlds.license:/Applications/IntelliJ IDEA.app/Contents/plugins/maven/lib/maven3/boot/plexus-classworlds-2.6.0.jar org.codehaus.classworlds.Launcher -Didea.version=2023.1 -s /Users/alex/Documents/config/maven/settings.xml -DskipTests=true package[INFO] Scanning for projects...[INFO] [INFO] ---------------------< com.hyts:develop-archetype >---------------------[INFO] Building develop-archetype 2.0.0[INFO] --------------------------------[ jar ]---------------------------------[WARNING] The POM for com.alibaba:druid:jar:1.1.21 is invalid, transitive dependencies (if any) will not be available, enable debug logging for more details[INFO] [INFO] --- maven-resources-plugin:3.1.0:resources (default-resources) @ develop-archetype ---[INFO] Using 'UTF-8' encoding to copy filtered resources.[INFO] Copying 20 resources[INFO] Copying 621 resources[INFO] [INFO] --- maven-compiler-plugin:3.8.0:compile (default-compile) @ develop-archetype ---[INFO] Changes detected - recompiling the module![INFO] Compiling 213 source files to /Users/alex/Documents/code/mine/develop-admin/target/classes
复制代码

将项目安装到本地仓库

如果需要将项目安装到本地仓库,可以直接执行 mvn instali 命令,注意,mvn install 命令会包含上面的 mvn package 过程。


[INFO] /Users/alex/Documents/code/mine/develop-admin/src/main/java/com/hyts/common/secure/domain/SecureUserTokenServiceImpl.java: 有关详细信息, 请使用 -Xlint:unchecked 重新编译。[INFO] [INFO] --- maven-resources-plugin:3.1.0:testResources (default-testResources) @ develop-archetype ---[INFO] Using 'UTF-8' encoding to copy filtered resources.[INFO] skip non existing resourceDirectory /Users/alex/Documents/code/mine/develop-admin/src/test/resources[INFO] [INFO] --- maven-compiler-plugin:3.8.0:testCompile (default-testCompile) @ develop-archetype ---[INFO] Nothing to compile - all classes are up to date[INFO] [INFO] --- maven-surefire-plugin:2.22.2:test (default-test) @ develop-archetype ---[INFO] Tests are skipped.[INFO] [INFO] --- maven-jar-plugin:3.2.2:jar (default-jar) @ develop-archetype ---[INFO] Building jar: /Users/alex/Documents/code/mine/develop-admin/target/develop-archetype-2.0.0.jar[INFO] [INFO] --- spring-boot-maven-plugin:2.7.0:repackage (repackage) @ develop-archetype ---[INFO] Replacing main artifact with repackaged archive[INFO] [INFO] --- spring-boot-maven-plugin:2.7.0:repackage (default) @ develop-archetype ---[INFO] Replacing main artifact with repackaged archive[INFO] ------------------------------------------------------------------------[INFO] BUILD SUCCESS[INFO] ------------------------------------------------------------------------[INFO] Total time:  16.794 s[INFO] Finished at: 2023-05-25T14:30:43+08:00[INFO] ------------------------------------------------------------------------
复制代码


安装到本地仓库之后,这个时候,点开自己的本地仓库,就可以看到相关的 jar 了。

IDEA 使用 Maven

不同于 Eclipse,IDEA 安装完成后,就可以直接使用 Maven 了。

Maven 相关配置

IDEA 中,Maven 的配置在 File->Settings->Build,Execution,Deployment->Build Tools->Maven:


JavaSE 工程创建

首先在创建一个工程时,选择 Maven 工程:



如果勾选上 Create from archetype,则表示可以根据一个项目骨架(项目模板)来创建一个新的工程,不过,如果只是创建 JavaSE 项目,则不用选择项目骨架。直接 Next 即可。然后填入项目的坐标,即 groupld 和 artifactld。

Maven 依赖管理

Maven 项目,如果需要使用第三方的控件,都是通过依赖管理来完成的。这里用到的一个东西就是 pom.xml 文件,概念叫做项目对象模型(POM,Project Object Model),我们在 pom.xml 中定义了 Maven 项目的形式,所以,pom.xml 相当于是 Maven 项目的一个地图。就类似于 web.xml 文件用来描述三大 web 组件一样。

Maven 的坐标

 <dependency>     <groupId>com.alibaba</groupId>     <artifactId>easyexcel</artifactId>     <version>${easyexcel.version}</version></dependency>
复制代码

dependencies

在 dependencies 标签中,添加项目需要的 jar 所对应的 maven 坐标。

dependency

一个 dependency 标签表示一个坐标

groupld

团体、公司、组织机构等等的唯一标识。团体标识的约定是它以创建这个项目的组织名称的逆向域名(例如 org.xxx)开头。一个 Maven 坐标必须要包含 groupld。一些典型的 groupld 如 apache 的 groupld 是 org,apache。

artifactld

artifactld 相当于在一个组织中项目的唯一标识符。

version

一个项目的版本。一个项目的话,可能会有多个版本。如果是正在开发的项目,我们可以给版本号加上一个 SNAPSHOT,表示这是一个快照版(新建项目的默认版本号就是快照版)

scope

表示依赖范围。



我们添加了很多依濑,但是不同依赖的使用范围是不一样的。最典型的有两个,一个是数据库驱动,另一个是单元测试。


数据库驱动,在使用的过程中,我们自己写代码,写的是 DBC 代码,只有在项目运行时,才需要执行 MySQL 驱动中的代码。所以,MySQL 驱动这个依赖在添加到项目中之后,可以设置它的 scope 为 runtime,编译的时候不生效。


单元测试,只在测试的时候生效,所以可以设置它的 scope 为 test,这样,当项目打包发布时,单元测试的依赖就不会跟着发布。

依赖冲突

依赖冲突产生的原因



在图中, a.jar 依赖 b.jar, 同时 a.jar 依赖 d.jar, 这个时候, a 和 b、d 的关系是直接依赖的关系,a 和 c 的关系是间接依赖的关系。

冲突解决

  1. 先定义先使用

  2. 路径最近原则(直接声明使用)以 spring-context 为例, 下图中红色表示失效的依赖(优先级低的依赖,即路径近的依赖优先使用):


上面这两条是默认行为。我们也可以手动控制。手动控制主要是通过排除依赖来实现,如下:


  <dependency>            <groupId>com.github.pagehelper</groupId>            <artifactId>pagehelper-spring-boot-starter</artifactId>            <version>${pagehelper.version}</version>            <exclusions>                <exclusion>                    <artifactId>mybatis</artifactId>                    <groupId>org.mybatis</groupId>                </exclusion>            </exclusions></dependency>
复制代码


这个表示从 spring-context 中排除 spring-core 依赖。

Maven 私服

Maven 仓库管理也叫 Maven 私服或者代理仓库。使用 Maven 私服有两个目的:


  1. 私服是一个介于开发者和远程仓库之间的代理。

  2. 私服可以用来部署公司自己的 jar。

Nexus 介绍

Nexus 是一个强大的 Maven 仓库管理工具, 使用 Nexus 可以方便的管理内部仓库同时简化外部仓库的访问。官网是:https://www.sonatype.com/

Nexus 安装

下载

下载地址:https://www.sonatype.com/download-oss-sonatype

解压

将下载下来的压缩包,拷贝到一个没有中文的路径下,然后解压。

启动

解压之后, 打开 cmd 窗口(以管理员身份打开 cmd 窗口) , 然后定位了 nexus 解压目录,执行 nexus.exe/run 命令启动服务。



这个启动稍微有点慢,大概有 1 两分钟的样子,启动成功后,浏览器输入 http://lcoalhost:8081 打开管理页面。打开管理页面后,点击右上角上的登录按钮进行登录,默认的用户名/密码是 admin/admin123。当然,用户也可以点击设置按钮,手动配置其他用户。



点击 Repositories 可以查看仓库详细信息


仓库类型

  • proxy:表示这个仓库是一个远程仓库的代理,最典型的就是代理 Maven 中央仓库

  • hosted:宿主仓库,公司自己开发的一些 jar 存放在宿主仓库中,以及一些在 Maven 中央仓库上没有的 jar

  • group:仓库组,包含代理仓库和宿主仓库

  • virtual:虚拟仓库

上传 Jar

上传 jar,配置两个地方:Maven 的 conf/settings.xml 文件配置:


<!-- servers   | This is a list of authentication profiles, keyed by the server-id used within the system.   | Authentication profiles can be used whenever maven must make a connection to a remote server.   |-->  <servers>    <!-- server     | Specifies the authentication information to use when connecting to a particular server, identified by     | a unique name within the system (referred to by the 'id' attribute below).     |      | NOTE: You should either specify username/password OR privateKey/passphrase, since these pairings are      |       used together.     |    <server>      <id>deploymentRepo</id>      <username>repouser</username>      <password>repopwd</password>    </server>    -->        <!-- Another sample, using keys to authenticate.    <server>      <id>siteServer</id>      <privateKey>/path/to/private/key</privateKey>      <passphrase>optional; leave empty if not used.</passphrase>    </server>    -->    <server>        <id>releases</id>        <username>ali</username>        <password>ali</password>      </server>      <server>        <id>Snapshots</id>        <username>ali</username>        <password>ali</password>      </server>  </servers>
复制代码


在要上传 jar 的项目的 pom.xml 文件中,配置上传路径:


<distributionManagement>  <repository>    <id>releases</id>    <url>http://localhost:8081/repository/maven-releases/</url>  </repository>  <snapshotRepository>    <id>snapshots</id>    <url>http://localhost:8081/repository/maven-snapshots/</ur1>  </snapshotRepository></distributionManagement>
复制代码


配置完成后,点击 deploy 按钮,或者执行 mvn deploy 命令就可以将 jar 上传到私服上。

下载 Jar

直接在项目中添加依赖,添加完成后,额外增加私服地址即可:


<repositories>  <repository>    <id>local-repository</id>    <url>http://localhost:8081/repository/maven-public/</url>    <releases>      <enabled>true</enabled>    </releases>    <snapshots>      <enabled>true</enabled>    </snapshots>  </repository></repositories>
复制代码


Maven 是一款用于 Java 项目构建、依赖管理和项目信息管理的工具。在 Java 开发中,Maven 已成为必不可少的工具之一。

发布于: 2023-05-25阅读数: 4
用户头像

洛神灬殇

关注

🏆 InfoQ写作平台-签约作者 🏆 2020-03-25 加入

👑 后端技术架构师,前优酷资深工程师 📕 个人著作《深入浅出Java虚拟机—JVM原理与实战》 💻 10年开发经验,参与过多个大型互联网项目,定期分享技术干货和项目经验

评论

发布
暂无评论
【深入浅出Maven开发实战】「入门教程系列」带你零基础学习和开发使用Maven开发工具实战指南(实战技术总结)_Java_洛神灬殇_InfoQ写作社区