最完整的 Maven 使用指南,尽在这里。
张三最近做了个项目,但是这个项目需要 30 多个 jar包。他只能从网上一个个去下载,下载完还要一个一个手动导入。
好不容易搞完了,结果却发现有些 jar 包版本竟然不兼容,搞了一天也没搞好。真的是“豆腐拌腐乳-越搞越糊涂!。”
经过一个多月的疯狂加班,这个项目终于做好了,张三部署好测试环境之后就交给测试人员李四了。
张三想着终于能好好摸鱼了,谁知道李四工作特认真,一会就测出来一堆 bug。
张三只能立即去更改 bug,改完还要手动编译、打包项目。最多的时候一天打包了十几次,可把张三累坏了。
那如何避免上面的场景呢?Maven 闪亮登场。
1. Maven 简介
Maven 是 Apache 软件基金会旗下一款自动化构建工具,专注于 Java 平台的项目构建和依赖管理。
简单点说 Maven 就是一个好用的工具。我们以前做项目需要自己到网上找 jar 包,而用了 Maven 之后,我们只需要配置一下依赖的坐标,它会自动将 jar 包下载到我们电脑硬盘的某一个目录下。
除了管理 jar 包,它还能帮我们干很多事情:
- 1.自动下载需要的 jar 包,管理 jar 包的版本以及它们之间的依赖关系。
- 2.帮你编译程序
- 3.帮你打包程序
- 4.帮你部署程序
- 5.帮你管理项目中各个模块的关系
名词解释:
依赖: 例如我们的项目中需要 servlet.jar,这个 jar 包就可以叫做依赖,或者说项目依赖 servlet.jar。我们在导入 a.jar 的时候发现还需要导入 b.jar,说明 a.jar 依赖 b.jar。
项目构建: 项目构建描述的是代码的编译、运行、打包、部署等一系列过程。
- 1.项目清理:清理之前编译的代码。
- 2.编译:将程序源代码编译为虚拟机可执行的代码,也就是 class 文件。maven 可以帮我们批量编译一堆代码。
- 3.测试:maven 可以执行测试程序代码,验证你的功能是否正确。
- 4.打包:将所有的 class 文件、配置文件等资源放到一个压缩文件中。 对于 java 程序,压缩文件是 xx.jar,对于 web 应用,压缩文件扩展名是 xx.war。
- 5.安装:将 jar 文件或者 war 文件安装到本机仓库中。
- 6.部署:将程序部署到服务器上,我们可以通过网址进行访问。
2. Maven 的安装和配置
2.1 下载安装
注: Maven 是使用 Java 开发的,所以必须先安装配置 JDK。
Maven 官网:
https://archive.apache.org/dist/maven/maven-3/
将下载完的压缩包解压到一个非中文无空格的目录下:
2.2 配置环境变量
1.新增变量
变量名:MAVEN_HOME
变量值:maven 的安装路径
2.修改 path
增加变量值:%MAVEN_HOME%\bin
3.验证
同时按下 window+R 键,输入 cmd,按下回车键。 然后命令行输入: mvn -v
4.修改配置本地仓库
为什么要修改本地仓库?
因为 Maven 默认的本地仓库在C/用户/.m2 文件夹里,随着下载的 jar 包越来越多,系统盘会越来越满,电脑会越来越卡,所以建议在 C 盘之外建一个本地仓库。
打开 Maven 的核心配置文件 settings.xml
添加如下标签:
<localRepository>你的repository目录</localRepository>
例如:
<localRepository>D:\CodeSoftware\Maven\repository</localRepository>
5.配置阿里云镜像下载地址
因为国外远程仓库下载 jar 包速度慢,国内阿里云下载速度快。
在 setting.xml 文件里面添加:
<mirror>
<id>alimaven</id>
<name>aliyun maven</name>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>;
<mirrorOf>central</mirrorOf>
</mirror>
完整的 setting.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>D:\CodeSoftware\maven\repository</localRepository>
<mirrors>
<mirror>
<id>alimaven</id>
<name>aliyun maven</name>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
<mirrorOf>central</mirrorOf>
</mirror>
</mirrors>
</settings>
3. IDEA 中使用 Maven
3.1 IDEA 中配置 Maven
File -> Settings:
3.2 创建 JAVA 工程
File -> New -> Project
3.3 创建 WEB 工程
File -> New -> Project
这里我们需要使用 Maven 自带的 web 项目模板。
因为使用 Maven 自带的 web 项目模板创建的项目目录不全,所以需要在 main 目录下创建 java 和 resources 目录。
3.4 使用 Maven 工具
当我们在 IDEA 中配置完 Maven 工具之后,IDEA 窗口的右边会出现 Maven 的按钮:
Maven 窗口图标的作用:
4. Maven 的核心概念
4.1 目录结构
maven 中规定的目录结构:
- 1.sms:项目名,也是项目的根路径
- 2.src:项目的源代码
- 3.main:主程序
- 4.java:项目源代码
- 5.rsources:主程序的配置文件
- 6.test:测试代码
- 7.rsources:测试代码的配置文件
- 8.pom.xml:Maven 项目的配置文件
4.2 pom 文件
pom 全称:Project Object Model,即项目对象模型。
Maven 把一个项目的结构和内容抽象成一个模型,在 pom.xml 文件中进行声明和描述。所以说 pom.xml 是 Maven 的核心。
完整的 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">
<parent>
<artifactId>spring-boot-parent</artifactId>
<groupId>org.springframework.boot</groupId>
<version>2.2.5.RELEASE</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>com.xxl</groupId>
<artifactId>sms</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
</properties>
<modules>
<module></module>
</modules>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.27</version>
</dependency>
</dependencies>
<build>
<plugins>
</plugins>
</build>
</project>
- 1.modelVersion: Maven 模型的版本,默认配置。
- 2.groupId:公司或者是组织的id,一般是公司域名的倒写,例如 com.alibaba。或者是公司域名+项目名的倒写,例如 com.alibaba.taotao。
- 3.artifactId:项目名称。
- 4.version:项目的版本号,通常使用三位数字标识,例如 2.2.5。如果项目还在开发中,通常在版本后加上 SNAPSHOT。如果项目很稳定,已经发布,一般会在版本后加上 RELEASE。
- 5.parent:用来声明要继承的父工程的 pom 配置。
- 6.packaging:项目打包的类型,默认是 jar。一般 java 程序打包成 jar,web 程序打包成 war。
- 7.properties:用来定义项目中一些配置,例如编码格式等。
- 8.dependencies:在 Maven 项目中,我们需要的 jar 包叫做依赖。我们在 dependencies 标签中配置依赖,依赖的配置是通过坐标来表示。坐标就是 groupId、artifactId、version 的组合。
- 9.modules:在 Maven 多模块开发中,设置本模块和其他模块的关系。
- 10.build:build 主要包含和项目构建相关的配置,例如设置编译插件的 jdk 版本。
4.3 依赖
在 Maven 项目中,我们需要的 jar 包叫做依赖。我们在 dependencies 标签中配置依赖的坐标之后,Maven 会根据依赖的坐标自动到本地仓库中查找,找到之后会自动引入到我们的项目中。
如果没有找到,Maven 会根据依赖的坐标从*仓库将 jar 包下载到本地仓库中。
依赖需要在 dependency 标签里面书写,它包含 groupId、artifactId、version。例如:
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.27</version>
</dependency>
</dependencies>
其实我们可以将依赖的坐标(dependency)当成是 jar 包的身份证,你在 pom.xml 中配置了依赖坐标,Maven 会根据这个身份证先去本机的 repository 目录下找 jar 包,如果找不到就去*仓库将该 jar 包下载到你电脑的 repository 文件夹下,然后引入到项目中。
4.4 依赖的范围
我们在配置依赖时,其实还有一个依赖的范围 scope:
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.27</version>
<scope>compile</scope>
</dependency>
依赖的范围:compile、test、provided,默认是 compile。
例如 junit 依赖的范围就是 test,只参与测试。 而 servlet 依赖的范围是 provided,不参与打包和部署,因为 tomcat 服务器已经包含 servlet 的 jar 包。
4.5 坐标
Maven 把任何一个 jar 包都作为仓库中的一个项目进行管理,用三个向量组成的坐标来表示。坐标在仓库中可以表示唯一的 Maven 项目。
坐标就是 groupId、artifactId、version 的组合。groupId、artifactId 和 version 决定项目在仓库中的路径,artifactId 和 version 决定 jar 包的名称。
4.6 仓库
我们在 pom.xml 文件里面配置了依赖(jar包)的坐标,Maven 就能自动将 jar 包加载到项目中,它从哪儿搞到的 jar 包?Maven 的仓库。
我们都知道仓库是用来存放东西的,那 Maven 仓库用来存放什么?jar 包。
根据仓库存储的位置,我们把 Maven 仓库分为本地仓库和远程仓库。
本地仓库: 就是把 jar 包存放到你电脑上的一个文件夹下面,Maven 默认将 jar 包放到 C 盘的 .m2\repository 目录中。
远程仓库: 远程仓库又分为*仓库、*仓库的镜像、私服。
*仓库包含所有通用的 jar 包,所有的程序员都能联网从*仓库中获取 jar 包。*仓库是 maven 默认的远程仓库,是最权威的。
*仓库官网地址:
https://mvnrepository.com/
我们需要的所有的依赖都能在上面找到:
*仓库的镜像: 亚洲、欧洲等每个洲都有若干的服务器,为*仓库分担流量。减轻*仓库的访问压力。所在洲的用户首先访问的是本洲的镜像服务器。上面我们配置的阿里云的 Maven 仓库镜像就属于*仓库的镜像。
私服: 在局域网环境中部署的服务器,一般公司中会使用私服。
4.7 Maven 生命周期
Maven 的生命周期:就是 Maven 构建项目的过程,清理,编译,测试,报告,打包,安装,部署。
5. Maven 常用设置
5.1 定义全局变量
我们可以在 properties 定义全局变量,然后使用 ${变量名} 统一配置依赖的坐标。例如:
<properties>
<mysql.version>8.0.27</mysql.version>
</properties>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
</dependencies>
5.2 指定资源位置
src 目录中所有的 java 文件会分别在 comile 和 test-comiple 阶段被编译,但是这两个目录中的其他文件都会被忽略掉,如果需要把 src 目录下的其他文件作为打包的 jar 包的一部分,需要指定资源文件位置。
我们需要在 build 标签中指定那个资源的位置:
<build>
<resources>
<resource>
<directory>src/main/java</directory><!--所在的目录-->
<includes><!--目录下的.properties,.xml 文件都会扫描到-->
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
</resource>
</resources>
</build>
6. Maven 管理多模块应用
有时候我们会把一个项目分为多个模块,例如 common 模块主要包含一些工具类、常量信息等,service 模块主要用来处理业务,web 模块主要是控制器。
Maven 可以很方便地帮我们维护不同模块之间的关系。
6.1 使用 Maven 创建多模块项目
创建 Maven 父工程 sms
File -> new -> Module -> Maven
删除父工程 src 目录,pom 文件打包方式改为 pom
创建子工程 sms-web
File -> new -> Module -> Maven
创建子工程 sms-service
File -> new -> Module -> Maven
创建子工程 sms-dao
File -> new -> Module -> Maven
创建子工程 sms-model
File -> new -> Module -> Maven
创建子工程 sms-common
File -> new -> Module -> Maven
父工程 pom 文件:
6.2 引入依赖
1. 模块之间的依赖:
我们都知道依赖是会传递的,例如 B 模块引入了 A 模块,C 模块引入了 B 模块,就相当于 C 模块引入了 A 模块。
而在项目中我们知道 service 依赖 dao,controller 依赖 service。dao、service、controller 又都依赖 model 实体类,dao 和 service 又都需要用到 common 。但是我们不可能在他们三个中都添加 model 的依赖,在 dao 和 service 中都添加 common 的依赖。
根据依赖的传递性,我们可以在 common 模块中添加 model 的依赖,在 dao 中添加 common 的依赖,在 service 中添加 dao 的依赖,在 controller 中添加 service 的依赖。
sms-common 的 pom.xml:
sms-dao 的 pom.xml:
sms-service 的 pom.xml:
sms-web 的 pom.xml:
然后再用 Maven 工具打包、安装之后,各模块之间就可以相互调用了。
2. 第三方依赖:
我们一般会在父工程的 pom.xml 中使用 dependencyManagement 标签来管理依赖的版本。子模块中如果用到了这个依赖,只需要在 dependencies 标签中引入即可。
通过上面的图片我们知道,dependencyManagement 标签并不能真正引用依赖,它只是规定了依赖的版本,便于我们统一管理。
假如 sms-web 模块需要使用 commons-io 的依赖,我们只需要在它的 pom.xml 文件的 dependencies 依赖中加入该依赖的坐标即可。
因为父模块中通过 properties 标签规定了依赖的版本,所以子模块中不需要再加入版本号,这样方便统一管理。
推荐阅读
-
Maven 包可执行 jar 包方法(有史以来最完整的方法)
-
最完整的 Maven 使用指南,尽在这里。
-
maven 3.6.3 下载和安装。安装教程(适合新手的最完整教程)
-
在 2022 年官方网站下安装最完整版本的 MAVEN 并访问官方网站
-
不用再找了,最完整的数据可视化色彩指南就在这里!
-
企鹅主题更改 最完整的问与答 详细步骤在这里
-
最完整的 centos 安装和配置 maven
-
计算机视觉中,究竟有哪些好用的目标跟踪算法(下)-快速变形主要因为CF是模板类方法。容易跟丢这个比较好理解,前面分析了相关滤波是模板类方法,如果目标快速变形,那基于HOG的梯度模板肯定就跟不上了,如果快速变色,那基于CN的颜色模板肯定也就跟不上了。这个还和模型更新策略与更新速度有关,固定学习率的线性加权更新,如果学习率太大,部分或短暂遮挡和任何检测不准确,模型就会学习到背景信息,积累到一定程度模型跟着背景私奔了,一去不复返。如果学习率太小,目标已经变形了而模板还是那个模板,就会变得不认识目标。(举个例子,多年不见的同学,你很可能就认不出了,而经常见面的同学,即使变化很大你也认识,因为常见的同学在你大脑里面的模型在持续更新,而多年不见就是很久不更新) 快速运动主要是边界效应(Boundary Effets),而且边界效应产生的错误样本会造成分类器判别力不够强,下面分训练阶段和检测阶段分别讨论。 训练阶段,合成样本降低了判别能力。如果不加余弦窗,那么移位样本是长这样的: 除了那个最原始样本,其他样本都是“合成”的,100*100的图像块,只有1/10000的样本是真实的,这样的样本集根本不能拿来训练。如果加了余弦窗,由于图像边缘像素值都是0,循环移位过程中只要目标保持完整那这个样本就是合理的,只有目标中心接近边缘时,目标跨越边界的那些样本是错误的,这样虽不真实但合理的样本数量增加到了大约2/3(padding= 1),即使这样仍然有1/3(3000/10000)的样本是不合理的,这些样本会降低分类器的判别能力。再者,加余弦窗也不是“免费的”,余弦窗将图像块的边缘区域像素全部变成0,大量过滤掉分类器本来非常需要学习的背景信息,原本训练时判别器能看到的背景信息就非常有限,我们还加了个余弦窗挡住了背景,这样进一步降低了分类器的判别力(是不是上帝在我前遮住了帘。不是上帝,是余弦窗)。 检测阶段,相关滤波对快速运动的目标检测比较乏力。相关滤波训练的图像块和检测的图像块大小必须是一样的,这就是说你训练了一个100*100的滤波器,那你也只能检测100*100的区域,如果打算通过加更大的padding来扩展检测区域,那样除了扩展了复杂度,并不会有什么好处。目标运动可能是目标自身移动,或摄像机移动,按照目标在检测区域的位置分四种情况来看: 如果目标在中心附近,检测准确且成功。 如果目标移动到了边界附近但还没有出边界,加了余弦窗以后,部分目标像素会被过滤掉,这时候就没法保证这里的响应是全局最大的,而且,这时候的检测样本和训练过程中的那些不合理样本很像,所以很可能会失败。 如果目标的一部分已经移出了这个区域,而我们还要加余弦窗,很可能就过滤掉了仅存的目标像素,检测失败。 如果整个目标已经位移出了这个区域,那肯定就检测失败了。 以上就是边界效应(Boundary Effets),推荐两个主流的解决边界效应的方法,但速度比较慢,并不推荐用于实时场合。