前言
Maven 作为一个构建工具,不仅能帮我们自动化构建、自动化测试、还能够抽象构建过程,提供构建任务实现;它跨平台,对外提供了一致的操作接口,这一切足以使它成为优秀的、流行的构建工具。Maven 不仅是构建工具,还是一个依赖管理工具和项目管理工具,它提供了中央仓库,能帮助我们自动下载构件。
官网:https://maven.apache.org/
这里只介绍 window下如何安装,在安装 Maven 之前,先确认已经安装了 JDK。
接着去下载附件解压到你想要的目录就行了。
最后设置一下环境变量,将 Maven 安装配置到操作系统环境中,主要就是配置 M2_HOME
和 PATH
两项,如下图:
都搞定后,验证一下,打开 doc 输入 mvn-v
如何得到下面信息就说明配置成功了。
plexus-classworlds-2.5.2.jar
。 plexus-classworlds
是一个类加载器框架,相对于默认的 java 类加载器,它提供了更加丰富的语法以方便配置,Maven 使用该框架加载自己的类库;settings.xml
。直接修改该文件,就能在机器上全局地定制 Maven 的行为,一般情况下,我们更偏向于复制该文件至 ~/.m2/
目录下(~表示用户目录),然后修改该文件,在用户范围定制 Maven 的行为;maven-core-3.0.jar
、 maven-model-3.0.jar
之类的文件,此外这里还包含一些 Maven 用到的第三方依赖如 commons-cli-1.2.jar
、 commons-lang-2.6.jar
等等;maven 仓库默认在国外,使用难免很慢,尤其是下载包的时候,换为国内镜像,让你感受飞一般的感觉。国内支持 maven 镜像的有阿里云,开源中国等,这里示例阿里云的。
打开 maven 的配置文件(一般在 maven 安装目录的 conf/settings.xml
),在 <mirrors></mirrors>
标签中添加 mirror 子节点(当然也可以在用户 home 目录 .m2 下面添加一个 settings.xml
文件)。
<!-- 阿里云仓库 --><mirror> <id>alimaven</id> <mirrorOf>central</mirrorOf> <name>aliyun maven</name> <url>http://maven.aliyun.com/nexus/content/repositories/central/</url></mirror>
以上central 表示该配置为中央库的镜像,任何对于中央仓库的请求都会转至该镜像,用户也可以用同样的方法配置其他仓库的镜像。
这里介绍下配置的各种选项:
<mirrorOf>*<mirrorOf>
:匹配所有远程仓库;<mirrorOf>external:*<mirrorOf>
:匹配所有远程仓库,使用 localhost 的除外,使用 file://
协议的除外。也就是说,匹配所有不在本机上的远程仓库;<mirrorOf>repo1,repo2<mirrorOf>
:匹配仓库 repo1h 和 repo2,使用逗号分隔多个远程仓库;<mirrorOf>*,!repo1<mirrorOf>
:匹配所有远程仓库,repo1 除外,使用感叹号将仓库从匹配中排除;需要注意的是,当镜像仓库不稳定或者停止服务的时候,Maven 仍将无法访问被镜像仓库,因而将无法下载构件。
打开 IDEA,在菜单栏中 File->Settings
。然后,在 Settings 对话框中选择 Build,Execution, Deployment->BuildTools->Maven。
保存即可。
新建一个 maven 项目后会在窗口的右端出现一个 Maven Project 按钮,单击该按钮后弹出下图的对话框:
其中 Lifecycle 中包括了 maven 常用的命令,Dependencies 展示了当前 Maven项目的相关依赖包列表。
简单介绍下 Maven 的常用命令:
mvn clean
:表示运行清理操作(会默认把 target 文件夹中的数据清理);mvn clean compile
:表示先运行清理之后运行编译,会将代码编译到 target 文件夹中;mvn clean test
:运行清理和测试;mvn cleanpackage
:运行清理和打包;mvn clean install
:运行清理和安装,会将打好的包安装到本地仓库中,以便其他的项目可以调用;mvn clean deploy
:运行清理和发布(发布到私服上面);上面的命令大部分都是连写的,大家也可以拆分分别执行,看个人喜好以及使用需求
maven 项目的核心是 pom.xml ——POM(Project Object Model 项目对象模型),如下:
<?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"> <modelVersion>4.0.0</modelVersion> <groupId>com.zuozewei</groupId> <artifactId>springBootDemo1</artifactId> <version>0.0.1-SNAPSHOT</version> <name>springBootDemo1</name></project>
<dependencies> <dependency> <groupId>实际项目</groupId> <artifactId>模块</artifactId> <version>版本</version> <type>依赖类型</type> <scope>依赖范围</scope> <optional>依赖是否可选</optional> <!—主要用于排除传递性依赖--> <exclusions> <exclusion> <groupId>…</groupId> <artifactId>…</artifactId> </exclusion> </exclusions> </dependency><dependencies>
根元素 project 下的 dependencies 可以包含一个或者多个 dependency 元素,以声明一个或者多个项目依赖。每个依赖可以包含的元素有:
grounpId、artifactId 和 version: 以来的基本坐标,对于任何一个依赖来说,基本坐标是最重要的,Maven 根据坐标才能找到需要的依赖。
如下示例:
dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>4.3.14.RELEASE</version> <scope>test</scope> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>${slf4j.version}</version> </dependency> </dependencies>
有时候你引入的依赖中包含你不想要的依赖包,你想引入自己想要的,这时候就要用到排除依赖了,比如下图中 spring-boot-starter-web
自带了 logback 这个日志包,我想引入 log4j2 的,所以我先排除掉 logback 的依赖包,再引入想要的包就行了。
排除依赖代码结构:
<exclusions> <exclusion> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-logging</artifactId> </exclusion></exclusions>
注意:声明 exclustion 的时候只需要 groupId 和 artifactId,而不需要 version 元素,这是因为只需要 groupId 和 artifactId 就能唯一定位依赖图中的某个依赖。
有时候我们引入的很多依赖包,他们都来自同一个项目的不同模块,所以他们的版本号都一样,这时候我们可以用属性来统一管理版本号。
<project> <modelVersion>4.0.0</modelVersion> <groupId>com.juven.mvnbook.account</groupId> <artifactId>accout-email</artifactId> <version>1.0.0-SNAPSHOT</version> <properties> <springframework.version>1.5.6</springframework.version> </properties> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>${springframework.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>${springframework.version}</version> </dependency> </dependencies> </project>
如下所示:
</properties> 这里定义你先要的版本</properties>
通过以上来定义,然后在下面依赖使用 ${}
来引入你的属性。
在 Maven 世界中,任何一个依赖、插件或者项目构建的输出,都可以称为构件。得益于坐标机制,任何 Maven 项目使用任何一个构件的方式都是完全相同的。在此基础上,Maven可以在某个位置统一存储所有 Maven 项目共享的构件,这个统一的位置就是仓库。实际的 Maven 项目将不再各自存储其依赖文件,它们只需要声明这些依赖的坐标,在需要的时候(例如,编译项目的时候需要将依赖加入到 classpath 中),Maven 会自动根据坐标找到仓库中的构件,并使用它们 为了实现重用,项目构建完毕后可生成的构件也可以安装或者部署到仓库中,供其他项目使用。
任何一个构件都有其唯一的坐标,根据这个坐标可以定义其在仓库中的唯一存储路径,这便是 Maven 的仓库布局方式。该路经与坐标对应关系为 groupId/artifactId/version/artifactId-version.packaging
举个例子,比如下面这个分页插件依赖如下:
<dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.47</version> </dependency>
那它对应的仓库的路径就是这样:
Maven 仓库是基于简单文件系统存储的,我们也理解其存储方式、因此,当遇到一些与仓库相关的问题时,可以很方便的查找相关文件,方便定位问题。
一般来说,在 Maven 项目目录下,没有诸如 lib/
这样用来存放依赖文件的目录。当 Maven 在执行编译或测试时,如果需要使用依赖文件,它总是基于坐标使用本地仓库的依赖文件。默认情况下,不管在 Window 还是 Linux 下,每个用户在自己用户目录下都有一个路径名为 .m2/repository/
的仓库目录。如果你想自定义本地仓库目录地址。你可以编辑文件 ~/.m2/settings.xml
,设置 localRepository 元素的值为想要的仓库地址,例如:
<settings><localRepository>D:\java\repository\</localRepository></settings>
复制代码这样,该用户的本地仓库地址就被设置成了 D:\java\repository\
需要注意的是,默认情况下, ~/.m2/settings.xml
文件不存在,用户需要从 Maven 安装目录复制 $M2_HOME/conf/settings.xml
文件再进行编辑。
由于最原始的本地仓库是空的,Maven 必须知道至少一个可用的远程仓库,才能在执行 Maven 命令的时候下载到需要的构件。中央仓库就是这样一个默认的远程仓库,Maven 的安装文件自带了中央仓库的配置。中央仓库包含了这个世界上绝大多数流行的开源 Java 构件,以及源码、作者信息、SCM,信息、许可证信息等,每个月这里都会接受全世界 Java 程序员大概1亿次的访问,它对全世界 Java 开发者的贡献由此可见一斑。
私服是一种特殊的远程仓库,它是架设在局域网内的仓库服务,私服代理广域网上的远程仓库,供局域网内的 Maven 用户使用。当 Maven 需要下载构件的时候,它从私服请求,如果私服上不存在该构件,则从外部的远程仓库下载,缓存在私服上之后,再为 Maven 的下载请求提供服务。因此,一些无法从外部仓库下载到的构件也能从本地上传到私服上供大家使用。私服的好处:
这里介绍两个提供仓库服务搜索的地址:
maven 本身并不是一个单元测试框架,maven 做的只是在构建执行到特定生命周期阶段的时候,通过插件来执行 Junit 或 TestNG 的测试用例。这插件是
maven-surefire-plugin
—测试运行器。
默认情况下, maven-surefire-plugin
的 test 目标会自动执行测试源码路径(默认 src/test/java/)下所有符合一组命名模式的测试类如:
**/Test*.java : 任何子目录下所有命名以Test开头的Java类**/*Test.java :任何子目录下所有命名以Test结尾的Java类**/*TestCase.java :任何子目录下所有命名以Test结尾的java类
mvn package-DskipTests
第一种方式:POM中配置 maven-surefire-plugin 插件提供该属性(一般不推荐):
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>2.5</version> <configuration> <skipTests>true</skipTests> </configuration></plugin>
第二种方式:跳过测试代码的编译:
mvn package-Dmaven.test.skip=true
参数 maven.test.skip
同时控制了 maven-compiler-plugin
和 maven-surefire-plugin
两个插件的行为,测试代码编译跳过,测试运行跳过。
maven.test.skip
的 POM 配置如下:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>2.5</version> <configuration> <skipTests>true</skipTests> </configuration></plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>2.5</version> <configuration> <skipTests>true</skipTests> </configuration></plugin>
maven-surefire-plugin
提供一个 test 参数让用户能够在命令行指定要运行的测试用例。
mvn test-Dtest=RandomGeneratorTest[测试用例的类名]
——效果是只有需要测试的测试类得到运行;mvn test-Dtest=Random*Test
——运行所有类名以 Random 开头,Test 结尾的测试类;mvn test-Dtest=test1,test2,test3
——逗号指定多个测试用例,效用是告诉 maven 运行这些测试类;mvn test-Dtest=test1,test2,test3,Random*Tes
t ——星号和逗号可结合使用;mvn test-Dtest-DfailIfNoTests=false
——效用是告诉 maven-surefire-plugin 即使没有任何测试也不要报错,否侧maven-surefire-plugin找不到任何匹配的测试类,就会报错并导致构建失败;PS:上述命令行动态指定测试类的方法都应该只是临时使用,否则失去测试本身意义。
maven 提倡约定优于配置原则。
maven 自动运行测试:
<plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-surefire-plugin</artifactId><version>2.5</version><configuration> <includes> <include>**/*Tests.java</include> </includes></configuration></plugin
通过 excludes 元素排除一些符合默认命名模式的测试类:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>2.5</version> <configuration> <excludes> <exclude>**/*ServiceTest.java</exclude> <exclude>**/*TempDaoTest.java</exclude> </excludes> </configuration></plugin>
有了excludes 配置后, maven-surefire-plugin
将不再自动运行它们。
本文介绍了 maven 中常用的知识点,希望对大家有所帮助。