学Maven,资料杂乱?一篇就够了

465 阅读15分钟

「本文已参与好文召集令活动,点击查看:后端、大前端双赛道投稿,2万元奖池等你挑战!

一、基本概念

1. 什么是maven

Maven(翻译为专家,内行)是跨平台的项目管理工具,主要服务于基于java平台的 项目构建依赖管理 以及 项目信息管理

2. 项目构建

项目的构建过程

清理项目 clean
编译项目 compile
测试项目 test
生成测试报告
打包项目 pacakage
部署项目 deploy

3. 依赖管理

自动管理项目所需的Jar包。

4.使用Maven的好处

  a) 平时开发项目时,一般都是一个项目一个工程。我们划分模块时,都是使pacakage来进行划分。但是当项目很大时,就有很多子模块,即使是使用pacakage来划分, 也让人眼花缭乱。
     优点:项目非常大时,可借助Maven将一个项目拆分为多个工程,最好是一个模块对应一个工程,利于分工写作。而且模块间还可以发送消息。
  b) 同一个项目的 Jar 包 复制 和 粘贴 到 WEB-INFO/lib 下
     问题:同样的 Jar 包重复出现在不同的工程中,一方面浪费空间,同时让工程臃肿
     优点:借助 Maven,可将 Jar 包仅仅保存在 “仓库中” 中,有需要该文件时,就引用该文件接口,不需要复制文件来占用空间
  c) 如果 Jar 包都到官网去下载,会浪费很多时间,而且可能不全。
     优点三:借助 Maven 来以规范的方式下载 Jar 包,因为所有知名框架或第三方工具的 Jar 包已经按照统一的规范放到了 Maven 的中央仓库中。
  d) 一个 Jar 包依赖的其他 Jar 包可能没导入到项目中而导致项目启动失败。
     优点四:Maven会自动将项目使用的Jar包导入,不仅导入,还会将Jar的依赖Jar包自动导入进来。

二、下载与安装

1. 下载

maven.apache.org/download.cg…

Maven工具目录: image.png

bin:含有mvn运行的脚本
boot:含有名为 plexus-classwords类加载器框架的Jar包
conf:含有settings.xml配置文件
lib:含有Maven运行时所需要的类库
LICENSE.txt, NOTICE.txt, README.txt针对Maven版本,第三方软件等介绍

2. 安装

  • 首先确保电脑已经安装了JDK(要求1.7以上),配置好JDK环境变量
  • 对 apache-maven-3.8.1-bin 文件进行解压缩(解压目录最好不要有中文和空格)
  • 设置系统环境变量:MAVEN_HOME
  • 设置系统环境变量Path:%MAVEN_HOME%\bin, 要注意与其他变量用 ;号隔开

贴两篇关于JAVA环境变量的理解文章:blog.csdn.net/w8y56f/arti… www.panziye.com/java/2497.h…

三、Maven仓库配置

1. Maven寻找Jar的历程

image.png

2. 设置本地仓库

默认情况下Maven将本地仓库的位置防止在:在 ${user.home}/.m2/repository”中,${user.home}表示当前登录系统的用户目录(如"C:\Users\gacl")

Jar包存放此位置不太友好,因此我们希望能够自定义下载Jar包的存放位置

  • 创建仓库目录 image.png
  • 修改settings.xml文件

配置文件详解:www.cnblogs.com/dalianpai/p…
blog.csdn.net/catoop/arti…

image.png

把jar包下载到本地的好处就是,当编译时,第一次执行"mvn compile"和"mvn clean"这两个命令时,Maven会去网络中的maven仓库下载需要的jar包,而第二次执行这两个命令时,由于所需的jar包已经在本地的仓库中存储,所以就可以直接拿来用了,这样就省去了去网络仓库下载jar包的时间。

3. 仓库分类

  • 本地仓库: 本地电脑
  • 私服: 局域网,一般是公司内部的服务器上
  • 中央仓库: 互联网上, Maven的团队维护的,为前世界所有Maven工程服务
  • 中央仓库的镜像: 为了分担中央仓库的负担, 提升用户的访问速递

4. 设置镜像

刚刚开始使用maven的时候, 不可避免在中央仓库下载jar包,但是网站在国外,所以下载速 度很慢, 解决方案, 配置国内的镜像:

<mirror>
    <id>nexus-aliyun</id>
    <mirrorOf>central</mirrorOf>
    <name>Nexus aliyun</name>
    <url>http://maven.aliyun.com/nexus/content/groups/public</url>
</mirror>

5. 仓库中保存的内容

  • Maven自身需要的jar包
  • 第三方的框架或工具的jar包
  • 我们自己开发的Maven工程打包安装上去的jar包

四、Maven项目标准目录结构

1. 目录结构

好的目录结构可以使开发人员更容易理解项目,为以后的维护工作也打下良好的基础。 Maven2根据业界公认的最佳目录结构,为开发者提供了缺省的标准目录模板。

image.png

五、用Maven命令创建项目

1. Maven参数

-D 传入属性参数(最常用)
-P 使用pom中指定的配置
-e 显示maven运行出错的信息
-o 离线执行命令,即不去远程仓库更新包
-X 显示maven允许的debug信息
-U 强制去远程参考更新snapshot包
其他参数可以通过mvn help 获取

2. 命令创建项目

创建Maven普通项目

mvn archetype:generate -DgroupId=packageName -DartifactId=projectName -DarchetypeArtifactId=maven-archetype-quickstart
  • GroupID是项目组织唯一的标识符,实际对应JAVA的包的结构。cn.ybzy.test
  • ArtifactID就是项目的唯一的标识符,实际对应项目的名称,就是项目根目录的名称。
  • archetypeArtifactId:指定原型类型,archetype的意思就是模板原型的意思,模板原型不一样,建立的项目的目录结构对应不一样,maven-archetype-webapp就是指一个简单的普通web应用的目录结构。在Maven中模板原型有2000多个之多,但是奇怪的是我们不推荐使用模板, 后面要说, 不用模板还好用些! 奇怪的是,输入groupId为全部的包路径时,会报找不到pom错误,直接输入名字就会创建成功

六、Maven常用命令与生命周期

  1. 命令
    mvn compile  将源代码编译成字节码.class文件
    mvn clean    将编译的目标文件夹target删除掉
    mvn test     将项目根目录下的test包里的单元测试类都运行一下,但这里注意一下,单元测试类的方法名约定XxxxTest,如果测试类命名没有按照这个约定的,不会被运行!
    mvn package  将项目打包,打包后的文件放在项目根目录的target目录中,创建的目录是webapp打包后的文件是war文件,如果是普通的java项目,打包后的文件就是jar文件
    mvn install  将我们自己写的一个工程,打包成jar包文件,放到本地的maven的仓库里,那么以后我们其他的项目如果需要这个jar包的类,就不用重写源码了,只需要调用取这个jar包就可以了!
    mvn deploy   (1)有私服, 它能够将我们的工程, 里打包jar包, install到私服上, 提给公司内部, 所有项目组成员, 共享, pom.xml 配置私服上的这个jar包的坐标(2)发布, 自动的将我们的项目打包, 发布本地或者是远程服务器, 比如tomcat里,这个项目可以被客户, 别人在web ,在浏览器上访问!
    mvn eclipse:eclipse 将项目转成eclipse项目,就可以从eclipse/sts这类的工具导入了
    mvn source:jar 将工程打成源码包

参考:blog.csdn.net/zhaojiantin…

2. 注意:mvn compile与mvn install、mvn deploy的区别

  • mvn compile,编译类文件
  • mvn install,包含mvn compile,mvn package,然后上传到本地仓库
  • mvn deploy,包含mvn install,然后,上传到私服,或者web容器

3. 其他常用命令

    mvn dependency:sources  故名思义,有了它,你就不用到处找源码了,运行一下,你项目里所依赖的jar包的源码就都有了
    mvn site  将工程的所有文档生成一个像帮助文档样的静态的web站点

4. Maven命令生命周期

在maven中存在三套"生命周期",每一套生命周期,相互独立,互不影响的,但是中同一套生命 周期里,执行后面的命令会自动先执行前面的命令

    CleanLifeCycle: 清理的生命周期  | clean
    defaultLifeCycle:默认的生命周期 | compile,test,package,install,deploy , 执行后面的命令,自动先执行前面所有的命令
    siteLifeCycle:站点生命周期      | site

所以可以使用命令 mvn clean deploy

5. Maven概念图

image.png

主要说明了maven的核心技术

  1. maven是怎么对jar包进行依赖管理
  2. maven是怎么对项目进行构建的(通过命令的方式,它们都是有生命周期的)
  3. maven的底层核心实现项目的构建和管理,都必须通过一个个插件来完成的,而插件本身并不包含在Maven的核心程序当中.

6. 其他问题

idea配置Maven教程:https://www.cnblogs.com/njuptzheng/p/13154202.html

七、解读pom.xml

Maven里的配置文件主要就两个里: settings.xml和pom.xml。settings.xml主要用于配置主maven的运行环境等一系列通用的属性,是全局级别的配置文的件;而件pom.xml主要描述项目的主maven坐标,依赖关系,开发者需要遵循的规则,缺陷坐管理系统,组织和管licenses ,以及其他所有的项目相关因素,是项目级别的配置文件。

配置文件详解:www.cnblogs.com/zhoudaxing/…

scope的分类

  • compile 默认就是compile,什么都不配置也就是意味着compile。compile表示被依赖项目需要参与当前项目的编译,当然后续的测试,运行周期也参与其中,是一个比较强的依赖。打包的时候通常需要包含进去。主程序有效, 测试程序有效, 要打包, 要部署
  • test scope为test表示依赖项目仅仅参与测试相关的工作,包括测试代码的编译,执行。主程序无效, 测试程序有效, 不要打包,不部署, 比较典型的如junit。
  • runntime runntime表示被依赖项目无需参与项目的编译,不过后期的测试和运行周期需要其参与。与compile相比,跳过编译而已,说实话在终端的项目(非开源,企业内部系统)中和compile区别不是很大。另外 runntime的依赖通常和optional搭配使用,optional为true。我可以用A实现,也可以用B实现。
  • provided provided意味着打包的时候可以不用包进去,别的设施(Web Container)会提供。事实上该依赖理论上可以参与编译,测试,运行等周期。相当于compile,但是在打包阶段做了exclude的动作。主程序有效 , 测试程序有效, 不被打包,不要部署。
  • system 从参与度来说,也provided相同,不过被依赖项不会从maven仓库抓,而是从本地文件系统拿,一定需要配合systemPath属性使用。

八、如何解决依赖冲突

1. 传递依赖的概念:

    传递依赖: A.jar 依赖 B.jar, B.jar 依赖 C.jar, 这个时候我们就说BA的直接依赖,CA传递依赖;

2. 什么是依赖冲突

传递依赖可能会产生冲突: 联系着上面, 新导入一个jarD.jar, D依赖C.jar, 但是B依赖的1.1版本, 而D依赖的是1.2版本, 这时候C这个jar包的两个版本, 如果同时被Maven导入工程, 冲突就出现了!

3. Maven默认的处理方式

  • 第一声明者优先原则:哪个先声明, 那就用哪个的传递依赖
  • 路径优先原则:直接依赖的优先级别要高于传递依赖

4. 解决方案

  • 排除依赖

image.png 注意:不需要的排除掉, 不是排除掉所用的包!

  • 版本锁定(这个是推荐使用的)

image.png


image.png 注意:(1)版本锁定(dependencyManagement)不会导入Jar包,只是做版本号的锁定(2)不仅可以锁定自己的pom,还可以锁定子工程的pom中Jar的版本号!

5. scope的依赖传递出去的范围

A–>B–>C。当前项目为A,A依赖于B,B依赖于C。知道B在A项目中的scope,那么怎么知道C在A中的scope呢?

image.png

九、Maven对项目的拆分和聚合

1. 拆分

把mvc项目进行拆分,原来是通过包名进行分层的,现在再Maven项目里,我们可以通过Maven工具,进一步的拆分,怎么分呢?

把Dao层,Service层,Controller和View层的代码,各自拆分成一个一个的表现上独立的工程来。

拆分后的工程分别是:mvc-dao , mvc-service , mvc-web 三个看起来独立的工程。

具体的拆分方式:

  • 先建立一个父工程(注意的就只有一个,Packaging打包的时候要选择: pom , 其他都和普通的Maven项目一样)创建父工程后,你会发现他的目录结构有点特别,只有一个pom.xml,父工程是不需要编码的。
它要做的工作或者说它的主要作用就是:一方面 : 在pom.xml文件中配置jar包 , 让子工程(子模块)继承!(所以把原来的pom.xml里的所有内容copy到这里来)另一方面:将各个子模块聚合在一起
  • 建立各个maven子模块, 快捷的办法选中父工程, 右键选择New -> Maven Module
注意1:父工程最后一个重要的点:不要忘记将父工程安装install到本地的Maven仓库,以供后面的子模块从本地Manven仓库中去引用
注意2:如果我们pom.xml引入的jar包, 是我们本地工程, 在同一个工作空间, Maven会优先从本地的工程里去引入相关的类, 只有本地工程中不存在对应的类, 去本地仓库当中去找!

2. 聚合

前面我们的拆分的时候, 为了让下个层级的工程,比如: Dao层为了下一层级的Service层,能够访问得到自己, Dao要mvn install , 打包成jar包安装到Maven仓库中, 以供Service在pom.xml文件中依赖继承, 这里的问题? 就是每个层都要一个一个地去安装install, 稍稍有点麻烦!

聚合就可以解决这个麻烦! 聚合可以一键安装所有的子工程!

具体配置: 在聚体工程中mvn install就会把所有的工程都mvn install

注意:一般情况下, 我们都是在父工程里进行聚合的! 而且, 创建子工程的时候, 父工程的pom.xml里自动配置modules。

3. 拆分后的Maven运行方式

  • 直接运行web工程
  • 通过父工程运行
  • 部署到tomcat运行

参考:blog.csdn.net/xiao__jia__…

十、Maven私服

1. 创建本地私服

私服,私有服务器。Nexus是常用的私用Maven服务器,一般是公司内部使用。

下载地址:www.sonatype.com/download-os…

image.png 私服功能:指定私服的中央地址、将自己的Maven项目指定到私服地址、从私服下载中央库的项目索引、从私服仓库下载依赖组件、将第三方项目jar上传到私服供其他项目组共享。

怎么安装使用Nexus:

image.png

  • 在Dos下执行命令安装私服(注意, 这里要使用超级管理员的Dos,不然没权限)

image.png 安装完成后, 就是一个服务, 这个服务默认是没有启动的

image.png

  • 启动服务 image.png
  • nexus有自己的页面, 访问的url地址。http://localhost:8081/nexus/ 默认的账号密码admin/admin123。安装完了后, 在私服上查找jar, 还是找不到的,它需要下载远程索引。
  • 下载远程索引:进入名为 Central 的资源库,在其配置页面,将远程下载索引调整为 true 。

image.png 这时,进入任务调度页面,可以看到一个修复资源库索引的任务正在运行。这个任务是由于资源库的配置变更自动触发的,执行一次,执行完会自动删除,作用是将 Maven 中央仓库的索引(目前,大概 2.6 G ,并且还在增加)下载到私服,一般要执行 1-2 小时,具体执行时长依赖实际网络环境。

2. Maven私服中仓库的类型

安装完成私服后, 进入到私服页面:

image.png

  • hosted: (当主人,原型) 宿主仓库
    • 测试版本Snapshots
    • 正式版本Releases
    • 第三方版本3rd , 一般存在版权问题的包, 比如Oracle驱动包就有版权
  • Proxy:代理仓库
    • 中央仓库Central , 根据我们前面讲的Maven寻找jar包的历程
    • Apache里的测试版本的jar包仓库
  • Group: 组仓库, 作用就是兼用前面两种仓库的! 是我们以后主要使用的仓库!
  • 剩下的那个仓库,被废弃了,不管它!

3. 上传jar包到私服

安装好了就要使用了, 首先来看上传jar到私服怎么搞。

  • 配置用户名和密码, 在conf/settings.xml上配置:
    <server>
        <id>nexus-releases</id>
        <username>admin</username>
        <password>admin123</password>
    </server>
    <server>
        <id>nexus-snapshots</id>
        <username>admin</username>
        <password>admin123</password>
     </server>

image.png

  • 在pom.xml这个具体的项目的核心配置文件中, 配置上传jar包到私服的地址
<distributionManagement>
    <!-- 两个ID必须与 setting.xml中的<server><id>nexus-releases</id></server>保持一致-->
    <repository>
        <id>nexus-releases</id>
        <name>Nexus Release Repository</name>
        <url>
           http://10.33.10.249:8081/nexus/content/repositories/release\s
        </url>
    </repository>
    <snapshotRepository>
        <id>nexus-snapshots</id>
        <name>Nexus Snapshot Repository</name>
        <url>
         http://10.33.10.249:8081/nexus/content/repositories/snapshots
        </url>
    </snapshotRepository>
</distributionManagement>

image.png

image.png

  • 执行deploy命令,上传

4. 下载jar包从私服

如何下载呢?通过配置!

  • 配置预处理文件, 在conf/settings.xml里的profile
<profile>
    <id>nexusProfile</id>
    <repositories>
    <repository>
        <id>nexus</id>
        <name>111</name>   
        <url>http://localhost:8081/nexus/content/groups/public/
        </url>
        <snapshots>
            <enabled>true</enabled>
        </snapshots>
        <releases>
            <enabled>true</enabled>
        </releases>
        <layout>default</layout>
     </repository>

</repositories>
<pluginRepositories>
    <pluginRepository>
        <id>public</id>
        <url>http://localhost:8081/nexus/content/groups/public/
        </url>
        <releases><enabled>true</enabled></releases>
        <snapshots><enabled>true</enabled></snapshots>
    </pluginRepository>
 </pluginRepositories>
</profile>

image.png

  • 激活前面预配置文件
    <activeProfiles>
        <activeProfile>nexus</activeProfile>
    </activeProfiles>
  • 下载jar包即可

注意:mirro和repository的区别:www.yisu.com/zixun/20487…

十一、Maven实现web项目自动部署(了解)

carqo插件