文章目录
- 1、什么是MAVEN
- 2、Maven模型
- 3、Maven仓库
- 4、项目集成
- 1_Idea集成Maven设置
- 2_创建Maven项目
- 3_POM配置详解
- 4_maven 坐标详情
- 5_Maven工程类型
- 6_导入Maven项目
- 5、依赖管理
- 1_依赖配置
- 2_依赖传递
- 3_可选依赖
- 4_排除依赖
- 4_可选依赖和排除依赖的区别
- 5_依赖范围
- 6_继承与聚合
- 7_版本锁定
- 8_自定义属性
- 9_生命周期
- 6、分模块开发与设计
- 1_引入
- 2_分模块开发(模块拆分)
- 7、多环境配置与应用
- 1_多环境配置作用
- 2_多环境配置步骤
- 8、插件
- 1_编译器插件
- 2_资源拷贝插件
- 3_tomcat插件
- 9、私服搭建
- 1_私服介绍
- 2_Nexus安装与启动
- 3_私服资源操作流程分析
- 4_私服仓库分类
- 5_资源上传与下载
- 10、附录
- 1_更新依赖索引
- 2_版本管理
- 3_清理maven仓库
- 4_跳过测试(了解)
1、什么是MAVEN
M a v e n Maven Maven 是 A p a c h e Apache Apache 旗下的一个开源项目,是一款用于管理和构建项目的工具,它基于项目对象模型(Project Object Model,简称: POM) 的概念,通过一小段描述信息来管理项目的构建、报告和文档。
官网:https://maven.apache.org/
Apache 软件基金会,成立于1999年7月,是目前世界上最大的最受欢迎的开源软件基金会,也是一个专门为支持开源项目而生的非盈利性组织。
开源项目:https://www.apache.org/index.html#projects-list
使用 M a v e n Maven Maven 能够做什么呢?
- 依赖管理
- 统一项目结构
- 项目构建
依赖管理:
- 方便快捷的管理项目依赖的资源(jar包),避免版本冲突问题
当使用 m a v e n maven maven 进行项目依赖(jar包)管理,则很方便的可以解决这个问题。
我们只需要在
m
a
v
e
n
maven
maven项目的pom.xml
文件中,添加一段如下图所示的配置即可实现。
统一项目结构 :
- 提供标准、统一的项目结构
在项目开发中,当你使用不同的开发工具 (如: E c l i p s e Eclipse Eclipse、 I d e a Idea Idea),创建项目工程时会有自己的工程结构。
若我们创建的是一个 m a v e n maven maven工程,是可以帮我们自动生成统一、标准的项目目录结构
具体的统一结构如下:
目录说明:
src/main/java
: java源代码目录src/main/resources
: 配置文件信息src/test/java
: 测试代码src/test/resources
: 测试配置文件信息
项目构建 :
- m a v e n maven maven 提供了标准的、跨平台(Linux、Windows、MacOS) 的自动化项目构建方式
如上图所示我们开发了一套系统,代码需要进行编译、测试、打包、发布,这些操作如果需要反复进行就显得特别麻烦,而 M a v e n Maven Maven提供了一套简单的命令来完成项目构建。
综上所述,可以得到一个结论: M a v e n Maven Maven是一款管理和构建 j a v a java java项目的工具。
2、Maven模型
在 M a v e n Maven Maven 中每个项目都相当于是一个对象,对象(项目)和对象(项目)之间是有关系的。
关系包含了:依赖、继承、聚合,实现 M a v e n Maven Maven 项目可以更加方便的实现导jar包、拆分项目等效果。
- 项目对象模型 (Project Object Model)
- 依赖管理模型(Dependency)
- 构建生命周期/阶段(Build lifecycle & phases)
1). 构建生命周期/阶段(Build lifecycle & phases)
以上图中紫色框起来的部分,就是用来完成标准化构建流程 。
当我们需要编译, M a v e n Maven Maven 提供了一个编译插件供我们使用;当我们需要打包, M a v e n Maven Maven 就提供了一个打包插件供我们使用等。
2). 项目对象模型 (Project Object Model)
以上图中紫色框起来的部分属于项目对象模型,就是将我们自己的项目抽象成一个对象模型,有自己专属的坐标,如下图所示是一个 M a v e n Maven Maven项目:
坐标,就是资源(jar包)的唯一标识,通过坐标可以定位到所需资源(jar包)位置
3). 依赖管理模型(Dependency)
以上图中紫色框起来的部分属于依赖管理模型,是使用坐标来描述当前项目依赖哪些第三方jar包
之前我们项目中需要jar包时,直接就把jar包复制到项目下的lib目录,而现在书写在pom.xml
文件中的坐标又是怎么能找到所要的jar包文件的呢?
答案: M a v e n Maven Maven 仓库
3、Maven仓库
仓库: M a v e n Maven Maven仓库是基于简单文件系统存储的,集中化管理 J a v a A P I Java API JavaAPI资源(构件)的一个服务。
M a v e n Maven Maven 可以在某个位置统一存储所有的 M a v e n Maven Maven 项目共享的构件,这个统一的位置就是仓库,项目构建完毕后生成的构件也可以安装或者部署到仓库中,供其它项目使用。
仓库中的任何一个构件都有其唯一的坐标,根据这个坐标可以定义其在仓库中的唯一存储路径。
仓库的本质就是一个目录(文件夹),这个目录被用来存储开发中所有依赖(就是jar包)和插件
得益于 M a v e n Maven Maven 的坐标机制,任何 M a v e n Maven Maven项目使用任何一个构件的方式都是完全相同的。
M a v e n Maven Maven 仓库分为:
-
本地仓库: 自己计算机上的一个目录(用来存储jar包)。
-
中央仓库: 由 M a v e n Maven Maven 团队维护的全球唯一的,仓库地址:https://mvnrepository.com/。
-
远程仓库(私服): 一般由公司团队搭建的私有仓库。
当项目中使用坐标引入对应依赖jar包后,首先会查找本地仓库中是否有对应的jar包
-
如果有,则在项目直接引用
-
如果没有,则去中央仓库中下载对应的jar包到本地仓库
如果搭建远程仓库(私服),可以将jar包的查找顺序则变为:本地仓库 --> 远程仓库–> 中央仓库
下载地址: https://maven.apache.org/download.cgi。
配置流程:
-
解压安装
建议解压到没有中文、特殊字符的路径下。
解压缩后的目录结构如下:
- bin目录: 存放的是可执行命令。(mvn 命令重点关注)
- conf目录: 存放Maven的配置文件。(
settings.xml
配置文件后期需要修改) - lib目录: 存放Maven依赖的jar包。( M a v e n Maven Maven 也是使用 j a v a java java开发的,所以它也依赖其他的jar包)
-
配置仓库
在自己计算机上新一个目录(本地仓库,用来存储jar包)
打开
conf/settings.xml
文件:本地仓库:
<?xml version="1.0" encoding="UTF-8"?> <settings xmlns="http://maven.apache.org/SETTINGS/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd"> <!-- 本地仓库配置 --> <localRepository>具体本地仓库位置</localRepository> <!-- 省略,具体信息参考后续内容。 --> </settings>
远程镜像仓库:
<mirror> <!-- 指定镜像ID(可自己改名) --> <id>alimaven</id> <!-- 匹配中央仓库(阿里云的仓库名称,不可以自己起名,必须这么写)--> <mirrorOf>central</mirrorOf> <!-- 指定镜像名称(可自己改名) --> <name>Maven aliyun</name> <!-- 指定镜像路径(镜像地址) --> <url>http://maven.aliyun.com/nexus/content/groups/public</url> </mirror>
注: 只可配置一个(另一个要注释!) ,不然两个可能发生冲突,导致jar包无法下载!!!
-
配置 M a v e n Maven Maven环境变量
M a v e n Maven Maven环境变量的配置类似于 J D K JDK JDK环境变量配置一样
1). 在系统变量处新建一个变量MAVEN_HOME
- MAVEN_HOME 环境变量的值,设置为
m
a
v
e
n
maven
maven 的解压安装目录
2). 在Path中进行配置
- PATH环境变量的值,设置为:
%MAVEN_HOME%\bin
3). 打开DOS命令提示符进行验证,出现如图所示表示安装成功
mvn -v
- MAVEN_HOME 环境变量的值,设置为
m
a
v
e
n
maven
maven 的解压安装目录
4、项目集成
1_Idea集成Maven设置
Maven home path :指定当前 M a v e n Maven Maven的安装目录
User settings file :指定当前 M a v e n Maven Maven的
settings.xml
配置文件的存放路径Local repository :指定 M a v e n Maven Maven 的本地仓库的路径 (如果指定了
settings.xml
,这个目录会自动读取出来,可以不用手动指定)
上述配置的 m a v e n maven maven环境,如果在项目中配置只是针对于当前工程的,如果我们再创建一个project,又恢复成默认的配置了。 要解决这个问题, 我们就需要配置全局的 m a v e n maven maven环境。
进入到IDEA欢迎页面,打开 All settings
,选择 Build,Execution,Deployment => Build Tools => Maven
这里所设置的 m a v e n maven maven的环境信息,并未指定任何一个 project,此时设置的信息就属于全局配置信息。
以后,我们再创建 project,默认就是使用我们全局配置的信息。
2_创建Maven项目
1、创建一个空项目
2、创建模块,选择 M a v e n Maven Maven,点击Next。
3、填写模块名称,坐标信息,点击create
,创建完成。
- M a v e n Maven Maven 项目的目录结构:
project-maven
|— src (源代码目录和测试代码目录)
|— main (源代码目录)
|— java (源代码java文件目录)
|— resources (源代码配置文件目录)
|— test (测试代码目录)
|— java (测试代码java目录)
|— resources (测试代码配置文件目录)
|— target (编译、打包生成文件存放目录)
4、编写 HelloWorld,并运行
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello Maven ...");
}
}
3_POM配置详解
P
O
M
POM
POM (Project Object Model) :指的是项目对象模型,用来描述当前的maven
项目。
- 使用
pom.xml
文件来实现
pom.xml
文件:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<!-- POM模型版本 -->
<modelVersion>4.0.0</modelVersion>
<!-- 当前项目坐标 -->
<groupId>com.example</groupId>
<artifactId>maven_project1</artifactId>
<version>1.0-SNAPSHOT</version>
<!-- 打包方式 -->
<packaging>jar</packaging>
</project>
pom文件详解:
<project>
: p o m pom pom文件的根标签,表示当前 m a v e n maven maven项目<modelVersion>
:声明项目描述遵循哪一个 P O M POM POM 模型版本- 虽然模型本身的版本很少改变,但它仍然是必不可少的(目前
P
O
M
POM
POM 模型版本是
4.0.0
)。
- 虽然模型本身的版本很少改变,但它仍然是必不可少的(目前
P
O
M
POM
POM 模型版本是
- 坐标 :
<groupId>
、<artifactId>
、<version>
- 定位项目在本地仓库中的位置,由以上三个标签组成一个坐标
<packaging>
:maven项目的打包方式,通常设置为jar或war(默认值:jar)
4_maven 坐标详情
什么是坐标?
- M a v e n Maven Maven 中的坐标是资源的唯一标识,通过该坐标可以唯一定位资源位置
- 使用坐标来定义项目或引入项目中需要的依赖
M a v e n Maven Maven坐标主要组成
- groupId:定义当前
M
a
v
e
n
Maven
Maven项目隶属组织名称(通常是域名反写,例如:
com.github
) - artifactId:定义当前
M
a
v
e
n
Maven
Maven项目名称(通常是模块名称,例如
order-service
、goods-service
) - version:定义当前项目版本号 1.0-SNAPSHOT (快照版)
注意:
- 上面所说的资源可以是插件、依赖、当前项目。
- 我们的项目如果被其他的项目依赖时,也是需要坐标来引入的。
5_Maven工程类型
1、POM工程
- POM工程是逻辑工程。用在父级工程或聚合工程中。用来做jar包的版本控制。
2、JAR工程
- 将会打包成jar,用作jar包使用。即常见的本地工程 —> Java Project。
3、WAR工程
- 将会打包成war,发布在服务器上的工程。
6_导入Maven项目
- 方式1:使用Maven面板,快速导入项目
打开IDEA,选择右侧
M
a
v
e
n
Maven
Maven 面板,点击 + 号,选中对应项目的pom.xml
文件,双击即可
说明:如果没有 M a v e n Maven Maven 面板,选择
View => Appearance => Tool Window Bars
。
- 方式2:使用idea导入模块项目
File => Project Structure => Modules => + => Import Module
找到要导入工程的pom.xml
。
5、依赖管理
1_依赖配置
依赖:指当前项目运行所需要的jar包。一个项目中可以引入多个依赖:
例如:在当前工程中,我们需要用到logback
来记录日志,此时就可以在
m
a
v
e
n
maven
maven工程的pom.xml
文件中,引入logback 的依赖。具体步骤如下:
-
在
pom.xml
中编写<dependencies>
标签 -
在
<dependencies>
标签中使用<dependency>
引入坐标 -
定义坐标的
groupId
、artifactId
、version
<dependencies>
<!-- 第1个依赖 : logback -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.11</version>
</dependency>
<!-- 第2个依赖 : junit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies>
- 点击刷新按钮,引入最新加入的坐标
- 刷新依赖:保证每一次引入新的依赖,或者修改现有的依赖配置,都可以加入最新的坐标
注意事项:
- 如果引入的依赖,在本地仓库中不存在,将会连接远程仓库 / 中央仓库,然后下载依赖(这个过程会比较耗时,耐心等待)
- 如果不知道依赖的坐标信息,可以到mvn的中央仓库中搜索
添加依赖的几种方式:
-
利用中央仓库搜索的依赖坐标
-
利用IDEA工具搜索依赖
-
熟练上手 m a v e n maven maven后,快速导入依赖
2_依赖传递
早期我们没有使用 m a v e n maven maven时,向项目中添加依赖的jar包,需要把所有的jar包都复制到项目工程下。
需要logback-classic
时,由于logback-classic
又依赖了logback-core
和slf4j
,所以必须把这3个jar包全部复制到项目工程下。
我们现在使用了
m
a
v
e
n
maven
maven,当项目中需要使用logback-classic
时,只需要在pom.xml
配置文件中,添加logback-classic
的依赖坐标即可。
在pom.xml
文件中只添加了logback-classic
依赖,但由于maven的依赖具有传递性,所以会自动把所依赖的其他jar包也一起导入。
传递性依赖是Maven2.0的特性。
假设你的项目依赖于一个库,而这个库又依赖于其他库。
你不必自己去找出所有这些依赖,你只需要加上你直接依赖的库, M a v e n Maven Maven会隐式的把这些库间接依赖的库也加入到你的项目中。
这个特性是靠解析从远程仓库中获取的依赖库的项目文件实现的。
一般的,这些项目的所有依赖都会加入到项目中,或者从父项目继承,或者通过传递性依赖。
如果A依赖了B,那么C依赖A时会自动把A和B都导入进来。
依赖传递可以分为:
-
直接依赖: 在当前项目中通过依赖配置建立的依赖关系
-
间接依赖: 被依赖的资源如果依赖其他资源,当前项目间接依赖其他资源
比如以上图中:
- projectA依赖了projectB。对于projectA 来说,projectB 就是直接依赖。
- 而projectB依赖了projectC及其他jar包。 那么此时,在projectA中也会将projectC的依赖传递下来。对于projectA 来说,projectC就是间接依赖。
3_可选依赖
A依赖B,B依赖C,如果A不想将C依赖进来,是否可以做到?
- 可选依赖指对外隐藏当前所依赖的资源————不透明。
<dependency>
<groupId>com.example</groupId>
<artifactId>maven_pojo</artifactId>
<version>1.0-SNAPSHOT</version>
<!--可选依赖是隐藏当前工程所依赖的资源,隐藏后对应资源将不具有依赖传递性-->
<optional>false</optional>
</dependency>
4_排除依赖
问题:之前我们讲了依赖具有传递性。那么A依赖B,B依赖C,如果A不想将C依赖进来,是否可以做到?
答案:在 m a v e n maven maven项目中,我们可以通过排除依赖来实现。
什么是排除依赖?
- 排除依赖:指主动断开依赖的资源。(被排除的资源无需指定版本)
<dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>1.5.6</version> <!--排除依赖, 主动断开依赖的资源--> <exclusions> <exclusion> <groupId>ch.qos.logback</groupId> <artifactId>logback-core</artifactId> </exclusion> </exclusions> </dependency>
依赖排除示例:
- 使用之前:
-
排除了
logback-classic
所依赖的logback-core
。
exclusions: 用来排除传递性依赖 其中可配置多个exclusion
标签,每个exclusion
标签里面对应的有groupId
,artifactId
,version
三项基本元素。注意:不用写版本号。
4_可选依赖和排除依赖的区别
5_依赖范围
在项目中导入依赖的jar包后,默认情况下,可以在任何地方使用。
如果希望限制依赖的使用范围,可以通过<scope>
标签设置其作用范围。
作用范围:
-
主程序范围有效(main 文件夹范围内)
-
测试程序范围有效(test 文件夹范围内)
-
是否参与打包运行(package 指令范围内)
scope 标签的取值范围:
scope值 | 主程序 | 测试程序 | 打包(运行) | 范例 |
---|---|---|---|---|
compile(默认) | Y | Y | Y | log4j |
test | - | Y | - | junit |
provided | Y | Y | - | servlet-api |
runtime | - | Y | Y | jdbc 驱动 |
system | Y | - | - | 本地系统库 |
import | - | - | - | BOM (Bill of Materials) |
annotation | Y | Y | Y | Lombok |
说明:
❀compile:这是默认范围。如果没有指定,就会使用该依赖范围。表示该依赖在编译和运行时都生效。
❀provided:已提供依赖范围。使用此依赖范围的
M
a
v
e
n
Maven
Maven依赖。典型的例子是servlet-api
,编译和测试项目的时候需要该依赖,但在运行项目的时候,由于容器已经提供,就不需要
M
a
v
e
n
Maven
Maven重复地引入一遍(如:servlet-api
)
❀runtime:runtime 范围表明编译时不需要生效,而只在运行时生效。典型的例子是 J D B C JDBC JDBC驱动实现,项目主代码的编译只需要 J D K JDK JDK提供的 J D B C JDBC JDBC接口,只有在执行测试或者运行项目的时候才需要实现上述接口的具体 J D B C JDBC JDBC驱动。
❀system:系统范围与provided
类似,不过你必须显式指定一个本地系统路径的JAR,此类依赖应该一直有效,
M
a
v
e
n
Maven
Maven 也不会去仓库中寻找它。但是,使用system
范围依赖时必须通过systemPath
元素显式地指定依赖文件的路径。
❀test:test范围表明使用此依赖范围的依赖,只在编译测试代码和运行测试的时候需要,应用的正常运行不需要此类依赖。典型的例子就是JUnit,它只有在编译测试代码及运行测试的时候才需要。Junit的jar包就在测试阶段用就行了,你导出项目的时候没有必要把junit
的东西到处去了就,所在在junit
坐标下加入scope-test
>
❀Import:import
范围只适用于pom文件中的<dependencyManagement>
部分。表明指定的
P
O
M
POM
POM 必须使用<dependencyManagement>
部分的依赖。注意:import只能用在dependencyManagement的scope里。
6_继承与聚合
继承关系:
如果A工程继承B工程,则代表A工程默认依赖B工程依赖的所有资源,且可以应用B工程中定义的所有资源信息。
被继承的工程(B工程)只能是 P O M POM POM工程(建议父工程打包方式设置为 p o m pom pom)。
<packaging>pom</packaging>
在父工程的 p o m pom pom文件中配置依赖关系(子工程将沿用父工程中的依赖关系)
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.10.RELEASE</version>
</dependency>
……
</dependencies>
配置子工程中可选的依赖关系
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.16</version>
</dependency>
……
</dependencies>
</dependencyManagement>
在子工程中配置当前工程所继承的父工程
<!--定义该工程的父工程-->
<parent>
<groupId>com.example</groupId>
<artifactId>maven_parent</artifactId>
<version>1.0-SNAPSHOT</version>
<!--填写父工程的pom文件,根据实际情况填写-->
<relativePath>../maven_parent/pom.xml</relativePath>
</parent>
在子工程中配置使用父工程中可选依赖的坐标
<dependencies>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
</dependency>
</dependencies>
注意:
-
在父项目中放在
<dependencyManagement>
中的内容时不被子项目继承,不可以直接使用。 -
放在
<dependencyManagement>
中的内容主要目的是进行版本管理。 -
里面的内容在子项目中依赖时坐标只需要填写
<group id>
和<artifact id>
即可(注意:如果子项目不希望使用父项目的版本,可以明确配置version)。 -
子工程中还可以定义父工程中没有定义的依赖关系
作用:
- 简化配置
- 减少版本冲突
聚合关系:
当我们开发的工程拥有2个以上模块的时候,每个模块都是一个独立的功能集合。
比如某大学系统中拥有搜索平台,学习平台,考试平台等。
开发的时候每个平台都可以独立编译,测试,运行。这个时候我们就需要一个聚合工程。
在创建聚合工程的过程中,总的工程必须是一个 P O M POM POM工程(Maven Project)(聚合项目必须是一个pom类型的项目,jar项目、war项目是没有办法做聚合工程的),各子模块可以是任意类型模块(Maven Module)。
<packaging>pom</packaging>
前提:继承。
聚合包含了继承的特性。
聚合时多个项目的本质还是一个项目,这些项目被一个大的父项目包含,且这时父项目类型为 p o m pom pom类型。
同时在父项目的pom.xml
中出现<modules>
表示包含的所有子模块。
<modules>
<module>../maven_entity</module>
<module>../maven_pojo</module>
<module>../maven_dao</module>
</modules>
总项目:一般总项目: P O M POM POM 项目。
-
聚合工程:通常是一个不具有业务功能的”空“工程(有且仅有一个 p o m pom pom文件)
-
作用:使用聚合工程可以将多个工程编组,通过对聚合工程进行构建,实现对所包含的模块进行同步构建
- 当工程中某个模块发生更新(变更)时,必须保障工程中与已更新模块关联的模块同步更新,此时可以使用聚合工程来解决批量模块同步构建的问题
聚合和继承的作用?
- 作用
- 聚合用于快速构建项目
- 继承用于快速配置
- 相同点:
- 聚合与继承的
pom.xml
文件打包方式均为 p o m pom pom,可以将两种关系制作到同一个 p o m pom pom文件中 - 聚合与继承均属于设计型模块,并无实际的模块内容
- 聚合与继承的
- 不同点:
- 聚合是在当前模块中配置关系,聚合可以感知到参与聚合的模块有哪些
- 继承是在子模块中配置关系,父模块无法感知哪些子模块继承了自己
7_版本锁定
如果项目中各个模块中都公共的这部分依赖,我们可以直接定义在父工程中,从而简化子工程的配置。 然而在项目开发中,还有一部分依赖,并不是各个模块都共有的,可能只是其中的一小部分模块中使用到了这个依赖。
而由于是一个项目中的多个模块,那多个模块中,我们要使用的同一个依赖的版本要一致,这样便于项目依赖的统一管理。比如:这个jwt
依赖,我们多个模块都使用的是 0.9.1
这个版本。
那假如说,我们项目要升级,要使用到jwt
最新版本 0.9.2
中的一个新功能,那此时需要将依赖的版本升级到0.9.2
,那此时该怎么做呢 ?
第一步:去找当前项目中所有的模块的pom.xml
配置文件,看哪些模块用到了jwt
的依赖。
第二步:找到这个依赖之后,将其版本version
,更换为 0.9.2
。
问题:如果项目拆分的模块比较多,每一次更换版本,我们都得找到这个项目中的每一个模块,一个一个的更改。 很容易就会出现,遗漏掉一个模块,忘记更换版本的情况。
那我们又该如何来解决这个问题,如何来统一管理各个依赖的版本呢?
答案: M a v e n Maven Maven 的版本锁定功能。
在
m
a
v
e
n
maven
maven中,可以在父工程的
p
o
m
pom
pom文件中通过 <dependencyManagement>
来统一管理依赖版本。
父工程:
<!--统一管理依赖版本-->
<dependencyManagement>
<dependencies>
<!--JWT令牌-->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
</dependencies>
</dependencyManagement>
子工程:
<dependencies>
<!--JWT令牌-->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
</dependency>
</dependencies>
注意:
在父工程中所配置的
<dependencyManagement>
只能统一管理依赖版本,并不会将这个依赖直接引入进来。 这点和<dependencies>
是不同的。子工程要使用这个依赖,还是需要引入的,只是此时就无需指定
<version>
版本号了,父工程统一管理。变更依赖版本,只需在父工程中统一变更。
8_自定义属性
我们也可以通过自定义属性及属性引用的形式,在父工程中将依赖的版本号进行集中管理维护。 具体语法为:
①:定义属性
<properties>
<lombok.version>1.18.24</lombok.version>
</properties>
②:引用属性
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</dependency>
接下来,我们就可以在父工程中,将所有的版本号,都集中管理维护起来。
版本集中管理之后,我们要想修改依赖的版本,就只需要在父工程中自定义属性的位置,修改对应的属性值即可。
资源文件引用属性
①:定义属性
<!--定义自定义属性-->
<properties>
<spring.version>5.2.10.RELEASE</spring.version>
<junit.version>4.12</junit.version>
<jdbc.url>jdbc:mysql://127.0.0.1:3306/ssm_db</jdbc.url>
</properties>
②:配置文件中引用属性
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=${jdbc.url}
jdbc.username=root
jdbc.password=root
③:开启资源文件目录加载属性的过滤器
<build>
<resources>
<resource>
<directory>${project.basedir}/src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</build>
④:配置
m
a
v
e
n
maven
maven打
w
a
r
war
war包时,忽略web.xml
检查
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.2.3</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
其他属性(了解)
- 属性列表
- 自定义属性(常用)
- 内置属性
- Setting属性
- Java系统属性
- 环境变量属性
属性分类 | 引用格式 | 示例 |
---|---|---|
自定义属性 | ${自定义属性名} | ${spring.version} |
内置属性 | ${内置属性名} | ${basedir} ${version} |
Setting属性 | ${setting.属性名} | ${settings.localRepository} |
Java系统属性 | ${系统属性分类.系统属性名} | ${user.home} |
环境变量属性 | ${env.环境变量属性名} | ${env.JAVA_HOME} |
9_生命周期
M a v e n Maven Maven 的生命周期就是为了对所有的构建过程进行抽象和统一。 描述了一次项目构建,经历哪些阶段。
在 M a v e n Maven Maven出现之前,项目构建的生命周期就已经存在,软件开发人员每天都在对项目进行清理,编译,测试及部署。虽然大家都在不停地做构建工作,但公司和公司间、项目和项目间,往往使用不同的方式做类似的工作。
M a v e n Maven Maven从大量项目和构建工具中学习和反思,然后总结了一套高度完美的,易扩展的项目构建生命周期。这个生命周期包含了项目的清理,初始化,编译,测试,打包,集成测试,验证,部署和站点生成等几乎所有构建步骤。
M a v e n Maven Maven对项目构建的生命周期划分为3套(相互独立):
-
clean: 清理工作。
-
default: 核心工作。如:编译、测试、打包、安装、部署等。
-
site: 生成报告、发布站点等。
三套生命周期又包含哪些具体的阶段呢, 我们来看下面这幅图:
我们看到这三套生命周期,里面有很多很多的阶段,这么多生命周期阶段,其实我们常用的并不多,主要关注以下几个:
-
clean: 移除上一次构建生成的文件
-
compile: 编译项目源代码,
javac
命令。 -
test: 使用合适的单元测试框架运行测试(
junit
) -
package: 将编译后的文件打包,如:
jar
、war
等 -
install: 包含编译,打包,安装项目到本地仓库
M a v e n Maven Maven 的生命周期是抽象的,这意味着生命周期本身不做任何实际工作,在Maven的设计中,实际任务(如源代码编译)都交由插件来完成。
IDEA工具为了方便程序员使用 m a v e n maven maven生命周期,在右侧的 m a v e n maven maven工具栏中,已给出快速访问通道
生命周期的顺序是:clean --> validate --> compile --> test --> package --> verify --> install --> site --> deploy
我们需要关注的就是:clean --> compile --> test --> package --> install
说明:在同一套生命周期中,我们在执行后面的生命周期时,前面的生命周期都会执行。
思考:当运行
package
生命周期时,clean
、compile
生命周期会不会运行?
clean
不会运行,compile
会运行。 因为compile
与package
属于同一套生命周期,而clean
与package
不属于同一套生命周期。
在日常开发中,当我们要执行指定的生命周期时,有两种执行方式:
- 在idea工具右侧的 m a v e n maven maven工具栏中,选择对应的生命周期,双击执行
- 在DOS命令行中,通过 m a v e n maven maven命令执行
方式一:在idea中执行生命周期
-
选择对应的生命周期,双击执行
方式二:在命令行中执行生命周期
- 进入到DOS命令行
6、分模块开发与设计
1_引入
问题导入
分模块开发对工程有什么好处?
模块拆分原则
目的:项目的扩展性变强了,方便其他项目引用相同的功能。
将原始模块按照功能拆分成若干个子模块,方便模块间的相互调用、接口共享,项目的管理维护、拓展。
2_分模块开发(模块拆分)
问题导入
一个完整的工程依据什么来进行模块的拆分?
-
创建 M a v e n Maven Maven模块
-
书写模块代码
注意事项:
- 分模块开发需要先针对模块功能进行设计,再进行编码。不会先将工程开发完毕,然后进行拆分
-
通过 m a v e n maven maven指令安装模块到本地仓库( i n s t a l l install install指令)
mvn install
注意事项:
- 团队内部开发需要发布模块功能到团队内部可共享的仓库中(私服)
7、多环境配置与应用
1_多环境配置作用
问题导入
多环境配置有什么好处?
- m a v e n maven maven提供配置多种环境的设定,帮助开发者使用过程中快速切换环境
2_多环境配置步骤
1.定义多环境
<!--定义多环境-->
<profiles>
<!--定义具体的环境:生产环境-->
<profile>
<!--定义环境对应的唯一名称-->
<id>env_dep</id>
<!--定义环境中专用的属性值-->
<properties>
<jdbc.url>jdbc:mysql://127.0.0.1:3306/ssm_db</jdbc.url>
</properties>
<!--设置默认启动-->
<activation>
<activeByDefault>true</activeByDefault>
</activation>
</profile>
<!--定义具体的环境:开发环境-->
<profile>
<id>env_pro</id>
……
</profile>
</profiles>
2.使用多环境(构建过程)
【命令格式】:mvn 指令 –P 环境定义id
。
【范例】:
mvn install –P env_pro
8、插件
1_编译器插件
通过编译器插件,我们可以配置使用的 J D K JDK JDK或者编译器的版本:
1、settings.xml
文件中配置全局编译器插件:
找到profiles
节点,在里面加入profile
节点:
<profile>
<!-- 定义的编译器插件ID,全局唯一,名字随便起 -->
<id>jdk-1.8</id>
<!-- 插件标记,activeByDefault :true默认编译器,jdk提供编译器版本 -->
<activation>
<activeByDefault>true</activeByDefault>
<jdk>1.8</jdk>
</activation>
<!-- 配置信息source-源信息,target-字节码信息,compilerVersion-编译过程版本 -->
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion>
</properties>
</profile>
2、配置编译器插件:pom.xml
配置片段
<!-- 配置maven的编译插件 -->
<build>
<plugins>
<!--JDK编译插件 -->
<plugin>
<!--插件坐标 -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.2</version>
<!-- -->
<configuration>
<!-- 源代码使用JDK版本-->
<source>1.7</source>
<!-- 源代码编译为class文件的版本,要保持跟上面版本一致-->
<target>1.7</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
</plugins>
</build>
2_资源拷贝插件
M
a
v
e
n
Maven
Maven 在打包时默认只将src/main/resources
里的配置文件拷贝到项目中并做打包处理,而非resource目录下的配置文件在打包时不会添加到项目中。
我们的配置文件,一般都放在:src/main/resources
。
然后打包后配置文件就会在target的classes下面放着:
测试:
我现在想把非resources下面的文件也打包到classes
下面:
需要配置:
pom.xml
配置片段:
<build>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.xml</include>
<include>**/*.properties</include>
</includes>
</resource>
</resources>
</build>
配置好以后,那么你设置的位置下的配置文件都会被打包了:
3_tomcat插件
我们如果创建war项目,必然要部署在服务器上,方式:
-
部署在远程服务器上
-
将IDEA和外部 t o m c a t tomcat tomcat产生关联,然后将项目部署在外部 t o m c a t tomcat tomcat上
现在学习一个新的方式,不再依赖外部的 t o m c a t tomcat tomcat, m a v e n maven maven提供了 t o m c a t tomcat tomcat插件,我们可以配置来使用。
创建web项目—war项目:
在index.jsp
中随便写点东西:
使用
T
o
m
c
a
t
Tomcat
Tomcat插件发布部署并执行war工程的时候,需要使用启动命令,启动命令为: tomcat7:run
。
命令中的tomcat7
是插件命名,由插件提供商决定。run
为插件中的具体功能。
(注意:之前用的编译器插件,资源拷贝插件,不是可运行的插件, m a v e n maven maven直接帮我们运行了,但是 t o m c a t tomcat tomcat属于可运行插件,它什么时候工作需要程序员来控制,怎么控制呢?我们必须通过命令来运行控制)
具体pom.xml
文件的配置如下:
<build>
<finalName>maven_war_pro</finalName>
<plugins>
<!-- 配置Tomcat插件 -->
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<configuration>
<!-- 配置Tomcat监听端口 -->
<port>8080</port>
<!-- 配置项目的访问路径(Application Context) -->
<path>/</path>
</configuration>
</plugin>
</plugins>
</build>
执行命令:
显示 t o m c a t tomcat tomcat启动成功:
在浏览器中访问index.jsp
页面:
9、私服搭建
1_私服介绍
问题导入
这里的私服和平时我们听的国服、体验服、欧服等等有什么区别?
-
团队开发现状分析
-
私服是一台独立的服务器,用于解决团队内部的资源共享与资源同步问题
-
N e x u s Nexus Nexus
- S o n a t y p e Sonatype Sonatype公司的一款 m a v e n maven maven私服产品
- 下载地址:https://help.sonatype.com/repomanager3/download
2_Nexus安装与启动
-
启动服务器(命令行启动)
nexus.exe /run nexus
-
访问服务器(默认端口:8081)
- http://localhost:8081
-
修改基础配置信息
- 安装路径下
etc
目录中nexus-default.properties
文件保存有 n e x u s nexus nexus基础配置信息,例如默认访问端口。
- 安装路径下
-
修改服务器运行配置信息
- 安装路径下bin目录中
nexus.vmoptions
文件保存有 n e x u s nexus nexus服务器启动对应的配置信息,例如默认占用内存空间。
- 安装路径下bin目录中
3_私服资源操作流程分析
4_私服仓库分类
问题导入
私服仓库分为哪几种?
仓库类别 | 英文名称 | 功能 | 关联操作 |
---|---|---|---|
宿主仓库 | hosted | 保存自主研发+第三方资源 | 上传 |
代理仓库 | proxy | 代理连接中央仓库 | 下载 |
仓库组 | group | 为仓库编组简化下载操作 | 下载 |
5_资源上传与下载
问题导入
往私服上传资源是否需要身份认证?在哪里设置认证信息?
资源上传与下载,我们需要做三步配置,执行一条指令。
第一步配置:在 m a v e n maven maven的配置文件中配置访问私服的用户名、密码。
第二步配置:在
m
a
v
e
n
maven
maven的配置文件中配置连接私服的地址(url
地址)。
第三步配置:在项目的pom.xm
l文件中配置上传资源的位置(url
地址)。
配置好了上述三步之后,要上传资源到私服仓库,就执行执行
m
a
v
e
n
maven
maven生命周期:deploy
。
私服仓库说明:
- RELEASE:存储自己开发的RELEASE发布版本的资源。
- SNAPSHOT:存储自己开发的SNAPSHOT发布版本的资源。
- Central:存储的是从中央仓库下载下来的依赖。
项目版本说明:
- RELEASE(发布版本):功能趋于稳定、当前更新停止,可以用于发行的版本,存储在私服中的RELEASE仓库中。
- SNAPSHOT(快照版本):功能不稳定、尚处于开发中的版本,即快照版本,存储在私服的SNAPSHOT仓库中。
从私服中下载依赖
【第一步】在
m
a
v
e
n
maven
maven的settings.xml
中<mirrors>
标签中配置,此时就需要注释掉aliyun的配置。
<mirror>
<id>nexus-maven</id>
<mirrorOf>*</mirrorOf>
<url>http://localhost:8081/repository/maven-public/</url>
</mirror>
<profile>
<id>allow-snapshots</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<repositories>
<repository>
<id>nexus-mavenc</id>
<url>http://192.168.150.101:8081/repository/nexus-maven/</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
</profile>
【第二步】在 n e x u s nexus nexus中设置允许匿名下载,如果不允许将不会从私服中下载依赖
如果私服中没有对应的jar,会去中央仓库下载,速度很慢。可以配置让私服去阿里云中下载依赖。
上传依赖到私服中
【第一步】配置本地仓库访问私服的权限(在
m
a
v
e
n
maven
maven的settings.xml
的servers
标签中配置)
<server>
<!--id任意,多个server的id不重复就行,后面会用到-->
<id>maven-nexus</id>
<username>admin</username>
<password>123456</password><!--填写自己nexus设定的登录秘密-->
</server>
【第一步】配置当前项目访问私服上传资源的保存位置(项目的pom.xml
文件中配置)
<distributionManagement>
<repository>
<!--和maven/settings.xml中server中的id一致,表示使用该id对应的用户名和密码-->
<id>maven-nexus</id>
<!--如果jar的版本是release版本,那么就上传到这个仓库,根据自己情况修改-->
<url>http://localhost:8081/repository/maven-releases/</url>
</repository>
<snapshotRepository>
<!--和maven/settings.xml中server中的id一致,表示使用该id对应的用户名和密码-->
<id>maven-nexus</id>
<!--如果jar的版本是snapshot版本,那么就上传到这个仓库,根据自己情况修改-->
<url>http://localhost:8081/repository/maven-snapshots/</url>
</snapshotRepository>
</distributionManagement>
注意:要和maven的settings.xml中server中定义的<id>maven-nexus</id>对应
【第三步】发布资源到私服命令
mvn deploy
10、附录
1_更新依赖索引
有时候给idea配置完 m a v e n maven maven仓库信息后,在idea中依然搜索不到仓库中的jar包。
这是因为仓库中的jar包索引尚未更新到idea中。
这个时候我们就需要更新idea中 m a v e n maven maven的索引了,具体做法如下:
打开设置----搜索maven----Repositories----选中本地仓库-----点击Update。
2_版本管理
-
SNAPSHOT(快照版本)
- 项目开发过程中临时输出的版本,称为快照版本
- 快照版本会随着开发的进展不断更新
-
RELEASE(发布版本)
- 项目开发到进入阶段里程碑后,向团队外部发布较为稳定的版本,这种版本所对应的构件文件是稳定的
- 即便进行功能的后续开发,也不会改变当前发布版本内容,这种版本称为发布版本
-
发布版本
- alpha版
- beta版
- 纯数字版
3_清理maven仓库
初始情况下,我们的本地仓库是没有任何jar包的,此时会从私服去下载(如果没有配置,就直接从中央仓库去下载),可能由于网络的原因,jar包下载不完全,这些不完整的jar包都是以lastUpdated结尾。
此时, m a v e n maven maven不会再重新帮你下载,需要你删除这些以lastUpdated结尾的文件,然后 m a v e n maven maven才会再次自动下载这些jar包。
如果本地仓库中有很多这样的以lastUpadted结尾的文件,可以定义一个批处理文件,在其中编写如下脚本来删除:
set REPOSITORY_PATH=E:\develop\apache-maven-3.6.1\mvn_repo
rem 正在搜索...
del /s /q %REPOSITORY_PATH%\*.lastUpdated
rem 搜索完毕
pause
操作步骤如下:
-
定义批处理文件
del_lastUpdated.bat
(直接创建一个文本文件,命名为del_lastUpdated
,后缀名直接改为bat
即可 ) -
在上面的bat文件上右键—》编辑 。修改文件:
修改完毕后,双击运行即可删除 m a v e n maven maven仓库中的残留文件。
4_跳过测试(了解)
问题导入
跳过测试会不会影响项目的构建过程?
应用场景
- 功能更新中并且没有开发完毕
- 快速打包
- ……
跳过测试命令
mvn install –D skipTests
注意事项:
- 执行的项目构建指令必须包含测试生命周期,否则无效果。例如执行
compile
生命周期,不经过test
生命周期。
细粒度控制跳过测试
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.1</version>
<configuration>
<skipTests>true</skipTests>
<!--设置跳过测试-->
<includes>
<!--包含指定的测试用例-->
<include>**/User*Test.java</include>
</includes>
<excludes>
<!--排除指定的测试用例-->
<exclude>**/User*TestCase.java</exclude>
</excludes>
</configuration>
</plugin>