首先说明,本人并不是第一次学习maven,也不是第二次学习maven,为什么还要来学习写下这些东西?是因为之前一直都是通过视频或者百度进行学习,知识零散且不全面,甚至更有版本的知识穿插问题,故决定以官方文档为基础进行系统性学习。
什么是POM?
pom代表“项目对象模型”。它是名为pom.xml的文件中保存的Maven项目的XML表示。当有Maven的人在场时,谈论一个项目是在哲学意义上说的,而不仅仅是包含代码的文件集合。项目包含配置文件、所涉及的开发人员及其角色、缺陷跟踪系统、组织和许可证、项目所在位置的URL、项目的依赖项,以及所有其他可以提供代码生命的小部分。这是一个一站式商店,所有与项目有关的事情。事实上,在Maven世界中,一个项目根本不需要包含任何代码,只需要pom.xml。
POM 是用来项目的构成,就像介绍一个人是谁,在哪一样,不影响构建的生命周期。
一个最基本的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.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.codehaus.mojo</groupId>
<artifactId>my-project</artifactId>
<version>1.0</version>
<!-- 依赖父项目 -->
<parent>
<groupId>org.codehaus.mojo</groupId>
<artifactId>my-parent</artifactId>
<version>2.0</version>
<relativePath>../my-parent</relativePath>
</parent>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<type>jar</type>
<scope>test</scope>
<optional>true</optional>
</dependency>
</dependencies>
<packaging>war</packaging>
</project>
配置文档说明:
modelVersion 指定pom当前版本。
groupId: 组织或团队 eg: org.apache
artifactId: 项目或模块名 eg: spring
version: 当前软件的版本 eg:1.0.0
packaging: 项目投入到生产环境当中前,都需要对项目进行一系列的打包操作,所以需要指定打包成什么,eg:war、jar等等。默认
是jar,主要包类型:pom,jar,maven-plugin,ejb,war,ear,rar.
dependencies: 项目的依赖列表,maven会自动从maven仓库当中下载指定的jar包,groupId、artifactId、version的含义和上方的一模一样。
dependencies-type:指定文件的后缀扩展名,默认是jar
dependencies-scope:与处理任务时相关的类路径,如何限制依赖的传递性。有compile: 仅在编译期间提供;provided:编译器提供,并且说明到运行的时候希望jdk或者容器提供它。runtime:仅仅在执行期间提供,如jdbc的驱动。test:测试的编译和执行阶段提供。system:和provided相似,总是是可用的,不需要从仓库当中去查找。
dependencies-systemPath:仅仅在scope为system的时候用,否则构建就会报错。路径必须是绝对的,指定特定的系统路径,eg: ${JAVA_HOME},maven就不会从maven仓库当中查找,而是去 systemPath指定的路径查找。
depenpendencies-optional:当一个项目A依赖另一个项目B时,项目A可能很少一部分功能用到了项目B,此时就可以在A中配置对B的可选依赖。举例来说,一个类似hibernate的项目,它支持对mysql、oracle等各种数据库的支持,但是在引用这个项目时,我们可能只用到其对mysql的支持,此时就可以在这个项目中配置可选依赖,也就是说,所依赖的项目可能下载也可能下载。
配置可选依赖的原因:1、节约磁盘、内存等空间;2、避免license许可问题;3、避免类路径问题,等等。
depenpendencies-exclusion:排除依赖,明确不依赖、不下载。
项目依赖
当项目的packaging设置为pom的时候,常常用于父工程或者聚合工程(多个项目模块)。pom可以继承的配置:groupId version description url inceptionYear
organization licenses developers contributors mailingLists scm issueManagement ciManagement properties dependencyManagement dependencies repositories pluginRepositories build plugin executions with matching ids plugin configuration etc. reporting profiles
不会继承的元素:artifactId name prerequisites
要注意的是:relativePath 并不是必须的,指明先在给出的路径中去查找,如果找不到才会去本地或者远程仓库当中查找。
超级pom(super pom)
所有的pom都会继承此pom,应当详细了解该pom,可以通过mvn help:effective-pom来查看最后打包的pom,因为这会影响构建的pom,该pom内容如下:
<project>
<modelVersion>4.0.0</modelVersion>
<repositories>
<repository>
<id>central</id>
<name>Central Repository</name>
<url>http://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>http://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>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.1</version>
</plugin>
<plugin>
<artifactId>maven-release-plugin</artifactId>
<version>2.0</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>
依赖管理(dependencyManagement)
资料参见:https://www.cnblogs.com/feibazhf/p/7886617.html
主要管理版本,对于子类继承同一个父类是很有用的,集中管理依赖版本不添加依赖关系,对于其中定义的版本,子pom不一定要继承父pom所定义的版本。
dependencies即使在子项目中不写该依赖项,那么子项目仍然会从父项目中继承该依赖项(全部继承)
dependencyManagement里只是声明依赖,并不实现引入,因此子项目需要显示的声明需要用的依赖。如果不在子项目中声明依赖,是不会从父项目中继承下来的;只有在子项目中写了该依赖项,并且没有指定具体版本,才会从父项目中继承该项,并且version和scope都读取自父pom;另外如果子项目中指定了版本号,那么会使用子项目中指定的jar版本。
eg:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>org.eclipse.persistence.jpa</artifactId>
<version>${org.eclipse.persistence.jpa.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>${javaee-api.version}</version>
</dependency>
</dependencies>
</dependencyManagement>