Author: haoransun
Wechat: SHR—97
Maven中央仓库地址:https://mvnrepository.com/
Maven官网下载地址:http://maven.apache.org/download.cgi
前言
生产环境下开发不再是一个项目一个工程,而是每一个模块创建一个工程,而多个模块整合在一起就需要使用到像 Maven 这样的构建工具。
1. Maven是什么?
Maven 是 Apache 软件基金会组织维护的一款自动化构建工具,专注服务于 Java 平台的项目构建和 依赖管理。Maven 这个单词的本意是:专家,内行。读音是[‘meɪv(ə)n]或[‘mevn]。
基本作用:
- 添加第三方 jar包
- jar包之间依赖关系
- 项目拆分为多模块
2. 构建是什么
构建说白了就是以我们编写的 Java 代码、框架配置文件、国际化等其他资源文件、JSP 页 面和图片等静态资源作为“原材料”,去“生产”出一个可以运行的项目的过程。
构建过程的主要环节:
清理:删除以前的编译结果,为重新编译做好准备。
编译:将 Java 源程序编译为字节码文件。
测试:针对项目中的关键点进行测试,确保项目在迭代开发过程中关键点的正确性。
报告:在每一次测试后以标准的格式记录和展示测试结果。
打包:将一个包含诸多文件的工程封装为一个压缩文件用于安装或部署。Java 工程对应 jar 包,Web 工程对应 war 包。
安装:在 Maven 环境下特指将打包的结果——jar 包或 war 包安装到本地仓库中。
部署:将打包的结果部署到远程仓库或将 war 包部署到服务器上运行。
3. Maven核心概念
Maven 能够实现自动化构建是和它的内部原理分不开的,这里我们从 Maven 的九个核心概念入手, 看看 Maven 是如何实现自动化构建的 。
- *POM *
- *约定的目录结构 *
- *坐标 *
- 依赖管理
- *仓库管理 *
- 生命周期
- 插件和目标
- *继承 *
- 聚合
1. POM
Project Object Model:项目对象模型。将 Java 工程的相关信息封装为对象作为便于操作和管理的模型。 Maven 工程的核心配置。可以说学习 Maven 就是学习 pom.xml 文件中的配置。
2. 约定的目录结构
约定>配置>编码
3. 坐标
使用如下三个向量在 Maven 的仓库中唯一的确定一个 Maven 工程。
groupid:公司或组织的域名倒序+当前项目名称
artifactId:当前项目的模块名称
version:当前模块的版本
1 | <groupId>com.alibaba</groupId> |
如何通过坐标到仓库中查找jar包
第一步:
将 gav 三个向量连起来:( com.alibaba+dubbo+2.6.0)
第二步:
以连起来的字符串为目录结构到仓库中查找(com/alibaba/dubbo/2.6.0/dubbo-2.6.0.jar)
4. 依赖管理
Maven 中最关键的部分,就是使用它的依赖管理功能。
1. 依赖
当 A jar 包用到了 B jar 包中的某些类时,A 就对 B 产生了依赖,这是概念上的描述。那么如何在项目 中以依赖的方式引入一个我们需要的 jar 包呢? 答案非常简单,就是使用 dependency 标签指定被依赖 jar 包的坐标就可以了。
2. 依赖的范围
可用到的有:compile、test、provided
依赖的有效性
依赖的传递性
A依 B,B依赖C,A能否使用C呢?那要看B依赖C的范围是不是compile,如果是则可用,否则不可用。
依赖的排除
如果我们在当前工程中引入了一个依赖是 A,而 A 又依赖了 B,那么 Maven 会自动将 A 依赖的 B 引入当 前工程,但是个别情况下 B 有可能是一个不稳定版,或对当前工程有不良影响。这时我们可以在引入 A 的时 候将 B 排除。
1 | <dependency> |
3. 统一声明版本号
引用之前声明的版本号
4. 依赖的原则
- 路径最短者优先
- 路径相同时先声明者优先(即 dependency的书写顺序)
5. 仓库管理
本地仓库:为当前本机电脑上的所有 Maven 工程服务。
远程仓库:
- 私服:架设在当前局域网环境下,为当前局域网范围内的所有 Maven 工程服务。
- 中央仓库:架设在 Internet 上,为全世界所有 Maven 工程服务。
- 中央仓库的镜像:架设在各个大洲,为中央仓库分担流量。减轻中央仓库的压力,同时更快的响应用户请求。
仓库中的文件
[1]Maven 的插件
[2]我们自己开发的项目的模块
[3]第三方框架或工具的 jar 包
6. 生命周期
Maven 生命周期定义了各个构建环节的执行顺序,有 了这个清单,Maven 就可以自动化的执行构建命令了。
Maven有3套相互独立的生命周期
①Clean Lifecycle 在进行真正的构建之前进行一些清理工作。
②Default Lifecycle 构建的核心部分,编译,测试,打包,安装,部署等等。
③Site Lifecycle 生成项目报告,站点,发布站点
运行任何一个阶段的时候,它前面的所有阶段都会被运行,例如我们运行 mvn install 的时候,代码会 被编译,测试,打包。这就是 Maven 为什么能够自动执行构建过程的各个环节的原因。此外,Maven 的插件机制是完全依赖 Maven 的生命周期的,因此理解生命周期至关重要。
7. 插件和目标
Maven的核心仅仅定义了抽象的生命周期,具体的任务都是交由插件完成的。
每个插件都能实现多个功能,每个功能就是一个插件目标。
*Maven 的生命周期与插件目标相互绑定,以完成某个具体的构建任务。 *
例如:compile 就是插件 maven-compiler-plugin 的一个目标;pre-clean 是插件 maven-clean-plugin 的一个目标。
8. 继承
由于非 compile 范围的依赖信息是不能在“依赖链”中传递的,所以有需要的工程只能单独配置。
1-创建父工程,打包方式为pom
2-在子工程中引用父工程
1 | <parent> |
如果子工程的 groupId 和 version 如果和父工程重复则可以删除。
3-在父工程中管理依赖
将 Parent 项目中的 dependencies 标签,用 dependencyManagement 标签括起来。
收集所有非compile范围的依赖信息,使用dependencyManagement标签统一管理
1 | <dependencyManagement> |
在子项目中重新指定需要的依赖,删除范围和版本号
1 | <dependencies> |
9. 聚合
将多个工程拆分为模块后,需要手动逐个安装到仓库后依赖才能够生效。修改源码后也需要逐个手动进 行 clean 操作。而使用了聚合之后就可以批量进行 Maven 工程的安装、清理工作。
在总的聚合工程中使用 modules/module 标签组合,指定模块工程的相对路径即可。
1 | <modules> |
4. Maven安装与使用
1. 下载
在官网中下载maven包,Maven官网
解压,然后将此Maven包放到想放的地方即可。
2. 配环境变量
先去安装java环境变量
(1)新建系统变量:
(2)编辑系统变量:Path,找到Path在环境变量值尾部加入
3. 检测是否安装成功
4. 配置本机仓库地址并搭建阿里云镜像服务
编辑 D:\apache-maven-3.2.2\conf\settings.xml
添加如下标签,设置本机仓库地址(新建RepMaven文件夹)
1 | <localRepository>D:\RepMaven</localRepository> |
配置阿里云镜像服务
1 | <mirrors> |
Maven设置默认使用JDK1.8(Maven版本要高于3.2.2)
在 settings.xml配置文件中,找到 <profiles>
标签
1 | <profile> |
为了方便项目迁移,也可在pom文件中配置
方式1:
1 | <properties> |
方式2:
finalName作用:如果设置就会按照你自己设定的名字(haoransun)作为报名,即 haoransun.war
如果没有设置,打包后的包名,就是 artifactId和version拼接的结果
1 | <build> |
5. SpringBoot项目maven打包指定mainclass
1. pom中引用springboot-maven插件
1 | <plugin> |
2. 到项目根目录下,执行命令:mvn clean package
,即先clean清除target目录下已经存在的jar或war或其他文件,然后package打包形成 jar 或 war,但不 install到本地maven库里。
6. pom.xml文件中的build配置
Maven是通过pom.xml来执行任务的,其中的build标签描述了如何来编译及打包项目,而具体的编译和打包工作是通过build中配置的 plugin 来完成。当然plugin配置不是必须的,默认情况下,Maven 会绑定默认插件来完成基本操作。
在没有配置的情况下,执行 mvn clean install
时,maven会调用默认的plugin来完成编译打包操作,具体来讲,执行mvn clean install
时会执行
1 | maven-clean-plugin:3.2:clean (default-clean) |
如果有需要可以针对各个 plugin 进行特殊配置,需要在pom.xml中的 <plugins>
标签中显示指定 plugin 和 属性配置。
如:配置 maven-compiler-plugin的版本和编译时使用的jdk版本
1 | <build> |
5. jar服务器运行姿势
1. 推荐服务器run方式:(=前后不能有空格)
[root@haoransun src]# nohup java -jar -Dserver.port=8888 demo-0.0.1-SNAPSHOT.jar >config.log 2>&1 &2. 服务器后台运行,日志过多?
SpringBoot 打成的可执行jar包,想要在服务器上运行,只需要服务器有jdk即可。(SpringBoot自带Tomcat)
1 | java -jar ***.jar 即可 |
仅仅如上面运行jar吗,关掉了xshell等页面,程序就会停掉。因此需要使用nohup对它进行后台运行。
1 | nohup java -jar ***.jar & 即可 |
可以在运行时指很多参数,如端口号等等。基本上在配置文件配置的参数都可以指定
1 | nohup java -jar ***.jar --server.port=9090 & |
上面的程序会默认将日志打印到所在目录的nohup.out文件中。一个定时任务甚至会产生上百G的日志。我们可以指定只打印不同级别的日志。也可以利用Linux的黑洞,/dev/null
1 | nohup java -jar ***.jar --server.port=9090 > /dev/null 2>&1 |
&:代表在后台运行,当前ssh不会被锁定,当窗口关闭时,程序终止运行
nohup:不挂断运行,即使终端关闭,程序仍然运行
3. Shell 脚本—-/dev/null 2>&1 详解
- 1 可以将/dev/null 看做“黑洞”,他等价于一个只写文件,所有写入它的文件都会永远丢失。而从他那读取内容则什么也没有,然而,/dev/null 对命令行和脚本都非常有用。
禁止标准输出: 1 cat $filename>/dev/null #文件内容丢失,而不会输出的标准输出。
禁止标准错误: 2>/dev/null 错误信息被丢到了太平洋。
- 2 1>/dev/null 2>&1含义
> 代表重定向到哪里,例如:echo “123” > /home/123.txt
1 表示stdout标准输出,系统默认值是1,所以”>/dev/null”等同于”1>/dev/null”
2 表示stderr标准错误
& 表示等同于的意思,2>&1,表示2的输出重定向等同于1
因此,大意就是:
1>/dev/null 首先表示标准输出重定向到空设备文件,也就是不输出任何信息到终端,说白了就是不显示任何信息。
2>&1 接着,标准错误输出重定向等同于 标准输出,因为之前标准输出已经重定向到了空设备文件,所以标准错误输出也重定向到空设备文件。
- 3 /dev/zero文件代表一个永远输出 0的设备文件,使用它作输入可以得到全为空的文件。因此可用来创建新文件和以覆盖的方式清除旧文件。
下面使用dd命令将从zero设备中创建一个10K大小(bs决定每次读写1024字节,count定义读写次数为10次),但内容全为0的文件。
dd if=/dev/zero of=file count=10 bs=1024
最常用的方式有:
command > file 2>file 与command > file 2>&1
首先command > file 2>file 的意思是将命令所产生的标准输出信息,和错误的输出信息送到file 中
command > file 2>file 这样的写法,stdout和stderr都直接送到file中, file会被打开两次,这样stdout和stderr会互相覆盖,这样写相当使用了FD1和FD2两个同时去抢占file 的管道。
而command >file 2>&1 这条命令就将stdout直接送向file, stderr 继承了FD1管道后,再被送往file,此时,file 只被打开了一次,也只使用了一个管道FD1,它包括了stdout和stderr的内容。
从IO效率上,前一条命令的效率要比后面一条的命令效率要低,所以在编写shell脚本的时候,较多的时候我们会command > file 2>&1 这样的写法。
总有三个文件处于打开状态:0:标准输入 1:标准输出 2:标准错误
4. Maven中SprintBoot构建Jar包
需要依赖 spring-boot-maven-plugin插件,并且指定 mainClass,如下图例子
6. Maven常用命令
mvn dependency :tree 打印依赖树
mvn dependency :tree -Dverbose 显示详情
mvn dependency :analyze 分析依赖
生命周期
- 清理-编译-测试-打包-安装-部署
- mvn clean
- mvn install
- mvn package
- 跳过测试并安装 mvn install -Dmaven.test.skip=true