J2EE开发笔记(四)—— pom.xml文件详解

1. pom.xml简介

POM是Project Object Model的缩写,pom.xml 则是每一个Maven工程必备的文件之一。我们这里引用官网上对POM的简介。

A Project Object Model or POM is the fundamental unit of work in Maven. It is an XML file that contains information about the project and configuration details used by Maven to build the project. Some of the configuration that can be specified in the POM are the project dependencies, the plugins or goals that can be executed, the build profiles, and so on. Other information such as the project version, description, developers, mailing lists and such can also be specified. POM stands for "Project Object Model". It is an XML representation of a Maven project held in a file named pom.xml . In fact, in the Maven world, a project need not contain any code at all, merely a pom.xml.

如果你想更加深入地了解 pom.xml 文件的方方面面,强烈推荐你阅读官方的参考文档: Introduction to the POMPOM Reference

2. pom.xml实战

下面,我们以一个实际项目中的 pom.xml 文件作为实战案例,分析里面所有元素和属性的含义和用法。我们会以xml文件注释的形式进行分析和说明。我们本次实战是基于一个最基本的Maven项目场景,不可能涵盖所有的Maven配置元素,我们会在 Maven开发笔记 系列博客中,对Maven做更加深入的学习和研究。本次实战的 pom.xml 文件如下:

<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">
    
    <!-- xml文件中,定义命名空间的格式为:xmlns:namespace-prefix="namespaceURI"
        定义默认命名空间的格式为:xmlns="namespaceURI" -->
    <!-- pom文件本身就是一个xml文件,最高级别的元素就是project元素,该元素定义了如下属性:
        xmlns:定义了该元素下的所有子元素的默认命名空间为:http://maven.apache.org/POM/4.0.0
        xmlns:xsi:定义了一个namespace-prefix,其代表的命名空间URI为:http://www.w3.org/2001/XMLSchema-instance
            定义该namespace-prefix主要是为了使用其所代表的命名空间中的schemaLocation属性时,比较简洁
            其中,使用xsi作为namespace-prefix,并不是硬性规定,只是大家都这么用,方便阅读理解,
            当然了,如果你执意要改成别的命名,也是可以的
        xsi:schemaLocation:该属性的使用格式为:xsi:schemaLocation="namespaceURI1 schemaURI1 namespaceURI2 schemaURI2 ..."
            其表示的意思是,使用schemaURI1所对应的schema文件,校验命名空间namespaceURI1下的元素,schemaURIN以此类推 -->
    
    <!-- Maven项目基本信息,即项目坐标定义 BEGIN-->
    <!-- modelVersion 指定了当前POM模型的版本,对于Maven2 及Maven3 来说,只能是4.0.0 -->    
    <modelVersion>4.0.0</modelVersion>
    <!-- groupId 表明其所属组织或公司,有时候会加上所属的项目,命名规则为组织或公司域名反转,或者再加项目名称 -->
    <groupId>top.qiumengchen</groupId>
    <!-- artifactId 项目的模块名,有时候和项目名保持一致,有时候为"项目名-模块名" -->
    <artifactId>basement</artifactId>
    <!-- version 当前项目的版本号,SHAPSHOT意为快照,说明该项目还处于开发中 -->
    <version>0.0.1-SNAPSHOT</version>
    <!-- packaging 定义项目的打包方式,常用可选值:jar、war、pom等,默认方式为jar -->
    <packaging>war</packaging>
    <!-- name 声明了一个对于用户更加友好的项目名称,非必须项 -->
    <name>My Basement Maven Project</name>
    <!-- Maven项目基本信息,即项目坐标定义 END-->
    
    <!-- 属性定义 BEGIN-->
    <!-- properties 通过该元素,用户可以自定义一个或多个Maven属性,然后在POM的其他地方
        使用${属性名称}的方式引用该属性,从而消除重复,保证文件的一致性 -->
    <properties>
        <project.build.encoding>UTF-8</project.build.encoding>
        <springframework.version>3.2.1.RELEASE</springframework.version>
    </properties>
    <!-- 属性定义 END-->
    
    <!-- 依赖定义 BEGIN-->
    <dependencies>
        <!-- groupId、artifactId、version 元素的含义同Maven项目基本信息中的对应元素含义一致
            type 指依赖的类型,对应于项目坐标定义的packaging,其默认值为jar
            scope 依赖的作用范围,例如:compile、test、provided、runtime、system,默认compile
            optional 标记依赖是否可选,主要在该项目被其他项目依赖的时候起作用,取值有:true、false。默认false
            exclusions 用来排除传递性依赖,用于排除某些不需要或不想要的特定依赖 -->
            
        <!-- SpringFramework 相关依赖 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>${springframework.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
            <version>${springframework.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>${springframework.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
            <version>${springframework.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-orm</artifactId>
            <version>${springframework.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
            <version>${springframework.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>${springframework.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${springframework.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>${springframework.version}</version>
            <scope>test</scope>
        </dependency>
        
        <!-- Apache Commons相关依赖 -->
        <!-- dbcp组件,提供数据库连接池功能 -->
        <dependency>
            <groupId>commons-dbcp</groupId>
            <artifactId>commons-dbcp</artifactId>
            <version>1.4</version>
        </dependency>
        <!-- fileupload组件,提供文件上传、下载等功能 -->
        <dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
            <version>1.3.1</version>
        </dependency>
        <!-- lang组件,提供对Java核心类库,特别是java.lang类库的扩展,提供了很多便利的方法 -->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.4</version>
        </dependency>
        
        <!-- 日志工具,log4j和commons-logging配合使用,效果最佳 -->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.14</version>
        </dependency>
        <!-- 使用slf4j接管commons-logging的职责,替换系统中已经存在的日志系统 -->
        <!-- slf4j核心jar包 -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.6.6</version>
        </dependency>
        <!-- 接管commons-logging的职责,使用common-loggin的接口,底层还是由SLF4J来决定哪种实现机制 -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>jcl-over-slf4j</artifactId>
            <version>1.6.6</version>
            <scope>runtime</scope>
        </dependency>
        <!-- 使用SLF4J的接口,底层由log4j实现 -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.6.6</version>
            <scope>runtime</scope>
        </dependency>
        
        <!-- JUnit 依赖 -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.8.1</version>
            <scope>test</scope>
        </dependency>
        
        <!-- 数据库相关依赖 -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>2.3.5</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.0.8</version>
            <scope>runtime</scope>
        </dependency>
                        
        <!-- fge json schema begin -->
         <dependency>  
            <groupId>com.fasterxml.jackson.core</groupId>  
            <artifactId>jackson-core</artifactId>  
            <version>2.3.0</version>    
        </dependency>  
        <dependency>  
            <groupId>com.fasterxml.jackson.core</groupId>  
            <artifactId>jackson-databind</artifactId>  
            <version>2.3.0</version>    
        </dependency>  
        <dependency>  
            <groupId>com.github.fge</groupId>  
            <artifactId>json-schema-validator</artifactId>  
            <version>2.2.6</version>    
        </dependency>  
        <!-- fge json schema end -->
        
    </dependencies>
    <!-- 依赖定义 END-->
  
    <!-- Maven打包参数 BEGIN -->
    <profiles>
        <!-- profile 可以让我们定义一系列的配置信息,然后指定其激活条件。
            可以定义多个profile,然后每个profile对应不同的激活条件和配置信息,
            从而达到不同情况下使用不同配置信息的效果。
            激活条件包括但不仅限于:不同JDK,不同操作系统信息,显式指定激活profile的id -->
        <profile>
            <id>development</id>
            <properties>
                <env>development</env>
            </properties>
        </profile>
        <profile>
            <id>beta</id>
            <properties>
                <env>beta</env>
            </properties>
        </profile>
        <profile>
            <id>production</id>
            <properties>
                <env>production</env>
            </properties>
        </profile>
    </profiles>
    <!-- Maven打包参数 END -->
    
    <!-- Maven编译设置 BEGIN -->
    <build>
        <!-- finalName 指定了最终构建的文件的名称格式,默认继承Maven默认父POM设定,即artifactId-version -->
        <finalName>basement</finalName>
        <!-- profile、filter、resource元素结合实现生成不同的发布包时,对资源进行不同的替换操作
        下面这段配置以及结合profile的配置表示:
        对src/main/resources下的资源进行过滤,过滤时采用的过滤文件为filter元素指定的文件,
        其中${env}是由编译时通过-P指定的profile决定的,
        过滤即指,使用filter中定义的变量的value替换src/main/resources目录下相同key变量的value -->
        <filters>
            <filter>vars/var.${env}.properties</filter>
        </filters>
        <resources>
            <resource>
                <directory>src/main/resources</directory>
                <filtering>true</filtering>
            </resource>
        </resources>
        <!-- 插件管理 -->
        <plugins>
            <!-- 配置编译Java代码插件,source指定编译Java 1.6版本的源文件,target指定生成与JVM 1.6兼容
                的字节码文件,encoding指定编译时采用的编码为UTF-8 -->
            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.3.2</version>
                <configuration>
                    <source>1.6</source>
                    <target>1.6</target>
                    <encoding>${project.build.encoding}</encoding>
                </configuration>
            </plugin>
            <!-- 配置处理资源文件的方式,encoding指定处理时采用的编码为UTF-8 -->
            <plugin>
                <artifactId>maven-resources-plugin</artifactId>
                <version>2.4</version>
                <configuration>
                    <encoding>${project.build.encoding}</encoding>
                </configuration>
            </plugin>
        </plugins>    
    </build>
    <!-- Maven编译设置 END -->
</project>

3. 总结

我们本次实战所采用的 pom.xml 文件比较简单,仅仅涵盖了Maven常用的配置元素。我们会在 Maven开发笔记 系列博客中进行更加详细深入的分析和研究。如果大家有任何疑问或建议,欢迎留言或评论,希望我们在相互讨论、学习中一起进步。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,214评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,307评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,543评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,221评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,224评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,007评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,313评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,956评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,441评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,925评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,018评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,685评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,234评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,240评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,464评论 1 261
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,467评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,762评论 2 345

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,599评论 18 139
  • 前言什么是 POMQuick Overview POM 常用元素 pom.xml 完整注释 参考 0 前言 什么是...
    seyvoue阅读 12,575评论 1 36
  • 1数量与质量 一个人非常执着于把一个想法变得非常完美的时候,往往会走入死胡同 就像我一直想写文章,想写自己的总结,...
    L雁小七阅读 221评论 0 0
  • 多少人连个真心话都不敢讲?连个真实感受都不能与人言,太害怕失去了,反而失去了自己,失去了自己,还有什么?建立的底座...
    纵情嬉戏天地间阅读 218评论 0 0
  • 渣男,顾名思义,不是我们所说的坏男人,坏男人可能只是三观不正,而渣男却完全是人品问题。坏男人虽坏但也许不渣,但有些...
    Lady_Jeline阅读 4,602评论 0 9