1. 创建一个maven项目
-
使用Idea创建一个maven项目
- File>New>Project,
- 左侧选择Maven,右侧选择Project SDK为1.8,点击Next
- 输入项目GroupId、ArtifactId,点击Next
- 点击Finish
-
项目目录结构
|demo |src |main |java # 源码目录 |resources # 资源目录 |test |java # 测试源码目录 |pom.xml # 项目配置文件
-
pom文件
<?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.john.example</groupId> <artifactId>demo1</artifactId> <version>1.0-SNAPSHOT</version> </project>
2. 约定优于配置
-
项目目录结构遵循约定
创建的maven空项目已经包含了一定的目录结构,需要开发者遵循这种目录约定,这是使用maven简洁配置需要付出的代价。目录 说明 {project.basedir} 存放pom文件和项目子模块 {project.basedir}/src/main/java 源码目录 {project.basedir}/src/main/resources 资源目录 {project.basedir}/src/test/java 测试源码目录 {project.basedir}/src/test/resources 测试资源目录 ${project.basedir}/target 包输出目录 ${project.basedir}/target/classes 编译输出目录 ${project.basedir}/target/test-classes 测试编译输出目录
3. pom文件
- 说明
POM(Project Object Model,项目对象模型)定义了项目的基本信息,用于描述项目如何构建、声明项目依赖。 -
简单配置
-
<?xml>
: xml头信息,定义xml文档的版本和编码方式。 -
<project>
: 所有pom.xml的根元素,声明了pom相关的命名空间和xsd元素。 -
<modelVersion>
: 指定当前pom模型的版本,对于maven2/3,只能是4.0.0。 -
<groupId>
: 定义当前maven项目隶属的实际项目。 -
<artifactId>
: 定义实际项目中的一个maven模块/项目。 -
<version>
: 定义maven项目当前所处的版本 -
groupId\artifactId\version
: 定义了一个项目基本的坐标。
-
-
其他配置
- 项目依赖
- 插件
- 执行目标
- 项目构建profile
4. maven坐标
- 说明
Maven定义了一组规则:世界上任何一个构件都可以使用Maven坐标唯一标识。
Maven坐标元素包括groupId
,artifactId
,version
,packaging
,classifier
。 -
坐标元素
-
groupId
: 定义当前maven项目隶属的实际项目。 -
artifactId
: 定义实际项目中的一个maven模块/项目。 -
version
: 定义maven项目当前所处的版本。 -
packaging
: 定义maven项目的打包方式。打包方式与生成构件的文件扩展名对应,默认为jar
, 常用的打包方式有jar
,war
,pom
。 -
classifier
: 帮助定义构建输出的附属构件。附属构件与主构件对应。如demo1-1.0-SNAPSHOT-sources
.jar这个构件,包含了主构件的源代码。不能直接定义项目的classifier,因为附属构件不是项目直接默认生成的,而是通过附加插件帮助生成的。
-
-
项目构件的文件名
- 一般规则为:
artifactId-version[-classifier].packaging
- 一般规则为:
5. maven依赖
-
使用maven怎么引入依赖?
-
如果要引入第三方jar包,需要知道jar的坐标,然后放入pom.xml中的
dependencies
元素中。
示例如下:<project> <dependencies> <!-- 添加依赖 --> <dependency> <groupId></groupId> <artifactId></artifactId> <version></version> <type></type> <scope></scope> <optional></optional> <exclusions> <exclusion></exclusion> <exclusion></exclusion> </exclusions> </dependency> </dependencies> </project>
-
dependencies
元素包含多个dependency
,每个dependency
代表项目依赖的一个构件信息。 -
dependency
元素中的groupId
,artifactId
,version
定义了一个构件的基本坐标。 -
type
被依赖构件的类型,对应于被依赖构件的packaging
。默认为jar
, 表示被依赖的构件是一个jar包。 -
scope
表示依赖的范围,参考 2.maven依赖范围。 -
optional
表示依赖是否可选,参考可选依赖。 -
exclusions
用来排除传递依赖。
-
-
maven依赖范围
依赖范围就是用来控制依赖与三种classpath(编译classpath,运行classpath,测试classpath【编译测试代码、运行测试代码】)的关系。
-
compile
: 编译依赖范围。如果未指定,默认使用该依赖范围。对于编译、测试、运行3种classpath都有效。比如spring-web。 -
test
: 测试依赖范围。只对测试classpath有效,在编译主代码、运行项目时无法使用此依赖。比如JUnit。 -
provided
: 已提供依赖范围。对于编译、测试classpath有效,但在运行时无效。比如servlet-api,在运行项目的时候容器已经提供了。 -
runtime
: 运行时依赖范围。对于测试、运行classpath有效,但在编译主代码时无效。比如jdbc驱动实现,运行的时候才需要具体的jdbc驱动实现。 -
system
: 系统依赖范围。该依赖与三种classpath的关系,和provided依赖范围完全一致。但是,使用system范围的依赖时必须通过systemPath元素显示指定依赖文件的路径。建议谨慎使用。<dependency> <groupId>com.john</groupId> <artifactId>rt</artifactId> <version>1.8</version> <scope>system</scope> <systemPath>${java.home}/lib/rt.jar</systemPath> </dependency>
-
import
: 导入依赖范围。在maven依赖和dependencyManagement时候用到。
-
-
依赖范围与classpath的关系
依赖范围
(scope)对于编译classpath有效 对于测试classpath有效 对于运行classpath有效 举例 compile Y Y Y spring-web test -- Y -- JUnit provided Y Y -- servlet-api runtime -- Y Y JDBC驱动实现 system Y Y -- 本地的jar包 -
scope与运行classpath
scope如果对于运行范围有效,是指依赖的jar包会被打包到项目的运行包中,最后运行的时候会被添加到classpath中运行。
如果scope对于运行项目无效,那么项目打包的时候,这些依赖不会被打包到运行包中。
6. 传递性依赖
-
说明
- 在项目中引入groupId:junit, artifactId:junit, version:4.12, scope:test的依赖,查看项目依赖,发现项目依赖junit,而junit又依赖org.hamcrest:hamcrest-core:1.3,该依赖也被自动加进来,这个叫做依赖的传递。
-
假设
A依赖于B,B依赖于C,我们说A对于B是第一直接依赖
,B对于C是第二直接依赖
,而A对于C是传递性依赖
。 - 第一直接依赖的范围和第二直接依赖的范围决定了传递依赖的范围。
-
依赖范围对传递性依赖的影响
第一直接依赖 \
第二直接依赖compile test provided runtime compile compile -- -- runtime test test -- -- test provided provided -- provided provided runtime runtime -- -- runtime
7. 依赖调解
-
第一原则:路径近者优先。
-
A->B->C->Y(1.0),A->D->Y(2.0)
,Y的2.0版本距离A更近一些,所以maven会选择2.0
-
-
第二原则:第一声明者优先。
-
A->B->Y(1.0),A->D->Y(2.0)
,Y的1.0版先声明,所以maven会选择1.0版本。
-
8. 可选依赖
A->B, scope:compile
B->X, scope:compile,optional:true
B->Y, scope:compile,optional:true
- X、Y是可选依赖,依赖不会由B传至A。X、Y不会对A造成影响。
- 理想情况下,不应该使用可选依赖。
9. 依赖管理最佳实践
-
排除依赖
-
前提
A->B, scope:compile B->C, scope:compile
- 目的:A不想引入传递性依赖C
- 使用
exclusions
元素声明排除依赖,exclusions
元素可以包含多个exclusion
元素。 - 声明
exclusion
元素时只需要groupId
和artifactId
-
-
归类依赖
-
使用
properties
元素定义maven属性<properties> <springframework.version>5.2.1.RELEASE</springframework.version> </properties>
-
-
优化依赖
-
查看当前项目的已解析依赖(Resolved Dependency)
john:demo1 john$ mvn dependency:list [INFO] Scanning for projects... [INFO] [INFO] ---------------------------< com.john:demo1 >--------------------------- [INFO] Building demo1 1.0-SNAPSHOT [INFO] --------------------------------[ jar ]--------------------------------- [INFO] [INFO] --- maven-dependency-plugin:2.8:list (default-cli) @ demo1 --- [INFO] [INFO] The following files have been resolved: [INFO] org.hamcrest:hamcrest-core:jar:1.3:test [INFO] org.springframework:spring-beans:jar:5.2.1.RELEASE:compile [INFO] org.springframework:spring-core:jar:5.2.1.RELEASE:compile [INFO] org.springframework:spring-jcl:jar:5.2.1.RELEASE:compile [INFO] junit:junit:jar:4.12:test [INFO] org.springframework:spring-web:jar:5.2.1.RELEASE:compile [INFO] [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 0.905 s [INFO] Finished at: 2019-12-14T18:34:26+08:00 [INFO] ------------------------------------------------------------------------
-
查看当前项目的依赖树
john:demo1 john$ mvn dependency:tree [INFO] Scanning for projects... [INFO] [INFO] ---------------------------< com.john:demo1 >--------------------------- [INFO] Building demo1 1.0-SNAPSHOT [INFO] --------------------------------[ jar ]--------------------------------- [INFO] [INFO] --- maven-dependency-plugin:2.8:tree (default-cli) @ demo1 --- [INFO] com.john:demo1:jar:1.0-SNAPSHOT [INFO] +- org.springframework:spring-web:jar:5.2.1.RELEASE:compile [INFO] | +- org.springframework:spring-beans:jar:5.2.1.RELEASE:compile [INFO] | \- org.springframework:spring-core:jar:5.2.1.RELEASE:compile [INFO] | \- org.springframework:spring-jcl:jar:5.2.1.RELEASE:compile [INFO] \- junit:junit:jar:4.12:test [INFO] \- org.hamcrest:hamcrest-core:jar:1.3:test [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 0.938 s [INFO] Finished at: 2019-12-14T18:35:31+08:00 [INFO] ------------------------------------------------------------------------
-
分析当前项目的依赖
john:demo1 john$ mvn dependency:analyze [INFO] Scanning for projects... [INFO] [INFO] ---------------------------< com.john:demo1 >--------------------------- [INFO] Building demo1 1.0-SNAPSHOT [INFO] --------------------------------[ jar ]--------------------------------- [INFO] [INFO] >>> maven-dependency-plugin:2.8:analyze (default-cli) > test-compile @ demo1 >>> [INFO] [INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ demo1 --- [WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent! [INFO] skip non existing resourceDirectory /Users/john/Desktop/demo1/demo1/src/main/resources [INFO] [INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ demo1 --- [INFO] Nothing to compile - all classes are up to date [INFO] [INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ demo1 --- [WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent! [INFO] skip non existing resourceDirectory /Users/john/Desktop/demo1/demo1/src/test/resources [INFO] [INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ demo1 --- [INFO] Nothing to compile - all classes are up to date [INFO] [INFO] <<< maven-dependency-plugin:2.8:analyze (default-cli) < test-compile @ demo1 <<< [INFO] [INFO] [INFO] --- maven-dependency-plugin:2.8:analyze (default-cli) @ demo1 --- [WARNING] Unused declared dependencies found: [WARNING] org.springframework:spring-web:jar:5.2.1.RELEASE:compile [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 1.285 s [INFO] Finished at: 2019-12-14T18:41:43+08:00 [INFO] ------------------------------------------------------------------------
-
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。