文章目录
一、IDEA项目中的概念
一般是在Project Structure中为项目进行设置
更多设置在File—>settings/New Project Settings中



Project
Project name
整个项目的名字
IDEA和eclipse不同之处在于IDEA中的project和eclipse中的workspace的概念相似,但是IDEA将project作为了最大的一个“工作空间”
在IDEA中每一个Module(模块)是可以单独运行的
Project SDK
设置项目所使用的JDK版本
在这个项目中的所有模块都是用这个版本的jdk
Project language level
编译的时候使用什么版本特性进行检查,不能超过这个版本的特性,可以向下兼容
Project compiler output
一个maven工程编译后的文件所存放的地方
在运行一个项目的时候真正运行的是out里的文件,而不是我们写的源代码
target文件夹一般是Module编译后文件的默认存放位置
在源代码中所有的路径最后都会变成out/target中的路径
编译的输出文件在每次编译后都会覆盖,所以不要将资源放入了out/target文件夹中,特别是做服务器上传文件的时候
Modules
一个项目一般是由多个模块构成,是一个项目的某个部分
也可以看作是一个单独的项目,每个模块可以单独运行
name
模块的名称
Sources
是对module的发开目录进行文件夹分类,那些文件夹中存放Java源码(src/main/java),那些文件存放静态资源(resources),存放测试文件的地方,如果是web项目,还有WEB-INF配置文件
在编译项目的时候就是编译标记为sources文件夹中的内容,资源文件会被自动编译进去
在使用文件路径的时候也是要根据文件标记进行路径的书写
paths
Compiler output:编译后的输出路径
Inherit project compile output path:继承项目编译输出路径,选择此选项以使用项目的输出路径为模块输出路径。即上面在Project选项中设置的out文件路径。
Use module compile output path:使用模块编译输出路径。一般是当前模块中的target文件夹(一般只有整个工程的输出为out)
在打包整个工程的时候,需要修改每个模块的输出路径,也就是改为继承项目的输出路径,然后在IDEA顶栏选择Build---->Build project打包整个项目
dependencies
模块依赖的jar包
Librabries
存放依赖的jar包的地方
maven通过xml文件将需要的jar包从本地或者远程仓库中下载,首先扫描本地,有就直接导入,没有就从远程仓库下载到本地仓库
Facets
管理项目的特性
说明这个项目的类型,是WEB,还是Spring等等
Aritifacts
打包的时候用的,设定怎么打包,打成什么样的包(war、warexploded)
WEB中的exploded类型可以进行热部署,war包是压缩过后的压缩文件
SDKS
管理JDK版本
Global Libraries
存放全局类库(jar)
可以存放一些常用的类库
.idea和.iml
存放了对项目或工程的一些配置信息
这样别的IDEA打开文件就可以直接读取配置信息从而快速运行
二、Maven概述
我们在构建项目的时候需要有一定的目录格式才能够很好的管理项目
而maven就是用于项目管理的
maven可以帮助我们很好的管理工程中的各种资源并进行项目的构建管理等工作
使用maven好处
- 统一快速地管理jar包,通过本地和远程仓库可以快速导入jar包,不需要再去手动下载
- 统一使用maven后项目的移指很快,配置文件都在,可以快速搭建项目环境
- 帮助我们编译、打包、发布项目
maven配置
主要是jar包镜像仓库的配置
在<settings>和</settings>之间添加
<mirrors>
<mirror>
<id>alimaven</id>
<name>aliyun maven</name>
<url>http://maven.aliyun.com/nexus/content/groups/public</url>
<mirrorOf>central</mirrorOf>
</mirror>
</mirrors>
maven基本目录结构
maven根据不同的工程类型会有不同的目录结构
但会有一个基本的目录结构
src
|--main
|--java 源代码目录
|--resources 资源目录
|--test
|--java 测试代码目录
|--resources 测试资源目录
target 编译文件父目录
|--classes 编译的后的class文件目录
|--test-classes 编译后的测试class文件目录
pom.xml maven工程配置文件
IDEA自带的Maven和手动下载的Maven区别
IDEA中自带了maven,但是需要进行设置才能使用插件安装的标准maven,默认是一个IDEA自带的类似maven的项目管理
另外IDEA中插件安装的maven并没有配置环境变量,因此不能使用命令行的方式使用maven
三、Maven生命周期
maven的生命周期就是指一个项目从源代码到部署的整个周期
maven有三个内置的生命周期
- 清洁(clean):为执行以下工作做必要的清理工作。比如删除out文件夹
- 默认(default):真正进行项目编译打包等工作的阶段
- 站点(site):生成项目报告,站点,发布站点
其中,默认生命周期包括以下阶段(简化版)
- 验证(validate) - 验证项目是否正确,所有必要的信息可用。
- 编译(compile) - 编译项目的源代码。
- 测试(test) - 使用合适的单元测试框架测试编译的源代码。这些测试不应该要求代码被打包或部署。
- 打包(package) - 采用编译的代码,并以其可分配格式(如JAR) 进行打包。
- 验证(verify) - 对集成测试的结果执行任何检查,以确保满足质量标准。
- 安装(instal) - 将软件包安装到本地存储库中,用作本地其他项目的依赖项。
- 部署(deploy) - 在构建环境中完成,将最终的包复制到远程存储库以与其他开发人员和项目共享。
四、Maven命令
在IDEA中右侧栏的maven窗口就有生命周期Lifecycle,双击就可以执行命令
| 命令 | 解释 |
|---|---|
| mvn -version | 显示版本信息 |
| mvn clean | 清理项目产生的临时文件,通常来说是模块下的target目录 |
| mvn compile | 编译源代码,就是resources目录下的代码,通常是src/main/java下的 |
| mvn package | 项目打包,会在target目录下生成jar或者war包等文件 |
| mvn test | 测试命令,执行src/test/java的junit测试用例 |
| mvn install | 将打包的jar/war文件复制到本地仓库,可以让其他模块使用 |
| mvn deploy | 将打包的文件提交到远程,让其他人员下载 |
| mvn site | 生成项目相关信息的网站 |
| mvn dependency:tree | 打印出项目的整个依赖树 |
| mvn archetype:generate | 创建maven的普通Java项目 |
| mvn tomcant:run | 在tomcat容器中运行web应用 |
在这些基本命令后可以跟一些插件命令或组合使用,实现插件的功能
比如mvn clean package
五、Maven版本规范/坐标
通过几个要素来定位项目
比如apache下的项目都是:项目名称.apache.org
maven.apache.org
tomcat.apache.org
groupId团体、组织的标识符。团体标识的约定是,它以创建这个项目的组织名称的逆向域名开头。一般对应着Java文件夹下的包结构artifactId单独项目的唯一标识符,比如tomcat、commons等,在里面不要包含句号version项目的版本packaging项目的类型,默认是jar,描述了项目打包后的输出。类型为jar的项目产生一个JAR文件,,类型为war的项目产生一个web应用SNAPSHOT这个版本一般用于开发过程中,表示不稳定的版本LATEST指某个特定构件的最新发布,这个发布可能是-一个发布版,也可能是-个snapshot版, 具体看哪个时间最后RELEASE指最后一个发布版
六、在IDEA中配置Maven
打开File---->Settings---->Build,Execution,Deployment---->Build Tools---->Maven

在Maven home directory中选择IDEA安装的插件,而不是Bundled
根据目录在插件maven的conf下找到settings.xml配置镜像
Local repository我这里使用的是默认的,建议放到空间比较大的盘,自行建一个repository文件夹,选中Override点击文件夹图标更改即可,因为jar使用多了大小还是比较大的,C盘比较大可以无视
IDEA中Maven工程和Maven模块的区别
在IDEA中在创建project的时候可选择空项目,然后建立maven模块
也可以直接创立一个maven工程
这两者的区别是
- 创建空项目再创建maven模块时默认是不在项目下,不以project为父模块
- 创建maven工程再创建maven模块默认是以project为父模块,并且模块文件夹放置于project中
七、Maven依赖
依赖管理
maven管理的最突出特点就是jar包的自动下载
我们通过在pom.xml中配置就可以实现jar的导入或下载
仓库分为本地仓库和中央仓库
本地仓库就是指使用的主机上仓库
中央/远程仓库是本地仓库没有就去中央仓库下载,中央仓库没有就只能手动下载(比如不开源的),放入本地放库,按照格式建立文件目录就可以
C:\Users\18996.m2\repository\com\alibaba\fastjson\1.2.68
其实就是按照groupId和artifactId创建文件目录,将对应版本的jar放入对应的版本号名字的文件夹中就可以
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vvqzQ7qT-1593501720944)(maven依赖.png)]
添加依赖的方式就是在pom.xml中添加jar包的坐标
其中包含了组织ID,项目ID,版本,范围
最主要的是前三个
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.7</version>
<scope>test</scope>
</dependency>
</dependencies>
依赖范围
类路径
在配置Java环境变量的时候配置过classpath(类路径)这一变量
编译好的class文件都会在类路径中
类加载器classloader也是在类路径中加载class二进制文件
在打包成jar后,在META-INF中有个文件会告诉jvm去哪个类中寻找main方法
最普通的Java工程就是我们的包名开始的,普通Java项目的资源需要放在src目录下
web项目打包后会放在WEB-INF的classes中,同时还有配置文件,src下的资源文件会自动复制到WEB-INF/classes下
对于maven项目而言
maven工程会将src/main/java和src/main/resources文件夹下的文件全部打包在classpath中。运行时它们两个文件夹下的文件会被放在一个文件夹下
maven项目不同的阶段引入到classpath中的依赖是不同的,比如
- 编译时,maven会将与编译相关的依赖引入到classpath
- 测试时,maven会将测试相关的依赖引入到classpath
- 运行时,maven会将与运行相关的依赖引入classpath
依赖范围就是用来控制依赖与这三种classpath的关系
前面导入依赖的scope标签就是标记依赖的依赖范围
该项默认配置compile,可选配置还有test、 provided、 runtime、 system、 import
compile、test、provided使用较多
为什么需要依赖的范围?以下例子说明了不同jar包在不同的时刻的作用
有些jar包(如selvlet-api) 运行时其实是不需要的,因为tomcat里有,但编译时是需要的,因为编译的时候没有tomcat环境
有些jar只在测试的时候才能用到。比如junit,,真是运行不需要的
有些jar运行,测试时必须要有,编译时不需要,如jdbc驱动,编译时用的都是jdk中的接口,运行时我们才使用反射注册了驱动。
编译依赖范围(compile)
该范围就是默认依赖范围,此依赖范围对于编译、测试、运行三种 classpath都有效,举个简单的例子,假如项 目中有fastjson的依赖,那么 fastjson不管是在编译,测试,还是运行都会被用到,因此 fastjson 必须是 编译范围(构件默认的是编译范围,所以依赖范围是编译范围的无须显示指定)
<dependency>
<groupId> com. alibaba</groupId>
<artifactId> fastjson</artifactId>
<version>1.2.68</version>
</dependency>
测试依赖范围(test)
使用此依赖范围的依赖,只对测试classpath有效,在编译主代码和项目运行时,都将无法使用该依赖,最常见的就是各种日志记录jar,需要显式指定scope,虽然不指定范围没错,但是会造成不必要的浪费
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.7</version>
<scope>test</scope>
</dependency>
</dependencies>
提供依赖范围(provided)
使用该依赖范围的maven依赖,只对编译和测试的classpath有效,对运行的classpath无效,典型的例子就是 servlet-api,编译和测试该项目的时候需要该依赖,但是在运行时,web容器已经提供的该依赖,所以运行时就不 再需要此依赖,如果不显示指定该依赖范围,并且容器依赖的版本和maven依赖的版本不一致的话,可能会引起版 本冲突,造成不良影响。
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
运行时依赖范围(runtime)
使用该依赖范围的maven依赖,只对测试和运行的classpath有效,对编译的classpath无效,典型例子就是JDBC的 驱动实现,项目主代码编译的时候只需要JDK提供的JDBC接口,只有在测试和运行的时候才需要实现上述接口的具 体JDBC驱动。
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.7</version>
<scope>runtime</scope>
</dependency>
依赖传递
概念
在构建项目的过程中,不都是从底层一步步写起,jar之间会有多重了依赖关系,依赖传递可以让我们不用关心我们所依赖的jar依赖了哪些jar,只要添加依赖,maven会自动将它所依赖的jar自动添加进来

依赖传递的原则
- 最短路径优先原则:如果A依赖于B,B依赖于C,在B和C中同时有同一个jar依赖,并且两个版本不一致,那么A会根据最短路径优先原则,在A中会传递过来B的那个共同依赖

- 路径相同先声明原则:如果工程同时依赖于B和A,B和C没有依赖关系,并且都有D的依赖,并且版本也不一样,那么会引入在pom.xml中先声明的那个依赖的版本

A和B在xml中谁先声明导入谁的D
<dependency>
<groupId>org.apache</groupId>
<artifactId>A</artifactId>
<version>1.12.2</version>
</dependency>
<dependency>
<groupId>org.apache</groupId>
<artifactId>B</artifactId>
<version>1.5.3</version>
</dependency>
这样就引入了A的D.jar(1.2)
但是这样仍会出现问题,如果在B中使用了新版本的新特性,又把A放在了前面,就会导致错误,需要手动更改位置
依赖的排除
在前面的情况中出现了引入了低版本jar导致某个jar不可用的情况,如果想要排除低版本的jar,可以使用exclusions标签限定D版本
<dependency>
<groupId>org.apache</groupId>
<artifactId>A</artifactId>
<version>1.12.2</version>
<exclusions>
<exclusion>
<groupId>org.apache</groupId>
<artifactId>D</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache</groupId>
<artifactId>B</artifactId>
<version>1.5.3</version>
</dependency>
这样就将A当中的D排除掉
聚合和继承
在分布式开发中,一个项目通常由许多子项目构成
利用maven的聚合和继承可以很好地解决项目的关系问题
父模块为MavenTest,其基本xml为

子模块在父模块当中,每个子模块都有pom.xml文件,其基本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>MavenTest</artifactId>
<groupId>org.example</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>child-one</artifactId>
</project>
其中一定要有<packaging>标签,如果没有要加上,内容要为pom,而且不需要src文件夹
在聚合多个项目时,如果这些被聚合的项目中需要引入相同的jar,那么可以将这些jar写入父pom中,各个子项目 继承该pom即可。父模块的打包方式必须为pom,否则无法构建项目。
在父模块中依赖了,子模块就可以使用依赖的jar,要注意子类中的父模块名称要对应
可以被继承的POM元素如下:
groupId:项目组ID,项目坐标的核心元素
version:项目版本,项目坐标的核心因素
properties:自定义的Maven属性,类似于常量,一般用于同一制定各个依赖的版本号,使用的时候用
${自定义标签名}就可以使用dependencies:项目的依赖配置 公共的依赖
dependencyManagement:项目的依赖管理配置
repositories:项目的仓库配置
build:包括项目的源码目录配置、输出目录配置、插件配置、插件管理配置等
在刚才的子模块中可以看见xml中并没有前面两个,就是直接继承了父模块的
还有一些项目的描述也可以被继承
description:项目的描述信息
organization:项目的组织信息
inceptionYear:项目的创始年份
url:项目的URL地址
developers:项目的开发者信息
contributors:项目的贡献者信息
distributionManagement:项目的部署配置
issueManagement:项目的缺陷跟踪系统信息
ciManagement:项目的持续集成系统信息
scm:项目的版本控制系统
malilingLists:项目的邮件列表信息
reporting:包括项目的报告输出目录配置、报告插件配置等
八、POM文件
基础配置
最常用的标签如下
<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.0http://maven.apache.org/xsd/maven
-4.0.0.xsd">
<!-- 模型版本。maven2.0必须是这样写,现在是maven2唯一支持的版本 -->
<modelVersion>4.0.0</modelVersion>
<!-- 公司或者组织的唯一标志,并且配置时生成的路径也是由此生成, 如com.xinzhi,maven会将该项目打
成的jar包放本地路径:/com/xinzhi/ -->
<groupId>org.apache</groupId>
<!-- 本项目的唯一ID,一个groupId下面可能多个项目,就是靠artifactId来区分的 -->
<artifactId>test</artifactId>
<!-- 本项目目前所处的版本号 -->
<version>1.0-SNAPSHOT</version>
<!-- 打包的机制,如pom,jar, war,默认为jar,父模块一定要是pom-->
<packaging>jar</packaging>
<!-- 为pom定义一些常量,在pom中的其它地方可以直接引用 使用方式 如下 :${file.encoding} -->
<!-- 常常用来整体控制一些依赖的版本号 -->
<properties>
<file.encoding>UTF-8</file.encoding>
<java.source.version>1.8</java.source.version>
<java.target.version>1.8</java.target.version>
</properties>
<!-- 定义本项目的依赖关系,就是依赖的jar包 -->
<dependencies>
<!-- 每个dependency都对应这一个jar包 -->
<dependency>
<!--
一般情况下,maven是通过groupId、artifactId、version这三个元素值(俗称坐标)来检索该构 件, 然后引入你的工程。如果别人想引用你现在开发的这个项目(前提是已开发完毕并发布到了远程仓 库)
-->
<!--
就需要在他的pom文件中新建一个dependency节点,将本项目的groupId、artifactId、version写 入, maven就会把你上传的jar包下载到他的本地
-->
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<!-- 依赖范围 -->
<scope>complie</scope>
<!-- 设置 依赖是否可选,默认为false,即子项目默认都继承。如果为true,则子项目必需显示的引入 -->
<optional>false</optional>
<!-- 依赖排除-->
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
...
</project>
dependency和dependencyManagement的区别
dependency
- 即使使在子项目中不写该依赖项,那么子项目仍然会从父项目中继承该依赖项(全部继承)
- 继承下来就会被编译,如果子项目根本不用这个依赖会增加子工程的负担
dependencyManagement
- 通常会在父工程中定义,目的是统一各个子模块的依赖版本
- 只是声明依赖,并不实现引入
- 子项目需要显示的声明需要用的依赖。如果不在子项目中声明依赖,是不会从父项目中继承下来的
- 只有在子项目中写了该依赖项,并且没有指定具体版本,才会从父项目中继承该项,并且version和scope都读取自父pom;另外如果子项目中指定了版本号,那么会使用子项目中指定的jar版本。
构建配置
<build>
<!-- 产生的构件的文件名,默认值是${artifactId}-${version}。 -->
<finalName>myPorjectName</finalName>
<!-- 构建产生的所有文件存放的目录,默认为${basedir}/target,即项目根目录下的target -->
<directory>${basedir}/target</directory>
<!--项目相关的所有资源路径列表,例如和项目相关的配置文件、属性文件,这些资源被包含在最终的打包文件
里。 -->
<!--项目源码目录,当构建项目的时候,构建系统会编译目录里的源码。该路径是相对于pom.xml的相对路
径。 -->
<sourceDirectory>${basedir}\src\main\java</sourceDirectory>
<!--项目单元测试使用的源码目录,当测试项目的时候,构建系统会编译目录里的源码。该路径是相对于
pom.xml的相对路径。 -->
<testSourceDirectory>${basedir}\src\test\java</testSourceDirectory>
<!--被编译过的应用程序class文件存放的目录。 -->
<outputDirectory>${basedir}\target\classes</outputDirectory>
<!--被编译过的测试class文件存放的目录。 -->
<testOutputDirectory>${basedir}\target\test-classes
</testOutputDirectory>
<!-- 以上配置都有默认值,就是约定好了目录就这么建 -->
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
<!--单元测试相关的所有资源路径,配制方法与resources类似 -->
<testResources>
<testResource>
<targetPath/>
<filtering/>
<directory/>
<includes/>
<excludes/>
</testResource>
</testResources>
<!--使用的插件列表 。 -->
<plugins>
<plugin>
...具体在插件使用中了解
</plugin>
</plugins>
<!--主要定义插件的共同元素、扩展元素集合,类似于dependencyManagement, -->
<!--所有继承于此项目的子项目都能使用。该插件配置项直到被引用时才会被解析或绑定到生命周期。 -->
<!--给定插件的任何本地配置都会覆盖这里的配置 -->
<pluginManagement>
<plugins>...</plugins>
</pluginManagement>
</build>
添加本地jar
<!-- geelynote maven的核心插件之-complier插件默认只支持编译Java 1.4,因此需要加上支持高版本jre的
配置,在pom.xml里面加上 增加编译插 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
<compilerArguments>
<!-- 本地jar,比如某一jar包放到src/main/webapp/WEB-INF/lib文件夹下,
如果没有配置,本地没问题,但是线上会找不到sdk类
为什么要引入,因为这个jar包在中央仓库没有,再比如oracle连接驱动的jar
-->
<extdirs>${project.basedir}/src/main/webapp/WEB-INF/lib</extdirs>
</compilerArguments>
</configuration>
</plugin>
仓库配置
<repositories>
<repository>
<id>alimaven</id>
<name>aliyun maven</name>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
pom.xml里面的仓库与setting.xml里的仓库功能是一样的。主要的区别在于,pom里的仓库是个性化的。比如一家大公司里的setting文件是公用的,所有项目都用一个setting文件,但各个子项目却会引用不同的第三方库,所 以就需要在pom.xml里设置自己需要的仓库地址。
项目信息配置
可以进行对项目的名称、主页、邮箱、开发者列表、贡献者列表等等进行配置,作了解即可
九、Maven仓库
任何的构件都有唯一的坐标,Maven根据这个坐标定义了构件在仓库中的唯一存储路径
maven仓库分为两类
- 本地仓库
- 远程仓库
- 中央仓库
- 私服
- 其他公共库
本地仓库
本地仓库是Maven在本地存储构建的地方。Maven的本地仓库,在安装maven后并不会创建,它是在第一次执行Maven命令的时候才被创建
Maven本地仓库的默认位置:无论是Windows还是Linux,在用户的目录下都有一个.m2/repository/的仓库目录, 这就是Maven仓库的默认位置
在Maven的目录下的conf目录下,有一个settings.xml文件,是Maven的配置文件,在里面可以修改本地仓库的位 置
远程仓库
远程仓库主要用于获取其它人的Maven构件,其中最主要的就是中央仓库。
中央仓库
中央仓库是默认的的远程仓库,Maven在安装的时候,自带的就是中央仓库的配置
所有的Maven都会继承超级POM,超级POM种包含如下配置:
<repositories>
<repository>
<id>central</id>
<name>Cntral Repository</name>
<url>http://repo.maven.apache.org</url>
<layout>default</layout>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
对于中国开发者来说,中央仓库由于在境外,速度较慢,因此通常使用国内的镜像仓库,比如阿里巴巴仓库
配置镜像仓库xml如下
<!--镜像列表-->
<mirrors>
<!--镜像-->
<mirror>
<id>alimaven</id>
<!--被镜像的服务器ID-->
<mirrorOf>central</mirrorOf>
<name>aliyun maven</name>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
</mirror>
</mirrors>
私服
私服是一种特殊的远程仓库,它是架设在局域网内的仓库服务,私服代理广域网上的远程仓库,供局域网内的Maven用户使用。当Maven需要下载构件的时候,它从私服请求,如果私服上不存在该构件,则从外部的远程仓 库下载,缓存在私服上之后,在为Maven的下载请求提供服务
私服的优点
- 加速构建;
- 节省带宽;
- 节省中央maven仓库的带宽;
- 稳定(应付一旦中央服务器出问题的情况);
- 可以建立本地内部仓库;
- 可以建立公共仓库。
maven 在默认情况下是从中央仓库下载构建,也就是 id 为 central 的仓库。如果没有特殊需求,一般只需要将私 服地址配置为镜像,同时配置其代理所有的仓库就可以实现通过私服下载依赖的功能。镜像配置如下:
<mirror>
<id>Nexus Mirror</id>
<name>Nexus Mirror</name>
<url>http://localhost:8081/nexus/content/groups/public/</url>
<mirrorOf>*</mirrorOf>
</mirror>
十、Maven插件
介绍
Maven 实际上是一个依赖插件执行的框架,每个任务实际上是由插件完成。Maven 插件通常被用来:
打包jar文件
创建war文件
编译代码文件
代码单元测试
创建工程文档
创建工程报告
插件通常提供了一个目标的集合,并且可以使用下面的语法执行:
mvn [plugin-name]:[goal-name]
例如,一个 Java 工程可以使用 maven-compiler-plugin 的 compile-goal 编译,使用以下命令:
mvn compiler:compile
另外,插件是在build中配置
maven-compiler-plugin
设置maven编译的jdk版本,maven3默认用jdk1.5,maven2默认用jdk1.3
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.8</source> <!-- 源代码使用的JDK版本 -->
<target>1.8</target> <!-- 需要生成的目标class文件的编译版本 -->
<encoding>UTF-8</encoding><!-- 字符集编码 -->
</configuration>
</plugin>
</plugins>
插件命令
在引入了插件后,具有命令的插件可以从右侧栏双击使用,也可以在命令行使用
比如添加了tomcat7插件
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<configuration>
<port>8080</port>
<uriEncoding>UTF-8</uriEncoding>
<path>/xinzhi</path>
<finalName>xinzhi</finalName>
</configuration>
</plugin>
除了从侧边栏双击使用命令外,在命令行也可以使用,插件命令在侧边栏都有提示
mvn tomcat7:run
war包打包插件
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<warName>test</warName>
<webResources>
<resource>
<directory>src/main/webapp/WEB-INF</directory>
<filtering>true</filtering>
<targetPath>WEB-INF</targetPath>
<includes>
<include>web.xml</include>
</includes>
</resource>
</webResources>
</configuration>
</plugin>
可以执行
mvn clean package
mvn clean war:war
mvn war:war
等等命令
十一、项目模板
在使用IDEA创建maven项目的时候可以勾选create from archetype快速生成项目模板

十二、Maven父子工程进行版本统一
前面提到了dependencyManagement标签来控制父子工程jar包
这个标签是在父工程的pom中进行配置,父工程指定版本,子工程只需要groupId和artifactId就能导入,版本是父工程中指定的版本
比如在父工程中有如下配置
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.68</version>
</dependency>
</dependencies>
</dependencyManagement>
经过如下配置,声明了工程中可以导入com.alibaba的fastjsonjar,版本为1.2.68,但是这时候并没有真正导入jar,即并没有传递给子工程
在某个需要使用到这个jar的子工程中进行如下声明
<dependencies>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
</dependency>
</dependencies>
另外,如果版本号较多难以记忆,可以使用properties标签进行管理
以上面的例子为例,在父工程中添加如下xml
<properties>
<fastjson-version>1.2.68</fastjson-version>
</properties>
就可以将父工程中的fastjson依赖声明改为如下形式
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>${fastjson-version}</version>
</dependency>
</dependencies>
</dependencyManagement>
十三、查询jar包坐标
常用网站
也可以在pom.xml文件中使用生成代码的快捷键,默认是Alt+Insert进行搜索
参考文章https://gitee.com/zhangnan716/document-blibli/tree/master/maven%E6%96%87%E6%A1%A3
十四、资源过滤问题
当有一些配置文件不是放在resources文件下的时候,会引入不了
可以将main/java下的所有资源全部包括
<build>
<resources>
<resource>
<directory>src/main/java/</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
<resource>
<directory>src/main/resources/</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
</build>