Maven从入门到入土-项目管理工具
前言Maven是我们经常用到的一个项目管理工具,但是我们有没有真正的对它进入了解呢?我是没有,所以才写下这篇博客来记录,我所知道的Maven知识,有不足的地方欢迎指正。认识Maven认识Maven从发音开始 美[ˈmeɪvn],中文谐音:美温,查了翻译后才知道我一直叫错了。在Maven官网中有一段关于他自己的介绍,下面只取一部分:The result is a tool that ...
文章目录
前言
Maven是我们经常用到的一个项目管理工具,但是我们有没有真正的对它进入了解呢?我是没有,所以才写下这篇博客来记录,我所知道的Maven知识,有不足的地方欢迎指正。
认识Maven
认识Maven
从发音开始 美[ˈmeɪvn]
,中文谐音:美温,查了翻译后才知道我一直叫错了。
在Maven官网中有一段关于他自己的介绍,下面只取一部分:
The result is a tool that can now be used for building and managing any Java-based project. We hope that we have created something that will make the day-to-day work of Java developers easier and generally help with the comprehension of any Java-based project.
Google翻译:
Maven是一个工具,现在可用于构建和管理任何基于Java的项目。
我们希望我们已经创建了一些东西,使Java开发人员的日常工作变得更加容易,并且通常有助于理解任何基于Java的项目。
Maven有以下主要特点:
- 构建工程项目简单、快捷
- 统一的依赖管理
- 丰富的插件功能
- 灵活的项目迁移
Maven的构建方式是使用:
POM(项目对象模型)来进行统一管理和构建,所以我们只需要阅读Maven的构建方式,那么你就会了解其他的Maven工程,那么以后对于我们来说是非常节省时间的。
如何使用?
下载Maven:
http://maven.apache.org/download.cgi
然后在设置到电脑环境中,如果你是纯小白的话,建议在网上搜索Maven的安装教程,和JAVA很像,教程也很多。 点击直通车直接百度
配置好后,打开命令窗口,输入mvn --version
就可以看到当前的版本和其他信息了。
POM
pom是在Maven
中是以pom.xml
文件形式展现的。下面是最常用的Pom
标签:
<groupId>...</groupId>
<artifactId>...</artifactId>
<version>...</version>
- groupId :一般用公司域名如: cn.wenhaha
- artifactId : 功能名
- version: 版本
<packaging>...</packaging>
packaging
表示打包方式,默认为jar
,除此之外还有:pom
、maven-plugin
、ejb
、war
、ear
、rar
<dependencyManagement>...</dependencyManagement>
<dependencies>...</dependencies>
<dependency>...</dependency>
dependencyManagement
是一个依赖管理器,往往在整个项目中,只有父项目才能声明,当然这只是一种约束,你也可以在每个项目中,声明他。不过我不建议你这么做。 他的作用是:声明子项目需要用到的依赖包,但子项目中,不声明使用,也不会依赖某个包。这么说太抽象了,还是举个栗子。
父项目:pom.xml
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.37</version>
</dependency>
</dependencies>
</dependencyManagement>
子项目:poim.xml
<dependencies>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
</dependency>
</dependencies>
从上面的栗子中可以看出使用dependencyManagement
的好处有:
- 统一管理版本号
- 事先声明,子项目需要在引用,这样可以避免其他不需要的子项目也依赖。
dependencies
这个就没啥可说的,上面栗子也看到了,这是一个依赖声明,项目中所需要的依赖包,都要在它里面声明,才可以哦。
说到依赖,有个查看项目依赖命令建议大家能够记下来,这是经常在项目中使用的:
mvn dependency:tree
dependency
在dependencies
标签下,一般用于声明需要依赖哪些模块,不至于jar
包。
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<type>jar</type>
<scope>test</scope>
<optional>true</optional>
</dependency>
可以看出dependency
标签下有很多子标签,前面的3个,已经在上面说了,下面我们从type
开始慢慢说明。
-
Type
type
表示的是依赖的类型,默认为jar
,除此之外还有ejb-client
和test-jar
,当然不止于此,你也可以自定义一个type
哦。 -
scope
scope表示什么时候将这个依赖包加入到classPath
中去,换句话说,什么时候才让依赖包生效。其中有5个可选项,默认为:compile
- compile : 编译,这些依赖项将传播到依赖项目。
- provided: 也是编译时,但不同的是,在运行时,才编译,而且不具备传递性。
- runtime: 运行时,表示编译不需要依赖项,但是用于执行。它位于运行时和测试类路径中,但不是编译类路径。
- test: 测试的时候才使用,正常运行时不需要使用到,而且不具备传递性。
- system : 使用本地
jar
包,来依赖项目,不会在项目仓库中查找。所以要通过systemPath
来指定要依赖的文件。
-
optional
默认为false
,表示为项目直接是否依赖传递,如果为true
就带表不依赖,反之依赖,什么意思呢?
比如 A 项目 要依赖 B项目, 但是B项目是依赖C项目的,所以A依赖B时,也同时会依赖C,这时如果在B的optional
属性为true
那么A只会依赖B,不会把D也一起依赖进来。
传递性依赖
竟然说到依赖性关系,那么久要说下Maven
的依赖机制了。为什么要有传递性依赖呢?传递性依赖不仅可以控制依赖和三种classpath的关系,还可以对传递性依赖产生影响。
这一章节和Scope
下的5个属性相关,如果你直接跳到这里,可以往上面滑动一点点,就在上面的那一小节,可以回顾下,这5个属性的说明。
假设有3个项目,分别为A、B、C,他们直接的依赖关系如下图
那么 A和B是直接依赖关系,A和C是传递性依赖。
问题是A为什么会传递性依赖于C,当A的状态发展改变时,又是如何依赖的?之前说到有一个标签为:scope
那么就是通过这个标签来实现传递性依赖的。
下面的表格中,左边的一列是第一依赖,上面一行为第二依赖。 第一依赖是指 a->b为第一依赖,b->c是第二依赖,那么a->是传递依赖。
compile | test | provided | runtime | |
---|---|---|---|---|
compile | compile(*) | - | - | runtime |
test | test | - | - | test |
provided | provided | - | provided | provided |
runtime | runtime | - | - | runtime |
表格说明
- 当第二依赖的范围为compile时,不会改变第一依赖。始终被依赖。
- 当第二依赖的范围为test时,不会被传递性依赖。
- 当第二依赖的范围为provided,只有第一依赖为provided,才会被传递。
- 当第二依赖的范围为runtime,只有第一依赖为compile,传递依赖为runtime,其他不变。
排除依赖
还是上一个例子,A依赖B,B依赖C,那么A会依赖C,现在A不想依赖C,那么只需要把C给排除掉就可以了。
<dependency>
<groupId>com.demo</groupId>
<artifactId>project-b</artifactId>
<version>1.0</version>
<exclusions>
<exclusion>
<groupId>com.demo</groupId>
<artifactId>project-c</artifactId>
</exclusion>
</exclusions>
</dependency>
依赖仲裁
假设有这么一种情况,A依赖B和C,B依赖了C,那么MAVEN
到底是使用谁的C包呢?
第一原则:最短路径优先原则
从上图所示,A到C的路径是最短的,所以MAVEN
会选择依赖于A中的C包
如果在加个D包,使得路径相等会怎么样呢?
第二原则:第一声明优先原则
根据上图所示,A是先声明B的,随后在声明C,所以,A是会依赖于B的D包,不会依赖于C的D包。
生命周期
Maven
的生命周期是构建在插件的形式展现的,生命周期其实是算一个概念,在某个阶段运行什么。
Maven
分为三个阶段的生命周期:clean
、default
、site
每个生命周期里又有多个阶段。当执行某个阶段时,这个阶段的后面各个阶段也会依次执行。
Clean 生命周期
Phase | Description |
---|---|
pre-clean | 在实际项目清理之前执行 |
clean | 删除上一个版本生成的所有文件 |
post-clean | 执行完成项目清理后执行 |
Default 生命周期
由于Default的生命周期比较多,下面只列出几个常用的
Phase | Description |
---|---|
generate-resources | 生成包含在包中的资源 |
compile | 编译项目的源代码。 |
test | 使用合适的单元测试框架运行测试 |
package | 编译代码并将其打包, 例如JAR |
install | 将软件包安装到本地存储库中 |
Site 生命周期
Phase | Description |
---|---|
pre-site | 在实际项目站点生成之前执行所需的过程 |
site | 生成项目的站点文档 |
post-site | 执行完成站点生成所需的流程,并准备站点部署 |
site-deploy | 将生成的站点文档部署到指定的Web服务器 |
关于生命周期更多详情可以去查看官网:生命周期详解【官网】
超级POM
超级POM是Maven的默认POM,除非有明确的设置,否则所有的POM都继承与超级POM。
像Maven生成的
/ src / main / java
和/ src / test / java
等等其他路径,都是有超级POM来实现的。
超级POM的位置在:apache-maven-3.5.0\lib\maven-model-builder-3.5.0.jar包中。
pom-4.0.0.xml
<?xml version="1.0" encoding="UTF-8"?>
<project>
<modelVersion>4.0.0</modelVersion>
<repositories>
<repository>
<id>central</id>
<name>Central Repository</name>
<url>https://repo.maven.apache.org/maven2</url>
<layout>default</layout>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>central</id>
<name>Central Repository</name>
<url>https://repo.maven.apache.org/maven2</url>
<layout>default</layout>
<snapshots>
<enabled>false</enabled>
</snapshots>
<releases>
<updatePolicy>never</updatePolicy>
</releases>
</pluginRepository>
</pluginRepositories>
<build>
<directory>${project.basedir}/target</directory>
<outputDirectory>${project.build.directory}/classes</outputDirectory>
<finalName>${project.artifactId}-${project.version}</finalName>
<testOutputDirectory>${project.build.directory}/test-classes</testOutputDirectory>
<sourceDirectory>${project.basedir}/src/main/java</sourceDirectory>
<scriptSourceDirectory>${project.basedir}/src/main/scripts</scriptSourceDirectory>
<testSourceDirectory>${project.basedir}/src/test/java</testSourceDirectory>
<resources>
<resource>
<directory>${project.basedir}/src/main/resources</directory>
</resource>
</resources>
<testResources>
<testResource>
<directory>${project.basedir}/src/test/resources</directory>
</testResource>
</testResources>
<pluginManagement>
<!-- NOTE: These plugins will be removed from future versions of the super POM -->
<!-- They are kept for the moment as they are very unlikely to conflict with lifecycle mappings (MNG-4453) -->
<plugins>
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.3</version>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.2-beta-5</version>
</plugin>
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.8</version>
</plugin>
<plugin>
<artifactId>maven-release-plugin</artifactId>
<version>2.3.2</version>
</plugin>
</plugins>
</pluginManagement>
</build>
<reporting>
<outputDirectory>${project.build.directory}/site</outputDirectory>
</reporting>
<profiles>
<!-- NOTE: The release profile will be removed from future versions of the super POM -->
<profile>
<id>release-profile</id>
<activation>
<property>
<name>performRelease</name>
<value>true</value>
</property>
</activation>
<build>
<plugins>
<plugin>
<inherited>true</inherited>
<artifactId>maven-source-plugin</artifactId>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<inherited>true</inherited>
<artifactId>maven-javadoc-plugin</artifactId>
<executions>
<execution>
<id>attach-javadocs</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<inherited>true</inherited>
<artifactId>maven-deploy-plugin</artifactId>
<configuration>
<updateReleaseInfo>true</updateReleaseInfo>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>
迷你POM
在Maven中,对于POM最低要求如下:
- project 根标签
- modelVersion 设置为4.0.0,表示继承与超级POM 4.0.0版本
- groupId 项目组ID
- artifactId 项目名
- version 当前项目的版本
根据最低要求,写出的POM是下面这个样子的。
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.demo.app</groupId>
<artifactId>my-app</artifactId>
<version>1.0.0</version>
</project>
总结
Maven是个很强大的构建工具,熟悉的使用可以加快对项目的效率。同时也要理解他们直接的依赖关系,除此之外Maven的功能远不过于此。像自定义插件、自定义骨架等特性,在下期说吧。
更多推荐
所有评论(0)