写在前面

Maven,学习框架之前我们都会接触到的一个工具,感觉他的定位,似乎就跟git一样,只是方便我们开发?于是自然而然的,很多小猿对于Maven都只是停留在会用的阶段,利用他来构建,打包,引入jar包。

而实际上呢,Maven还有很多强大的地方,多模块开发,私服等等也是需要我们掌握的,在实际的开发中,往往是多模块共同开发,特别是我们之前提及的Dubbo分布式开发中,多模块开发是重中之重!

传统项目开发

导jar包

  • 既然是导jar包,我们是在本地windows开发,而实际项目是要放到linux服务器上,如果我们单纯把项目打成jar包丢上去,依赖文件也是jar包,但两个系统因为环境不一样,直接丢jar包(他不会重新编译运行的),得出来的结果可能就不一样

比如String的getByte方法,在两个系统上得到的结果是不一样的,如果没有重新编译运行,那最终也会有偏差

Maven概念

POM

Project Object Model

  • 把每个项目看成一个对象来进行管理

Maven作用

项目构建和管理

提供一套自动化构建项目的方法.并且通用,兼容性好,跨平台

  • 包括打包,编译,测试,运行等一套操作下来,让你在开发环境也可以方便进行测试等功能

构建是面向过程的,就是一些步骤,完成项目代码的编译,测试,运行,打包,部署等等。

maven支持的构建包括有:

1.清理, 把之前项目编译的东西删除掉,我新的编译代码做准备。

2.编译, 把程序源代码编译为执行代码, java-class文件

  • 批量的,maven可以同时把成千上百的文件编译为class。
  • javac 不一样,javac一次编译一个文件。

3.测试, maven可以执行测试程序代码,验证你的功能是否正确。

4.报告, 生成测试结果的文件, 测试通过没有。

5.打包, 把你的项目中所有的class文件,配置文件等所有资源放到一个压缩文件中。

  • 这个压缩文件就是项目的结果文件, 通常java程序,压缩文件是jar扩展名的。
  • 对于web应用,压缩文件扩展名是.war

6.安装, 把5中生成的文件jar,war安装到本地仓库供别的文件使用

7.部署, 把程序安装好可以执行。

这些在下边的生命周期其实刚刚好体现出来

依赖管理

  • 处理jar包冲突问题

统一开发结构--约定大于配置

即能进行配置的不要去编码指定,能事先约定规则的不要去进行配置。这样既减轻了劳动力,也能防止出错。

  • 实际上maven并没有强行要求约束我们项目的文件结构,而是因为他做得好,自然而然就变成一种通用的结构了

坐标

仓库

私服(下文中会有具体实例)

下载顺序??

先在本地仓库找,找不到就去私服找,如果私服没有,则会到中央仓库下载到私服并且发送到本地仓库

无论如何都还是最终会下到本地,区别只是从哪发送到本地而已?

  • 此处有点疑问,私服没有会去中央仓库下到私服吗?我下边配置了阿里云和私服,似乎私服没有的话是直接从阿里云直达下载到本地仓库,并不会通过私服?希望大佬可以指正一下!

图源 https://m.yisu.com/zixun/309916.html

镜像仓库配置

mirrorOf

对哪种仓库进行镜像

手工maven

Maven工程目录结构



构建命令

Maven构建命令使用mvn开头,后面加功能参数,可以一次执行多个命令,使用空格分隔

clean

把编译的去掉,target文件目录删除掉

install

把你的当前项目安装到本地仓库,成为一个jar包供别的项目引用里边的类

package

会先compile,然后再clean



依赖管理

依赖传递

依赖具有传递性,包括直接传递和间接传递。

直接传递:在当前项目中通过依赖配置建立的依赖关系(A使用B,A和B就是直接传递)

间接传递:如果A依赖B,而B依赖C,那么A和C之间就是间接传递

冲突原则

路径优先

在越浅层的优先级越高

声明优先

在同一层,先声明的比较高

在同一个pom中配置了相同资源的不同版本

后配置的覆盖前边的

可选依赖

排除依赖

①手动排除依赖,,且2可以直接把3整个依赖进来,再排除掉特定的



②借助idea插件排除依赖 -- Maven Helper

打开pom文件,下方就可以选择切换查看方式

右键选中你需要排除的 Exclude即可

③版本锁定--(待补充实例,拿Dubbo的吧)

Dubbo的GitHub文档中应用到了这点

<properties>
<spring-boot.version>2.3.0.RELEASE</spring-boot.version>
<dubbo.version>2.7.8</dubbo.version>
</properties> <dependencyManagement>
<dependencies>
<!-- Spring Boot -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency> <!-- Apache Dubbo -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-dependencies-bom</artifactId>
<version>${dubbo.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency> </dependencies>
</dependencyManagement> <dependencies>
<!-- Dubbo Spring Boot Starter -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>2.7.8</version>
</dependency>
</dependencies>

dependencyManagement

  • 通过它元素来管理jar包的版本,让子项目中直接引用依赖而不用列出版本号。Maven会沿着父子层次向上走,直到找到一个拥有元素的项目,然后它就会使用在这个dependencyManagement元素中指定的版本号。

管理通用性

  • 我们不需要给每个子项目都去声明版本了,只需要在最顶层父类中统一进行管理。

可扩展性

  • 如果某个子项目需要另外一个版本号时,只需要在dependencies中声明一个版本号即可。子类就会使用子类声明的版本号,不继承于父类版本号。

依赖范围

传递性(了解)

生命周期与插件



继承(SpringBoot就是一个很好的例子)

作用

通过继承可以实现在子工程中沿用父工程中的配置(与Java类似)

制作方式

在子工程中声明其父工程坐标与对应的位置

<!--定义该工程的父工程-->
<parent>
<groupId> </groupId>
<artifactId> </artifactId>
<version> </version>
<!--填写父工程的pom文件-->
<relativePath>父工程pom文件地址</relativePath>
</parent>

如SpringBoot中

<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.6</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>

在父工程中定义依赖管理

可以管理版本,解决子工程中依赖冲突问题(上文提及到的版本锁定)

<!--声明此处进行依赖管理-->
<dependencyManagement>
<!--具体的依赖-->
<dependencies>
<dependency>
<groupId> </groupId>
<artifactId> </artifactId>
<version> </version>
</dependency>
</dependencies>
</dependencyManagement>

继承依赖使用:在子工程中定义依赖关系,无需声明依赖版本,版本参照父工程中依赖的版本

<dependencies>
<dependency>
<groupId> </groupId>
<artifactId> </artifactId>
</dependency>
</dependencies>

聚合

  • 我们实际开发中,很多时候是多模块开发,会把业务单独抽离出来成为一个模块,比如Dao模块,Service模块

    • 那这个时候比如说Dao模块发生了变化,其他所有依赖Dao模块的模块怎么办呢,都得去更新吗?他自己知道吗?还是得我们自己去重新install重新依赖,有没有办法让他们同时更新而不是单独更新呢?--这就要用到我们的聚合

建立一个空模块

打包类型设置为pom

<packaging>pom</packaging>

聚合module

效果

私服仓库分类

  • 宿主仓库hosted:指的是我们公司或团队内部的包,并且 hosted 类型的仓库会分为 releases 和 snapshots 两个,前者是正式版,后者一般是开发测试版(快照版);

保存那些无法从中央仓库直接获取的资源,比如说我们自己研发的一些项目,或者一些第三方非开源项目比如oracle(要注意版权问题)

  • 代理仓库proxy:用来代理中央仓库,例如我们依赖的包在本地仓库没有,就会到私服获取,私服没有的话,会到中央仓库先把包下载到私服,然后再下载到本地仓库;
  • 仓库组group:把多个仓库组合起来,然后我们项目中只需要配置上这个类型的仓库地址,就可以把它里面组合的几个仓库都关联上.

**快速搭载Nexus私服

私服作用

有时候我们是多台机器开发,而我们要去引用别人机器上的模块jar包时,这个时候对方单纯install也只是发布到对方电脑上的本地仓库而已,我们还是访问不到.这个时候就需要一个中间商私服,来存放一些需要共享的资源

nexus下载安装

  • 首先要下载 nexus 搭载我们的私服
  • 下载完成后,修改etc中的启动端口(默认是8081)

  • 进入bin目录
  • vim nexus
  • 进入后直接 /run_as_user 查找到run_as_root 再按 i 进入编辑模式



把这一项改为false , 才可以用root用户开启nexus

  • 修改完成后 按ESC退出编辑模式进入命令模式 输入 :wq 保存退出即可
  • 最后 ./nexus start 启动
  • 访问你设置的端口号

账号默认是admin

初次登录会提示你去特定位置找密码



在该目录下寻找即可

之后可以修改默认密码

访问私服仓库(手动上传)--不推荐

  • 上方可以切换视图,左边是浏览仓库,右边的管理设置仓库,我们在管理这一层添加一个自己的仓库

这里我们创建一个宿主仓库

修改快照版/发行版

找到maven-public , 把我们刚创建的包含进去即可

去浏览页面找到我们的仓库,手动上传

idea环境上传

需要配置两个地方

  • 一个是本地仓库如何跟私服打交道 -- 对应默认的总setting文件
  • 一个是我们的工程要发布到私服具体哪个仓库 -- 对应当前项目pom文件里边的配置



上传jar认证配置

上传jar包需要认证,maven的认证是在.m2/settings.xml或自己的的maven里settings.xml中servers标签下配置的.

这里特别说明一下,servers配置的ID很关键,这个与你项目里面的distrubtionManagement下配置的仓库ID一致,否则会报审核未通过的错误。

<!--  配置访问服务器的权限-->
<server>
<id>nexus-Melo</id>
<username>admin</username>
<password>admin</password>
</server>
<server>
<id>Melo-Release</id>
<username>admin</username>
<password>admin</password>
</server>
<server>
<id>Melo-Snapshots</id>
<username>admin</username>
<password>admin</password>
</server>

这里的id对应了setting.xml里配置的server.id信息name任取

<!--    私服发布管理-->
<distributionManagement>
<repository>
<!-- id要跟setting中配置访问时的id一致-->
<id>Melo-Release</id>
<!-- 仓库地址 去nexus网站找到仓库复制url即可 -->
<url>http://ip地址:端口/repository/Melo-Release/</url>
</repository>
<snapshotRepository>
<id>Melo-Snapshots</id>
<url>http://ip地址:端口/repository/Melo-Snapshot/</url>
</snapshotRepository>
</distributionManagement>

上传效果

idea环境从私服获取(同时使用阿里云镜像+私服)

  • 配置全局setting.xml,我们所有项目就都会去私服找了

建议使用自带的maven-public仓库组 , 然后把我们自己创建的仓库包含进去

注意不要把proxy类的仓库包含进我们的group!这样我们配置的阿里云镜像就失效了

除非自己去手动改proxy代理的仓库地址,但个人感觉不太推荐,具体见后文"另外的实现方式"

配置server--访问服务器的权限

包含拉取和上传的两部分配置,两部分都需要权限

<!--  配置访问服务器的权限-->
<!--第一个id要和下面的mirror中的id一致,代表拉取时也需要进行身份校验-->
<server>
<id>nexus-Melo</id>
<username>你的私服账号</username>
<password>你的私服密码</password>
</server>
<!-- 下边是我们上传时的访问配置,id对应你上传时<distributionManagement>中写的id-->
<server>
<id>Melo-Release</id>
<username>你的私服账号</username>
<password>你的私服密码</password>
</server>
<server>
<id>Melo-Snapshots</id>
<username>你的私服账号</username>
<password>你的私服密码</password>
</server>

配置mirror

<!--    阿里云私服,拿中央仓库-->
<mirror>
<id>alimaven</id>
<name>aliyun maven</name>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
<!-- 访问中央仓库才使用阿里云镜像-->
<mirrorOf>central</mirrorOf>
</mirror>
<!-- 自己的maven私服-->
<mirror>
<id>nexus-Melo</id>
<!--镜像名称 -->
<name>nexus-Melo</name> <!--镜像除了中央仓库以外的仓库(本地有的话还是优先本地,没有再去私服找,私服没有的话会先通过阿里云下载到私服,再发送到本地)-->
<mirrorOf>!central</mirrorOf>
<!--该镜像的URL。构建系统会优先考虑使用该URL,而非使用默认的服务器URL。
选择你用哪个私服仓库来作为镜像,建议选择自带的maven-public,具体看上边 -->
<url>http://ip地址:端口/repository/maven-public/</url>
</mirror>

扩展--mirrorOf

*表示所有 !表示非

,!repo1 : 在除了repo1的仓库中寻找

external:
: 刚好跟上边的 !internal.repo,* 相反

扩展--mirror**

  • 默认情况下配置多个mirror的情况下,只有第一个生效。

    • 无法连接的时候,才会去找后一个;而我们想要的效果是:当某个jar包在第一个mirror中不存在的时候,maven会去第二个mirror中查询下载,但是maven不会这样做!

正确的操作是在profiles节点下配置多个profile,而且配置之后要激活!!!!

配置profile

<!--      阿里云-->
<profile>
<id>aliyun</id>
<repositories>
<repository>
<id>aliyun</id>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
<updatePolicy>always</updatePolicy>
</snapshots>
</repository>
</repositories>
</profile> <!-- 自己的私服-->
<profile>
<!-- 注意这个id,下边激活的时候会用到,要一一对应-->
<id>nexus-pr</id>
<!-- 远程仓库列表 -->
<repositories>
<repository>
<!-- 上边要拉取的仓库id-->
<id>nexus-Melo</id>
<name>nexus-Melo</name>
<!-- 虚拟的URL形式,指向镜像的URL-->
<url>http://ip地址:端口/repository/maven-public/</url>
<layout>default</layout>
<!-- 表示可以从这个仓库下载releases版本的构件-->
<releases>
<enabled>true</enabled>
</releases>
<!-- 表示可以从这个仓库下载snapshot版本的构件 -->
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
<!-- 暂时还没有自定义插件的需求 -->
<!-- 插件仓库列表 -->
<!-- <pluginRepositories>-->
<!-- <pluginRepository>-->
<!-- &lt;!&ndash; 上边要拉取的仓库id&ndash;&gt;-->
<!-- <id>nexus-Melo</id>-->
<!-- <name>nexus-Melo</name>-->
<!-- <url>http://114.132.235.87:9001/repository/maven-public/</url>-->
<!-- <layout>default</layout>-->
<!-- <snapshots>-->
<!-- <enabled>true</enabled>-->
<!-- </snapshots>-->
<!-- <releases>-->
<!-- <enabled>true</enabled>-->
<!-- </releases>-->
<!-- </pluginRepository>-->
<!-- </pluginRepositories>-->
</profile>

激活profile!!

				<!--对应上边profile定义的id!!!-->
<!-- 激活阿里云-->
<activeProfile>aliyun</activeProfile>
<!-- 激活nexus-->
<activeProfile>nexus-pr</activeProfile>
<activeProfile>jdk-1.8</activeProfile>

实现阿里云与私服共存的效果

那些中央仓库有的文件,就会走阿里云镜像去下载,如果是我们自定义的jar包(中央仓库没有的),就会走我们的私服去下载!

另外的实现方式

  • 其实我们也可以直接在私服创建一个proxy仓库,让他代理阿里云镜像就好了,但是这样其实也有个问题,就是proxy仓库本身是不允许我们自定义上传组件的,所以综合考虑的话还是上边自行配置的方法好一点

写在最后

  • maven这一块,具体的聚合继承实例,等到真正运用上了分布式开发的时候,应该会有所渗透。而私服的运用,在多台机器上是十分重要的!

Maven还停留在导jar包?快来探索Nexus私服的新世界的更多相关文章

  1. 如何将第三方jar包上传到Nexus私服

    首先登陆私服服务器         以动力威视私服为例:          自己搭建的私服地址:http://192.168.1.5:8081/nexus/index.html#view-reposi ...

  2. Intellij Idea系列之导Jar包与编写单元测试(二)

     Intellij Idea系列之导Jar包与编写单元测试(二) 一.初衷 对于很多的初学者来说,Intellij如何导入jar包感到很迷惑,甚至在网上搜过相关文章之后还是云里雾里,本博客通过图文并茂 ...

  3. 说点手动导jar包的细节Referenced Libraries

    对于Referenced Libraries 若是手动,新建好Scala项目工程,这里取名为ScalaInAction 得需将Scala 2.11.8自带的,换成2.10.*版本 在其上,点击右键,B ...

  4. eclipse导出maven工程的可执行jar包

    一.eclipse导出maven工程的可执行jar包 建立两个maven工程 ZKServer 和ZKClient 注意:用maven进行开发管理的话,默认的打出来的jar包是不能运行的,需要在pom ...

  5. maven向本地仓库导入jar包(处理官网没有的jar包)

    对于官网没有的jar包,maven向本地仓库导入jar包用如下命令 mvn install:install-file -DgroupId=包名 -DartifactId=项目名 -Dversion=版 ...

  6. 【转】maven导出项目依赖的jar包

    本文转自:http://my.oschina.net/cloudcoder/blog/212648 一.导出到默认目录 targed/dependency 从Maven项目中导出项目依赖的jar包:进 ...

  7. Maven导出Project依赖的jar包

    Maven导出Project依赖的jar包 从Maven仓库中导出jar包: mvn dependency:copy-dependencies 会导出到Project的targed/dependenc ...

  8. [Maven]Maven构建可执行的jar包(包含依赖jar包)

    ----------------------------------------------------------------- 原创博文,如需转载请注明出处! 博主:疲惫的豆豆 链接:http:/ ...

  9. Maven 生成可执行的jar包

    maven 默认打包生成的 jar 包是不能够直接运行的,因为带有 main 方法的类信息不会添加到 manifest 中,即打开 jar 文件中的 META-INF/MANIFEST.MF 文件,将 ...

随机推荐

  1. 一文搞懂Python Unittest测试方法执行顺序

    大家好~我是米洛! 欢迎关注我的公众号测试开发坑货,一起交流!点赞收藏关注,不迷路. Unittest unittest大家应该都不陌生.它作为一款博主在5-6年前最常用的单元测试框架,现在正被pyt ...

  2. 关于软链接ln -s 的使用

    1.效果跟windows创建快捷方式是一样的,先找到要被创建的原始文件或目录.然后才能创建. 2.格式:ln  -s   [源文件或目录]   [目标文件或目录] 3.源文件或目录必须是绝对目录. 4 ...

  3. sed 找出含有某个字符串的行 注释掉

    1.源文件例子 [root@node1 ~]# cat /etc/fstab # # /etc/fstab # Created by anaconda on Mon Mar 1 18:32:15 20 ...

  4. Docker安装flink及避坑指南

    Docker安装flink 导航 无处不在的大数据 安装flink 拉取flink镜像 编写docker-compose.yml 生成启动 查看安装效果 常见坑及解决方案 问题1 问题2 参考   本 ...

  5. CORS跨域请求规则以及在Spring中的实现

    CORS: 通常情况下浏览器禁止AJAX从外部获取资源,因此就衍生了CORS这一标准体系,来实现跨域请求. CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origi ...

  6. js判断苹果端,安卓端

    <script type="text/javascript"> var browser = { versions : function() { var u = navi ...

  7. npm WARN ajv-keywords@2.1.1 requires a peer of ajv@^5.0.0 but none is installed. You must install peer dependencies yourself.

    解决: npm install -g npm-install-peers npm install -g npm npm i ajv 但是好像没啥用

  8. SpringBoot 如何进行对象复制,老鸟们都这么玩的!

    大家好,我是飘渺. 今天带来SpringBoot老鸟系列的第四篇,来聊聊在日常开发中如何优雅的实现对象复制. 首先我们看看为什么需要对象复制? 为什么需要对象复制 如上,是我们平时开发中最常见的三层M ...

  9. OC源码剖析对象的本质

    1. 类的底层实现 先写一个 Person 类: @interface Person : NSObject @property (nonatomic, copy) NSString *p_name; ...

  10. httprunner环境准备:Pycharm创建httprunner项目

    使用命令行方式,可能会不大习惯,下面来一个通过Pycharm来创建httprunner项目. 创建虚拟环境. 安装httprunner 创建脚手架目录:httprunner startproject ...