当前位置:   article > 正文

Maven POM的艺术_pom文件左边有个蚂蚁

pom文件左边有个蚂蚁

Maven POM的艺术

Maven 知识的累积者

Maven 是为了简化 基于Java的项目的构建而生的。说到简化, 对于没有经历过复杂构建过程的人而言, 很难理解 Maven 的简化含义。为了了解 Maven 到底如何帮助我们 简化了项目构建。我们首先需要对Maven诞生之前的项目构建过程有一个大概的了解。

项目构建的先行者 Ant

在Maven 之前,程序员通常使用 ant 来构建 Java项目, ant 意即蚂蚁, 是Apache 基金会下的跨平台(基于JAVA)的构件工具。
每个ant项目都包含一个 ant脚本(默认是build.xml) , ant脚本中包含一个project标签, project 标签中包含多个 target标签, target标签中包含多个 task,task是一个标签组的概念,包含 usage, clean, javac,jar, sql,delete等众多具体标签, 每个task 标签有特定的用法,例如 delete 就是用于删除文件或路径的标签。
如下提供一个ant脚本的参考示例

<?xml version="1.0" encoding="GBK"?>
[code]<!-- 定义生成文件的project根元素,默认的target为空 -->
<project name="antQs" basedir="." default="">
<!-- 定义三个简单属性 -->
<property name="src" value="src"/>
<property name="classes" value="classes"/>
<property name="dest" value="dest"/>
<!-- 定义一组文件和目录集 -->
<path id="classpath">
     <pathelement path="${classes}"/>
</path>
<!-- 定义help target,用于输出该生成文件的帮助信息 -->
<target name="help" description="打印帮助信息">
     <echo>help - 打印帮助信息</echo>
     <echo>compile - 编译Java源文件</echo>
     <echo>run - 运行程序</echo>
     <echo>build - 打包JAR包</echo>
     <echo>clean - 清除所有编译生成的文件</echo>
</target>
<!-- 定义compile target,用于编译Java源文件 -->
<target name="compile" description="编译Java源文件">
     <!-- 先删除classes属性所代表的文件夹 -->
     <delete dir="${classes}"/>
     <!-- 创建classes属性所代表的文件夹 -->
     <mkdir dir="${classes}"/>
     <!-- 编译Java文件,编译后的class文件放到classes属性所代表的文件夹内 -->
     <javac destdir="${classes}" debug="true"
           deprecation="false" optimize="false" fail>
           <!-- 指定需要编译的Java文件所在的位置 -->
           <src path="${src}"/>
           <!-- 指定编译Java文件所需要第三方类库所在的位置 -->
           <classpath refid="classpath"/>
     </javac>
</target>
<!-- 定义run target,用于运行Java源文件,
     运行该target之前会先运行compile target -->
<target name="run" description="运行程序" depends="compile">
     <!-- 运行lee.HelloTest类,其中fork指定启动另一个JVM来执行java命令 -->
     <java classname="lee.HelloTest" fork="yes" fail>
           <classpath refid="classpath"/>
           <!-- 运行Java程序时传入2个参数 -->
           <arg line="测试参数1 测试参数2"/>
     </java>
</target>
<!-- 定义build target,用于打包JAR文件,
     运行该target之前会先运行compile target -->
<target name="build" description="打包JAR文件" depends="compile">
     <!-- 先删除dest属性所代表的文件夹 -->
     <delete dir="${dest}"/>
     <!-- 创建dest属性所代表的文件夹 -->
     <mkdir dir="${dest}"/>
     <!-- 指定将classes属性所代表的文件夹下的所有
           *.classes文件都打包到app.jar文件中 -->
     <jar destfile="${dest}/app.jar" basedir="${classes}"
           includes="**/*.class">
           <!-- 为JAR包的清单文件添加属性 -->
           <manifest>
                <attribute name="Main-Class" value="lee.HelloTest"/>
           </manifest>
     </jar>
</target>
<!-- 定义clean target,用于删除所有编译生成的文件 -->
<target name="clean" description="清除所有编译生成的文件">
     <!-- 删除两个目录,目录下的文件也一并删除 -->
     <delete dir="${classes}"/>
     <delete dir="${dest}"/>
</target>
</project>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68

可以想见,即便一个简单的项目,基本都需要经过 初始化,目录结构搭建, 编译, 打包等过程,而当你使用ant时,需要手动的定义每一个过程需要完成的工作,是比较繁琐的,特别是当项目比较大的时候, 你需要手动维护庞大的依赖群, 管理依赖之间的关系。

项目管理工具 Maven

与ant专注于构建不同,maven不仅支持了ant的全部功能,还在项目文件的管理中下了一番功夫。

  1. 首先, Maven提供了默认的文件结构 {PROJECT_HOME}/src/main/java , 因为该文件结构具有相当大的通用性, 且支持自定义。因而在搭建项目时,开发人员不再需要维护项目的目录结构
  2. 其次, Maven 内置了 更多的隐式规则, 包括构建流程,生命周期及其插件等,使得更加简单的构建项目的同时,也支持自定义项目构建流程。
  3. 添加了以 repository 和 dependency 为核心的 依赖管理,简化了依赖引用和存储。

探寻究竟, maven站在前人的基础上,意识到保持灵活的同时, 也需要做到简便, 默认的通用结构、构建规则、构建生命规则给Maven带来使用上的便利性。

作者注:
maven的成功也可以带给我们思考,在软件设计和开发的工作中,一个健壮的系统或者功能点,应该是具备灵活的构成后,充分考虑用户的使用场景和习惯,提供一套默认的规则以带来便利性。这样的设计和实现相信是具备更优秀的品质的。

下面, 展示一个简单项目的maven配置文件

<?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>cn.kerninventory</groupId>
    <artifactId>demo-maven</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

</project>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

相较ant脚本而言,显然更加的精简而小巧。
在这里插入图片描述
附图,maven的默认项目结构

摘录官网的一句话:

Maven的主要目标是允许开发人员在最短的时间内理解开发工作的完整状态。

什么是POM

POM 是 Project Object Mode 的缩写, 意即 项目对象模型。 在Maven中, 每个JAVA项目都拥有一个 pom.xml 的配置文件, pom 文件如同项目的身份卡,里面记录了该项目的信息。

  1. 唯一的索引值, Maven 项目通过POM文件中的 groupId, artifactId, version 组成项目的唯一索引值, 最终组成 groupId:artifactId:version 的键值
  2. 父子关系,maven支持项目的继承,通过指定标签中的内容,可以向上拥有父项目的一些信息和依赖关系。所有POM文件都默认继承了MAVEN官方定义的一个父级POM文件
  3. 依赖关系,maven提供了非常简便的依赖引用方式, 通过 标签可以维护多个依赖性, 你只需要声明依赖的索引即可,也就是上述的groupId, artifactId, version
  4. 构建细节,通常情况下,默认的构建规则就能满足需要,如果需要自定义构建细节,通过 标签可以进行自定义的配置。

如下展示一个简单项目的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 https://maven.apache.org/xsd/maven-4.0.0.xsd” >
  <!--当前唯一受支持的 POM 版本 -->
  <modelVersion> 4.0.0 </ modelVersion>
 
  <!--基础知识-->
  <groupId>com.test</ groupId>
  <artifactId>demo</ artifactId>
  <version>1.0.0-SNAPSHOT</ version>
  <packaging>jar</ packaging>
  <!--添加你需要的依赖项 -->
  <dependencies> 
    <dependency>
      	<groupId>com.test</ groupId>
  			<artifactId>demo-core</ artifactId>
  			<version>1.0.0-SNAPSHOT</ version>
    </dependency>
 </ dependencies>
  
  <!--构建设置-->
  <build> ... </ build>

</ project>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

定位/存储/使用 Maven的坐标系

如何通过尽量少的属性来维护大量的对象呢? 不仅要做好分类工作,还要知道对象的新旧情况。
maven运用了一些基础的数学知识来解决问题,通过建立一个三维坐标系来管理大量的项目对象。

在上文中,我们提到了POM文件的groupId, artifactId,version属性,

如果使用 groupId 作为横轴, artifactId作为竖轴, version作为纵轴, 那么我们可以在脑海中轻易构建如下图所示的这样一个结构
在这里插入图片描述
这就是在三维空间中定位的 三位笛卡尔坐标系模型。
如下套用官网的内容说明下三个属性:

  • groupId:这在组织或项目中通常是唯一的。例如,所有核心Maven工件都可以(当然,应该)位于groupId下org.apache.maven。组ID不一定使用点表示法,例如junit项目。注意,点号groupId不必与项目包含的包结构相对应。但是,遵循此做法是一种很好的做法。当存储在存储库中时,该组的行为与Java打包结构在操作系统中的行为非常相似。点被操作系统特定的目录分隔符(例如Unix中的“ /”)替换,该分隔符成为基础存储库中的相对目录结构。在给出的示例中,该org.codehaus.mojo组位于目录中$M2_REPO/org/codehaus/mojo
  • artifactId:artifactId通常是已知项目的名称。尽管groupId很重要,但是小组中的人们很少在讨论中提及groupId(他们通常都是相同的ID,例如MojoHaus项目的groupId :)org.codehaus.mojo。它与groupId一起创建了一个密钥,用于将该项目与世界上其他所有项目分开(至少,它应该:))。与groupId一起,artifactId完全定义了存储库中工件的居住区。对于上述项目,my-project居住在$M2_REPO/org/codehaus/mojo/my-project
  • version:这是命名难题的最后一部分。groupId:artifactId表示一个项目,但无法描述我们正在谈论的那个项目的具体化身。我们要junit:junit2018年版(4.12版)还是2007年版(3.8.2版)?简而言之:代码更改,应对这些更改进行版本控制,并且此元素使这些版本保持一致。它还可以在工件的存储库中使用,以将版本彼此分开。my-project版本1.0文件位于目录结构中$M2_REPO/org/codehaus/mojo/my-project/1.0
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小舞很执着/article/detail/1010503
推荐阅读
相关标签
  

闽ICP备14008679号