目录
Maven的作用
我们构建一个项目需要用到很多第三方的类库,如写一个使用Spring的Web项目就需要引入大量的jar包。一个项目Jar包的数量之多往往让我们瞠目结舌,并且Jar包之间的关系错综复杂,一个Jar包往往又会引用其他Jar包,缺少任何一个Jar包都会导致项目编译失败。
以往开发项目时,程序员往往需要花较多的精力在引用Jar包搭建项目环境上,而这一项工作尤为艰难,少一个Jar包、多一个Jar包往往会报一些让人摸不着头脑的异常。而Maven就是一款帮助程序员构建项目的工具,我们只需要告诉Maven需要哪些Jar 包,它会帮助我们下载所有的Jar,极大提升开发效率。
使用Maven构建的项目均使用统一的目录结构,基本的目录结构如下所示
文件夹结构 | 描述 |
---|---|
src/main/java | 存放 java 代码文件 |
src/main/resources | 包含了 图片 / 属性文件等资源文件 |
src/test/java | 存放 测试代码文件 |
src/test/resources | 包含了测试所需要的资源文件 |
target | 输出目录 |
pom.xml | Maven的配置文件 |
常用的名词解释
仓库
在 Maven 的术语中,仓库是一个位置,例如目录,可以存储所有的工程 jar 文件、library jar 文件、插件或任何其他的工程指定的文件。
Maven 仓库有三种类型,本地仓库,中央仓库,远程仓库
- 本地仓库(local)
Maven 本地仓库是机器上的一个文件夹。它在你第一次运行任何 maven 命令的时候创建。
Maven 本地仓库默认被创建在 %USER_HOME% 目录下。要修改默认位置,在 %M2_HOME%\conf 目录中的 Maven 的 settings.xml 文件中定义另一个路径。
<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>C:/MyLocalRepository</localRepository>
</settings>
- 中央仓库(central)
Maven 中央仓库是由 Maven 社区提供的仓库,其中包含了大量常用的库。
中央仓库的关键概念:
- 这个仓库由 Maven 社区管理。
- 不需要配置。
- 需要通过网络才能访问。
要浏览中央仓库的内容,maven 社区提供了一个 URL:http://search.maven.org/#browse。使用这个仓库,开发人员可以搜索所有可以获取的代码库。
- 远程仓库(remote)
如果 Maven 在中央仓库中也找不到依赖的库文件,它会停止构建过程并输出错误信息到控制台。为避免这种情况,Maven 提供了远程仓库的概念,它是开发人员自己定制仓库,包含了所需要的代码库或者其他工程中用到的 jar 文件。
Maven 依赖搜索顺序
当我们执行 Maven 构建命令时,Maven 开始按照以下顺序查找依赖的库:
步骤 1 - 在本地仓库中搜索,如果找不到,执行步骤 2,如果找到了则执行其他操作。
步骤 2 -在中央仓库中搜索,如果找不到,并且有一个或多个远程仓库已经设置,则执行步骤 4,如果找到了则下载 到本地仓库中已被将来引用。
步骤 3 -如果远程仓库没有被设置,Maven 将简单的停滞处理并抛出错误(无法找到依赖的文件)。
步骤 4 - 在一个或多个远程仓库中搜索依赖的文件,如果找到则下载到本地仓库已被将来引用,否则 Maven 将停止 处理并抛出错误(无法找到依赖的文件)。
坐标
在Maven中,坐标是Jar包的唯一标识,Maven通过坐标在仓库中找到项目所需的Jar包。
如下代码中,groupId和artifactId构成了一个Jar包的坐标。
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.1.1</version>
</dependency>
groupId:所需Jar包的项目名
artifactId:所需Jar包的模块名
version:jar包的版本号
构建生命周期
一个典型的 Maven 构建生命周期是由以下几个阶段的序列组成的:
阶段 | 处理 | 描述 |
---|---|---|
prepare-resources | 资源拷贝 | 本阶段可以自定义需要拷贝的资源 |
compile | 编译 | 本阶段完成源代码编译 |
package | 打包 | 本阶段根据 pom.xml 中描述的打包配置创建 JAR / WAR 包 |
install | 安装 | 本阶段在本地 / 远程仓库中安装工程包 |
当需要在某个特定阶段之前或之后执行目标时,可以使用 pre 和 post 来定义这个目标。
当 Maven 开始构建工程,会按照所定义的阶段序列的顺序执行每个阶段注册的目标。Maven 有以下三个标准的生命周期:
- clean
- default(or build)
- site
目标表示一个特定的、对构建和管理工程有帮助的任务。它可能绑定了 0 个或多个构建阶段。没有绑定任何构建阶段的目标可以在构建生命周期之外被直接调用执行。
执行的顺序依赖于目标和构建阶段被调用的顺序。例如,考虑下面的命令。clean 和 package 参数是构建阶段,而 dependency:copy-dependencies 是一个目标。
mvn clean dependency:copy-dependencies package
这里的 clean 阶段将会被首先执行,然后 dependency:copy-dependencies 目标会被执行,最终 package 阶段被执行。
传递依赖 与 排除依赖
- 传递依赖:如果我们的项目引用了一个Jar包,而该Jar包又引用了其他Jar包,那么在默认情况下项目编译时,Maven会把直接引用和简洁引用的Jar包都下载到本地。
- 排除依赖:如果我们只想下载直接引用的Jar包,那么需要在pom.xml中做如下配置:(将需要排除的Jar包的坐标写在中)
<exclusions>
<exclusion>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</exclusion>
</exclusions>
依赖冲突
若项目中多个Jar同时引用了相同的Jar时,会产生依赖冲突,但Maven采用了两种避免冲突的策略,因此在Maven中是不存在依赖冲突的。
- 短路优先
若本项目引用了A.jar,A.jar又引用了B.jar,B.jar又引用了X.jar,并且C.jar也引用了X.jar。
在此时,Maven只会引用引用路径最短的Jar。
本项目——>A.jar——>B.jar——>X.jar
本项目——>C.jar——>X.jar
- 声明优先
若引用路径长度相同时,在pom.xml中谁先被声明,就使用谁。
聚合
-
什么是聚合?
将多个项目同时运行就称为聚合。 -
如何实现聚合?
只需在pom中作如下配置即可实现聚合:
<modules>
<module>../模块1</module>
<module>../模块2</module>
<module>../模块3</module>
</modules>
继承
-
什么是继承?
在聚合多个项目时,如果这些被聚合的项目中需要引入相同的Jar,那么可以将这些Jar写入父pom中,各个子项目继承该pom即可。 -
如何实现继承?
- 父pom配置:将需要继承的Jar包的坐标放入标签即可。
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.2.2</version>
</dependency>
</dependencies>
</dependencyManagement>
子pom配置:
<parent>
<groupId>父pom所在项目的groupId</groupId>
<artifactId>父pom所在项目的artifactId</artifactId>
<version>父pom所在项目的版本号</version>
</parent>
scope的分类
1.compile:scope的默认值 他表示被依赖项目需要参与当前项目的编译,还有后续的测试,运行周期也参与其中,是一个比较强的依赖。打包的时候通常需要包含进去
2.test:依赖项目仅仅参与测试相关的工作,包括测试代码的编译和执行,不会被打包,例如:junit
3.runtime:表示被依赖项目无需参与项目的编译,不过后期的测试和运行周期需要其参与。与compile相比,跳过了编译而已。例如JDBC驱动,适用运行和测试阶段
4.provided:打包的时候可以不用包进去,别的设施会提供。事实上该依赖理论上可以参与编译,测试,运行等周期。相当于compile,但是打包阶段做了exclude操作
5.system:从参与度来说,和provided相同,不过被依赖项不会从maven仓库下载,而是从本地文件系统拿。需要添加systemPath的属性来定义路径
快照 -SNAPSHOT
快照是一个特殊的版本,它表示当前开发的一个副本。与常规版本不同,Maven 为每一次构建从远程仓库中检出一份新的快照版本。对于普通版本,Maven 一旦下载了指定的版本(例如 data-service:1.0),它将不会尝试从仓库里再次下载一个新的 1.0 版本。想要下载新的代码,数据服务版本需要被升级到 1.1。但是对于快照,Maven 每次都会自动获取最新的快照(data-service:1.0-SNAPSHOT)。
常用命令
-
新建一个Maven项目
方法a. 按照提示信息输入group-id,artifact-id,version即可
mvn archetype:generate
方法b.直接在命令行指定 group-id,artifact-id,version
mvn archetype:generate -DgroupId=otowa.user.dao -DartifactId=user-dao -Dversion=0.01-SNAPSHOT
2. 编译源代码
mvn compile
3.编译测试代码:
mvn test-compile
4.自动下载源码
mvn dependency:sources
5.安装第三方jar包
方法a:先安装再引入
步骤一:在maven中安装第三方jar包
mvn install:install-file -DgroupId=com -DartifactId=client -Dversion=0.1.0 -Dpackaging=jar -Dfile=D:\client.jar
步骤二:在pom.xml中引入第三方jar
<dependency>
<groupId>com</groupId>
<artifactId>client</artifactId>
<version>0.1.0</version>
</dependency>
方法b: 直接在pom.xml中指明第三方的jar包位置,然后引入依赖
还有一种简便的引入第三方jar包的方式,在src目录下新建一个lib文件夹,然后将jar包导入进去,最后在pom.xml文件中引入即可
<dependency>
<groupId>ldapjdk</groupId>
<artifactId>ldapjdk</artifactId>
<scope>system</scope>
<version>1.0</version>
<systemPath>${basedir}\src\lib\ldapjdk.jar</systemPath>
</dependency>
6. 运行测试:
mvn test
7. 产生site:
mvn site
8. 打包:
mvn package
9. 在本地Repository中安装jar:
mvn install
例:installing D:\xxx\xx.jar to D:\xx\xxxx
10. 清除产生的项目:
mvn clean
命令执行完后会删除target目录
11. 生成eclipse项目:
mvn eclipse:eclipse
12. 生成idea项目:
mvn idea:idea
13. 组合使用goal命令,如只打包不测试:
mvn -Dtest package
14. 编译测试的内容:
mvn test-compile
15. 只打jar包:
mvn jar:jar
16. 只测试而不编译,也不测试编译:
mvn test -skipping compile -skipping test-compile
( -skipping 的灵活运用,当然也可以用于其他组合命令)
17. 清除eclipse的一些系统设置:
mvn eclipse:clean
18.查看当前项目已被解析的依赖:
mvn dependency:list
19.上传到私服:
mvn deploy
20. 强制检查更新,由于快照版本的更新策略(一天更新几次、隔段时间更新一次)存在,如果想强制更新就会用到此命令:
mvn clean install-U
21. 源码打包:
mvn source:jar
或
mvn source:jar-no-fork
Maven常见问题
1.如何将普通的Maven项目导入Eclipse
问题描述:直接将原始的Maven项目到Eclipse是行不通的,因为没有.project和 .classpath这两个文件
问题解决:只需要一个简单的命令即可,执行命令后,即可在Eclipse中以Existing Maven Projects的方式导入了
mvn eclipse:eclipse
拷贝Maven依赖jar包到指定目录
mvn dependency:copy-dependencies -DoutputDirectory=lib
参考文章:http://blog.csdn.net/u010425776/article/details/52027706
https://blog.csdn.net/cd18333612683/article/details/66478332