Maven进阶

时间:2024-10-26 22:15:36

目录

pom.xml文件

坐标

坐标的概念

坐标的意义

坐标的含义

自己项目的坐标

第三方项目坐标

依赖

依赖的意义

依赖的使用

依赖范围

依赖传递和可选依赖

依赖传递

依赖范围对传递依赖的影响

依赖阻断(暴力行为)

可选依赖

仓库

仓库的概念

本地仓库

*仓库

依赖的搜索顺序

Maven生命周期

Maven继承和聚合

继承

可继承的POM元素

IDEA实现Maven的继承

继承的依赖管理

聚合管理

properties属性的使用

maven私服架构

maven私服介绍

Nexus介绍

maven私服实战

nexus安装

nexus仓库类型

将项目发布到私服

从私服下载jar包

第三方jar包发布到私服

maven仓库界面上传

maven命令行模式


pom.xml文件

        就像 Make 的 MakeFile、Ant 的 build.xml 一样,Maven 项目的核心是 pom.xml。POM( Project Object Model,项目对象模型 ) 定义了项目的基本信息,用于描述项目如何构建,声明项目依赖,等等。Gredele

坐标

坐标的概念

        在 Maven 中坐标是构件的唯一标识,Maven 坐标的元素包括 groupIdartifactIdversionpackaging、classifier。上述5个元素中,groupId、artifactId、version 是必须定义的,packaging 是可选的 ( 默认为 jar )。

坐标的意义

        Maven世界拥有大量构建,我们需要找一个用来唯一标识一个构建的统一规范

        拥有了统一规范,就可以把查找工作交给机器

坐标的含义

  • groupId:组织标识,一般为:公司网址的反写+项目名
  • artifactId:项目名称,一般为:项目名-模块名
  • version:版本号 形式为0.0.1-SNAPSHOT:
    • 第一个 0 表示大版本号,第二个 0 表示分支版本号,第三个 0 表示小版本号
    • SNAPSHOT -- 快照版本,ALPHA -- 内侧版本,BETA -- 公测版本,RELEASE -- 稳定版本,GA -- 正式发布
    • SNAPSHOT -- 快照版本,和RELEASE -- 稳定版本被使用的更多
  • packaging:打包的方式,如:pom, jar, maven-plugin, ejb, war, ...
  • clissifier:用来帮助定义构件输出的一些附属构件。

自己项目的坐标

第三方项目坐标

依赖

依赖的意义

        当编写Java代码时,我们总是需要一些库,例如,做单元测试我们需要JUnit库。对于更大的项目,我们可能需要创建自己的库并在不同的部分使用它的项目。不同的项目需要不同版本的库。 保持项目最新的库JAR文件的正确版本不是一个容易的任务。

        每个外部JAR可能还依赖于其他外部JAR文件等。以递归方式下载所有这些外部依赖JAR文件并确保下载正确的版本是一项巨大的任务。

        当项目越来越大,我们将需要越来越多的外部依赖。

        Maven将下载它们并将它们放在您的本地Maven存储库中。

        我们可以在POM文件中的dependencies元素内指定依赖关系。

依赖的使用

        例如我们的项目需要进行单元测试,则需要使用到junit-4.9.jar包,使用maven引用该依赖的方式如下:

dependencies:表示一个包含所有依赖的集合

dependency:表示一个具体的依赖,可以是本地项目也可以是第三方的依赖

groupId,artifactId,version:引用依赖包的三维坐标,用来定位该依赖包;

scope:控制该依赖包在什么情况下会被加到classpath中

依赖范围

Maven项目在开发工程中有三套classpath

  • 主代码:main下面的都是主代码在编译的时候的依赖
  • 测试代码:test下是测试代码编译的时候的依赖
  • 运行时:main代码在运行的时候对包的依赖

依赖范围的使用,通过在引用第三方依赖时的标签进行设置

比如:

        共 6 种 scope,包括:compileprovidedruntimetest、system、import。例如上图的junit,只在测试中使用,则选择test即可,默认为compile

  • Compile:编译依赖范围。默认使用此依赖范围,其下的maven依赖,对于编译,测试,运行classpath都有效。
  • Test:测试依赖范围。只对测试classpath有效,编译主代码或运行项目时无法使用此依赖。典型例子如junit。
  • Provided:传递性依赖在编译和测试时被包含。其对于编译与测试classpath有效,运行时无效。如在web开发时,只有在编译和测试时才用到servlet-api,将其设置为此范围,在运行时servlet-api由web容器提供,无须依赖。并且在打war包时,此范围的依赖不会打在WEB-INF/lib下。
  • Runtime:运行时依赖范围。与provided相对,运行时classpath有效。典型例子如jdbc(编写是接口规范运行是提供具体实现类需要jar包)。

log4j是一个日志,junit是单元测试

依赖传递和可选依赖

依赖传递

当你在 Maven 项目中声明一个依赖时,这个依赖可能还会依赖其他的库。这些被依赖的库就是传递性依赖。Maven 会自动解析这些传递性依赖,并将它们包含在项目的构建过程中。

应用场景:

第一直接依赖: HelloFriend项目依赖Hello项目

第二直接依赖: MakeFriend项目依赖HelloFriend项目

依赖范围对传递依赖的影响

依赖阻断(暴力行为)

例如我们在HelloFriend项目里面的Hello依赖处添加该配置

则makeFriend项目里面就不会再引入Hello的依赖

可选依赖

        如果我们需要在依赖中明确的排除掉某一依赖,则可以使用exclusion属性,排除掉引用的依赖,如图:

这个exclusions中为什么不需要写版本?

因为 在HelloFriend 中依赖Hello的时候就已经写好了Hello的版本了

我只需在这里摘除Hello就可以了

仓库

仓库的概念

在 Maven 的术语中,仓库是一个位置(place)。

Maven 仓库是项目中依赖的第三方库,这个库所在的位置叫做仓库。

在 Maven 中,任何一个依赖、插件或者项目构建的输出,都可以称之为构件。

Maven 仓库能帮助我们管理构件(主要是JAR),它就是放置所有JAR文件(WAR,ZIP,POM等等)的地方。

仓库的类型有:

  • 本地(local)
  • *(central)
  • 远程(remote)

本地仓库

Maven 的本地仓库,在安装 Maven 后并不会创建,它是在第一次执行 maven 命令的时候才被创建。

运行 Maven 的时候,Maven 所需要的任何构件都是直接从本地仓库获取的。如果本地仓库没有,它会首先尝试从远程仓库下载构件至本地仓库,然后再使用本地仓库的构件。

默认情况下,不管Linux还是 Windows,每个用户在自己的用户目录下都有一个路径名为 .m2/respository/ 的仓库目录

*仓库

Maven *仓库是由 Maven 社区提供的仓库,其中包含了大量常用的库。

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

*仓库的关键概念:

Ø 这个仓库由 Maven 社区管理。

Ø 不需要配置。

Ø 需要通过网络才能访问。

依赖的搜索顺序

Maven生命周期

Maven有三套相互独立的生命周期:

  • Clean
    • clean生命周期的目的是清理项目
  • Default
    • default生命周期的目的是构建项目(从clean开始到install结束)
  • site
    • site生命周期的目的是建立项目站点。(发布项目)

Maven 的生命周期(Lifecycle)是指 Maven 构建项目时所遵循的一系列阶段。这些阶段包括:

clean:清理项目,例如删除之前的构建产物。

validate:验证项目是否正确配置,所有必要的信息是否可用。

compile:编译项目的源代码。

test:运行测试,确保代码修改没有破坏现有功能。

package:将编译的代码打包成可分发的格式,如 JAR、WAR 文件。

verify:运行任何检查以验证包是否如预期工作。

install:将包安装到本地仓库,以便其他项目可以作为依赖使用。

site:生成项目报告,如 JavaDoc、源代码 XRef 等。(发布项目)

deploy:将最终的包复制到远程仓库或其他服务端位置。(部署项目)

在idea中可以直接点击右侧Maven Projects中小齿轮,可以直接执行命令

 也可以点击下图指向的按钮,然后输入命令

Maven继承和聚合

继承

继承就是避免重复,maven的继承也是这样,它还有一个好处就是让项目更加安全。比如我们在项目开发的过程中,可能多个模块独立开发,但是多个模块可能依赖相同的公共模块,比如说每个模块都需要javaseo-utils,在编译的时候,maven-compiler-plugin插件也要被引入,maven仓库地址以及发布目录都是相同的配置。我们可以使用Maven的继承功能,把公共的配置信息写到父模块中,子模块只要继承了该父模块,也会继承父模块的配置信息。

可继承的POM元素

groupId :项目组 ID ,项目坐标的核心元素;

version :项目版本,项目坐标的核心元素;

description :项目的描述信息;

organization :项目的组织信息;

inceptionYear :项目的创始年份;

url :项目的 url 地址

develoers :项目的开发者信息;

contributors :项目的贡献者信息;

distributionManagerment :项目的部署信息;

issueManagement :缺陷跟踪系统信息;

ciManagement :项目的持续继承信息;

scm :项目的版本控制信息;

mailingListserv :项目的邮件列表信息;

properties :自定义的 Maven 属性;

dependencies :项目的依赖配置;

dependencyManagement :醒目的依赖管理配置;

repositories :项目的仓库配置;

build :包括项目的源码目录配置、输出目录配置、插件配置、插件管理配置等;

reporting :包括项目的报告输出目录配置、报告插件配置等。

IDEA实现Maven的继承

前端:写网页的

后端:写背后逻辑的

前台:用户端 前台中有前端和后端

后台:管理员端 后台中有前端和后端

需要五个模块 父工程模块,前台模块,后台模块,公共模块,图片模块

前台模块,后台模块,公共模块,图片模块都被父工程模块统一管理

父工程只做管理,公共模块操作数据库

创建父类项目

创建子类项目core

 

 

 

以同样的方式创建manage和portal项目

至此,一个由parent统一管理core,manage和portal的mavan项目就创建好了;

观察父子项目的pom文件配置

继承的依赖管理

父类直接引用依赖,如果在父类的dependencies内直接引用依赖,则子类都会继承该依赖,以mybatis为例:

父类通过dependencyManagement管理依赖,子类不会默认继承该依赖,但是当子类使用该依赖时无需考虑版本信息,直接继承父类dependencyManagement中设置的版本号(Version),以log4j为例:

聚合管理

我们在平时的开发中,项目往往会被划分为好几个模块,比如common公共模块、system系统模块、log日志模块、reports统计模块、monitor监控模块等等。这时我们肯定会出现这么一个需要,我们需要一次构件多个模块,而不用每个模块都去mvn;

以上面得父子项目为例,当我们对parent进行mvn install时,会对core,manage和portal项目均进行install操作:

properties属性的使用

通过 properties元素用户可以定义一个或多个 maven 属性,然后在 maven 的其他地方使用 ${属性名称} 的方式引用该属性,这种做法的意义在于消除重复和统一管理。比如,需要在多个地方重复声明同样的 SpringFramework 版本,现在只需要在一个地方声明就可以。

maven私服架构

maven私服介绍

        正式开发,不同的项目组开发不同的工程。maven-dao 工程开发完毕,发布到私服maven-service 从私服下载 dao。

        公司在自己的局域网内搭建自己的远程仓库服务器,称为私服, 私服服务器即是公司内部的 maven 远程仓库, 每个员工的电脑上安装 maven 软件并且连接私服服务器,员工将自己开发的项目打成 jar 并发布到私服服务器,其它项目组从私服服务器下载所依赖的构件(jar)。

        私服还充当一个代理服务器,当私服上没有 jar 包会从互联网*仓库自动下载。

Nexus介绍

Nexus 是 Maven 仓库管理器, 通过 nexus 可以搭建 maven 仓库,同时 nexus 还提供强大的仓库管理功能,构件搜索功能等。

maven私服实战

nexus安装

nexus官网Sonatype Code Repository OSS Tool | Sonatype

1 从官网下载nexus,解压到一个不含中文的目录下。

我这里是直接解压在了D盘中 D:\nexus-2.12.0-01

查看conf文件下的nexus.properties配置文件,可以修改对应的配置

2 nexus的安装命令:使用管理员运行cmd命令窗口,切换目录D:\nexus-2.12.0-01\bin目录下,执行nexus.bat install进行安装。执行nexus.bat start 启动服务 执行nexus.bat stop停止服务。

3 nexus的卸载命令:使用管理员运行cmd命令窗口,切换目录D:\nexus-2.12.0-01\bin目录下,执行nexus.bat uninstall进行卸载

4 访问图形化界面:打开浏览器,输入http://localhost:端口号/nexus访问

我这里输入为http://localhost:8079/nexus

5 点击log in,进行登录。用户名:admin 密码:admin123

nexus仓库类型

nexus提供了不同的仓库类型

1 hosted,宿主仓库, 部署自己的 jar 到这个类型的仓库,包括 releases 和 snapshot 两部分, Releases 公司内部发布版本仓库、 Snapshots 公司内部测试版本仓库

2 proxy,代理仓库, 用于代理远程的公共仓库,如 maven *仓库,用户连接私服,私服自动去*仓库下载 jar 包或者插件。

3 group,仓库组,用来合并多个 hosted/proxy 仓库,通常我们配置自己的 maven 连接仓库组。Group仓库组也是可以自己进行定制的。

4 virtual(虚拟):兼容 Maven1 版本的 jar 或者插件

将项目发布到私服

        需要在客户端即部署要部署的工程电脑上配置 maven 环境,并修改settings.xml 文件, 配置连接私服的用户和密码 。

        此用户名和密码用于私服校验,因为私服需要知道上传的账号和密码是否和私服中的账号和密码一致。

        在servers节点下进行配置

<!-- 定义稳定版本的id名称,用户名密码 -->
<server>
      <id>releases</id>
      <username>admin</username>
      <password>admin123</password>
</server>
<!-- 定义开发版本的id名称,用户名密码 -->
<server>
      <id>snapshots</id>
      <username>admin</username>
      <password>admin123</password>
   </server>

        配置项目 pom.xml,配置私服仓库的地址,本公司的自己的 jar 包会上传到私服的宿主仓库,根据工程的版本号决定上传到哪个宿主仓库,如果版本为 release 则上传到私服的 release 仓库,如果版本为snapshot 则上传到私服的 snapshot 仓库。

<distributionManagement>
   <repository>
      <id>releases</id>
      <url>http://localhost:8079/nexus/content/repositories/releases/</url>
   </repository>
   <snapshotRepository>
      <id>snapshots</id>
      <url>http://localhost:8079/nexus/content/repositories/snapshots/</url>
   </snapshotRepository>
</distributionManagement>

        注意:这里的 id 标签的值要和 settings.xml配置文件中的id值保持一致。

在该工程中执行deploy命令,发布项目到私服上。

这里上传的是RELEASES稳定版本

查看私服结果

也可以上传SNAPSHOT快照版本

查看私服结果

从私服下载jar包

        在settings.xml配置文件配置私服的镜像文件

<mirror>
        <!-- id名称 -->
        <id>nexusmaven</id>
        <!-- 表示拦截所有的请求,都重定向到私服,从私服下载jar包,私服没有再去*仓库下载 -->
        <mirrorOf>*</mirrorOf>  
        <name>nexus maven</name>
        <!-- 私服的组地址 -->
    <url>http://localhost:8079/nexus/content/groups/public/</url>      
</mirror>

        进行测试

        先把自己的某个项目发布到私服中,然后删除掉本地仓库中的jar包,再使用其他项目去依赖该jar包,查看是否从私服中下载。

        在其他项目中引入该坐标依赖。

<!--依赖Hello这个项目-->
<dependency>
   <groupId>cn.tx.maven</groupId>
   <artifactId>Hello</artifactId>
   <version>0.0.1-RELEASES</version>
   <scope>compile</scope>
</dependency>

        还有一种方式,可以配置仓库的方式,可以修改自己项目的pom配置文件,添加仓库的配置。

<repositories>
   <repository>
      <id>nexus</id>
      <name>nexusmaven</name>
      <url>http://localhost:8079/nexus/content/groups/public/</url>
      <releases>
         <enabled>true</enabled>
      </releases>
      <snapshots>
         <enabled>true</enabled>
      </snapshots>
   </repository>
</repositories>
<pluginRepositories>
   <pluginRepository>
      <id>public</id>
      <url>http://localhost:8079/nexus/content/groups/public/</url>
      <name>pluginRepositories</name>
   </pluginRepository>
</pluginRepositories>

        上面的方式不是特别的理想,需要在每一个项目的pom文件中都添加相同的配置,比比较麻烦。可以在settings.xml配置文件中添加配置,完成统一的设置。

<!-- 下载jar包配置 -->
    <profile> 
        <!--profile的id -->
        <id>dev</id>
        <repositories>
            <repository> <!--仓库id,repositories可以配置多个仓库,保证id不重复 -->
                <id>nexus</id> <!--仓库地址,即nexus仓库组的地址 -->
                <url>http://localhost:8079/nexus/content/groups/public/</url> <!--是否下载releases构件 -->
                <releases>
                    <enabled>true</enabled>
                </releases> <!--是否下载snapshots构件 -->
                <snapshots>
                    <enabled>true</enabled>
                </snapshots>
            </repository>
        </repositories>
        <pluginRepositories> <!-- 插件仓库,maven的运行依赖插件,也需要从私服下载插件 -->
            <pluginRepository> <!-- 插件仓库的id不允许重复,如果重复后边配置会覆盖前边 -->
                <id>public</id>
                <name>Public Repositories</name>
                <url>http://localhost:8079/nexus/content/groups/public/</url>
            </pluginRepository>
        </pluginRepositories>
    </profile>

        激活配置

<activeProfiles>
        <activeProfile>dev</activeProfile>
    </activeProfiles>

        进行测试

第三方jar包发布到私服

maven仓库界面上传

        添加完成

maven命令行模式

        先在settings.xml配置文件中配置用户名密码

<server>
<id>thirdparty</id>
<username>admin</username>
 <password>admin123</password>
</server>

        使用maven命令上传第三方包

 mvn deploy:deploy-file -Dmaven.test.skip=true -DgroupId=sdk的groupId -DartifactId=包的名称 -Dversion=版本号(如:0.0.1) -Dpackaging=包的类型 -Dfile=第三方sdk存放在本地的文件位置 -Durl=要上传到maven仓库的仓库位置 -DrepositoryId=maven中配置的server id

1 -DgroupId=com.fastjson 第三方包的groupId

2 -DartifactId=fastjson 第三方包的名称

3 -Dversion=1.2.71  版本号(如:0.0.1),建议用三位版本号表示

4 -Dpackaging=jar  上传的类型是jar类型

5 -Dfile=D:\repository.....\fastjson-1.2.71.jar  第三方sdk存放在本地的文件位置

6 -Durl=http://localhost:8079/repository/myself_hosted/   要上传到maven仓库的仓库位置

7 -DrepositoryId=release  setting.xml文件中配置server的ID

        添加完成