当前位置: 澳门新濠3559 > 编程 > 正文

在通过maven引入jar包的时候,pom包括了所有的项目

时间:2019-10-06 23:57来源:编程
之前学习maven知道,在通过maven引入jar包的时候,需要明确定义其坐标元素 groupId、artifactId、version、packaging、classfier ,从而确认具体的jar包信息,其中 groupId、artifactId、version 三要素一

之前学习maven知道,在通过maven引入jar包的时候,需要明确定义其坐标元素groupId、artifactId、version、packaging、classfier,从而确认具体的jar包信息,其中groupId、artifactId、version三要素一定不可缺失,可是有些POM中却没有引入包版本,却可以正常运行,例如下图,那么是为什么呢?

坐标

maven管理项目依赖的底层基础-坐标。坐标元素:groupId、artifactId、version、packaging、classifier。

<dependency>
         <groupId>org.apache.pig</groupId>
         <artifactId>pig</artifactId>
         <classifier>h2</classifier>
         <version>0.15.0</version>
         <scope>provided</scope>
</dependency>

groupId:定义当前maven项目隶属的实际项目。
artifactId:定义实际项目中的一个maven项目(模块),推荐的做法是使用实际项目名作为artifactId的前缀。
version:定义maven项目当前所处的版本。
packaging:定义maven项目的打包方式。默认使用jar。
classifier:定义用来帮助定义构建输出的一些附属构件。例如xxx-1.0-javadoc.jar和xxx-1.0-sources.jar就包含了java文档和源代码。注意:不能直接定义项目的classifier,因为附属构件不是项目直接默认生成的,而是由附加的插件帮助生成的。
groupId、artifactId、version是必须定义的,packaging是可选的,classifier是不能直接定义的。
项目构件的文件名一般的规则为artifactId-version [-classifier].packaging。

前言

本文转载自

澳门新濠3559 1image

依赖

  项目中用到了maven,而且用到的内容不像利用maven/eclipse搭建ssm(spring spring mvc mybatis)用的那么简单;maven的核心是pom.xml,那么我就它来谈谈那些不同的地方;

快速察看

我们猜测肯定是有哪个地方有明确的包版本说明,要不然就违背了Maven的规则其实在springboot的官方文档中也有具体解释这个没有设置包版本的原因,具体可看==>Spring Boot Docs

依赖配置

            <dependency>
                <groupId>org.apache.storm</groupId>
                <artifactId>storm-core</artifactId>
                <version>${storm.version}</version>
                <scope>provided</scope>
                <type>jar</type>
                <optional>true</optional>
                <exclusions>
                    <exclusion>
                        <groupId>org.slf4j</groupId>
                        <artifactId>slf4j-api</artifactId>
                    </exclusion>
                    <exclusion>
                        <groupId>org.slf4j</groupId>
                        <artifactId>slf4j-log4j12</artifactId>
                    </exclusion>
                </exclusions>
            </dependency>

type:依赖的类型,对应于项目坐标定义的packaging。
scope:依赖的范围。
optional:标记依赖是否可选。
exclusions:用来排除传递性依赖。

在通过maven引入jar包的时候,pom包括了所有的项目信息。  给我印象最深的就是如下四个元素:modules、parent、properties、import。

<project>
  <modelVersion>4.0.0</modelVersion>
<!--maven2.0必须是这样写,现在是maven2唯一支持的版本-->
  <!-- 基础设置 -->
  <groupId>...</groupId>
  <artifactId>...</artifactId>
  <version>...</version>
  <packaging>...</packaging>

  <name>...</name>

  <url>...</url>
  <dependencies>...</dependencies>
  <parent>...</parent>
  <dependencyManagement>...</dependencyManagement>
  <modules>...</modules>
  <properties>...</properties>

  <!--构建设置 -->
  <build>...</build>
  <reporting>...</reporting>

  <!-- 更多项目信息 -->
  <name>...</name>
  <description>...</description>
  <url>...</url>
  <inceptionYear>...</inceptionYear>
  <licenses>...</licenses>
  <organization>...</organization>
  <developers>...</developers>
  <contributors>...</contributors>

  <!-- 环境设置-->
  <issueManagement>...</issueManagement>
  <ciManagement>...</ciManagement>
  <mailingLists>...</mailingLists> 
  <scm>...</scm>
  <prerequisites>...</prerequisites>
  <repositories>...</repositories>
  <pluginRepositories>...</pluginRepositories>
  <distributionManagement>...</distributionManagement>
  <profiles>...</profiles>
</project>

接下来我们具体分析下其真正的原因

依赖范围

缘由:首先,maven在编译项目主代码的时候需要使用一套classpath,需要的文件以依赖的方式被引入到classpath中。其次,maven在编译和执行测试的时候会使用另外一套classpath。最后,实际运行maven项目的时候,又会使用一套classpath。
依赖范围就是用来控制依赖与这三种classpath(编译classpath、测试classpath、运行classpath)的关系。
compile:编译依赖范围。默认的依赖范围。对于编译、测试、运行三种classpath都有效。
test:测试依赖范围。只对测试classpath有效。
provided:已提供依赖范围。对于编译和测试classpath有效,但在运行时无效。例如servlet-api。
runtime:运行时依赖范围。对于测试和运行时classpath有效,对编译主代码时无效。例如:jdbc,编译时只需要jdk提供的jdbc接口,只有在执行测试或者运行项目的时候才需要实现该接口的具体jdbc驱动。
system:系统依赖范围。同provided依赖范围。使用时必须通过systemPath元素显式指定依赖的文件的路径。此依赖不是通过maven仓库解析的,往往与本机系统绑定。
import:导入依赖范围。不会对三种classpath产生实际的影响。与dependencyManagement有关。

澳门新濠3559 2

依赖范围与classpath的关系

modules

基本内容:

澳门新濠3559 3image

传递性依赖

假如A依赖于B,B依赖于C,那么A对于B第一直接依赖,B对于C是第二直接依赖,A对于C是传递性依赖。
依赖范围不仅可以控制依赖与三种classpath的关系,还对传递性依赖产生影响。

澳门新濠3559 4

依赖范围影响传递性依赖

注:左一列表示第一直接依赖范围,最上一行表示第二直接直接依赖范围,中间的交叉单元格则表示传递性依赖范围。

  从字面意思来说,module就是模块,而pom.xml中的modules也正是这个意思,用来管理同个项目中的各个模块;如果maven用的比较简单,或者说项目的模块在pom.xml没进行划分,那么此元素是用不到的;不过一般大一点的项目是要用到的。

pom包括了所有的项目信息

如上图,可以看到spring-boot-starter-tomcat是依赖自spring-boot-starters父maven的,其dependency中并没有明确的具体的jar包信息

依赖调解

第一原则:路径最近者优先。
第二原则:第一声明者优先。在依赖路径长度相等的前提下,在pom中依赖声明的顺序决定了谁会被解析使用,顺序最靠前的那个依赖优胜。

  1.需求场景

groupId:项目或组织的唯一标识,并且配置时生成路径也是由此生成。如org.myproject.mojo生成的相对路径为:/org/myproject/mojo

如下图,再看spring-boot-starters包,其父maven是spring-boot-parent

可选依赖

可选依赖,可能项目实现了两个特性,特性一依赖于X,特性二依赖于Y,而且这两个特性是互斥的,用户不可能同时使用两个特性。
可选依赖不会被传递,需要显式声明依赖。

    如果我们的项目分成了好几个模块,那么我们构建的时候是不是有几个模块就需要构建几次了(到每个模块的目录下执行mvn命令)?当然,你逐个构建没问题,但是非要这么麻烦的一个一个的构建吗,那么简单的做法就是使用聚合,一次构建全部模块。

artifactId:项目的通用名称

澳门新濠3559 5image

依赖冲突

  • 使用exclusion元素
  • 直接引入需要的依赖

  2.具体实现

version:项目的版本

如下图spring-boot-parent的父pom是spring-boot-dependencies,看到这里通过名字应该很清楚在spring-boot-dependencies中肯定包含了大部分默认的jar包版本约定

优化依赖

mvn dependency:list
mvn dependency:tree 详细了解项目中所有依赖的具体信息
mvn dependency:analyze 可以分析项目中使用到的,但没有显式声明的依赖;项目中未使用的,但显式声明的依赖。注意:只会分析编译主代码和测试代码需要用到的依赖,一些执行测试和运行时需要的依赖发现不了。

    a.既然使用聚合,那么就需要一个聚合的载体,先创建一个普通的maven项目account-aggregator,如下图:

packaging:打包机制。例如pom,jar,maven-plugin,ejb,war,ear,rar,par

澳门新濠3559 6image

仓库

本地仓库
远程仓库:中央仓库,私服,其他公共库

SNAPSHOT
RELEASE

  澳门新濠3559 7

name:用户描述项目的名称,无关紧要的东西,可选。

如下图的spring-boot-dependencies,并没有父POM

生命周期和插件

maven的生命周期是为了对所有的构建过程进行抽象和统一。这个生命周期包含了项目的清理、初始化、编译、测试、打包、集成测试、验证、部署和站点生成等几乎所有构建步骤。几乎所有项目的构建,都能映射到这样一个生命周期上。
maven的生命周期是抽象的,实际的任务都交由插件来完成。例如:maven-compiler-plugin针对编译的插件,maven-surefire-plugin针对测试的插件。

    因为是个聚合体,仅仅负责聚合其他模块,那么就只需要上述目录,该删除的就删了;注意的是pom文件的书写(红色标明的):

url:应该是只写明开发团队的网站,无关紧要,可选。

澳门新濠3559 8image澳门新濠3559 9image澳门新濠3559 10image

生命周期

maven有三套相互独立的生命周期,clean、default、site。clean生命周期的目的是清理项目,default生命周期的目的是构建项目,site生命周期的目的是建立项目站点。
每个生命周期包含一些阶段(phase),这些阶段是有顺序的,并且后面的阶段依赖于前面的阶段。执行某个阶段的时候,会顺序执行该阶段之前的所有阶段。

<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.youzhibing.account</groupId>
  <artifactId>account-aggregator</artifactId>
  <version>1.0.0-SNAPSHOT</version>
  <packaging>pom</packaging>

  <name>Account Aggrregator</name>
  <url>http://maven.apache.org</url>

  <modules>
    <!-- 模块都写在此处 -->
      <module>account-register</module>
      <module>account-persist</module>
  </modules>

</project>

classifer:分类,可选。

从上图可以看出在spring-boot-dependencies中利用dependencyManagement管理了所有的jar包现在也知道了spring-boot-starter-tomcat中的Tomcat版本是8.5.15

clean生命周期

pre-clean:执行一些清理前需要完成的工作
clean:清理上一次构建生成的文件
post-clean:执行一些清理后需要完成的工作

    b.创建子模account-register、account-persist:右击account-aggregator,new --> other --> Maven,选择Maven Module,创建moven模块。

其中,groupId artifactId version packaging组成了项目的唯一坐标,一般情况下,前面三个就可以组成唯一坐标。

dependencyManagement 和 dependencys 有什么区别么?主要的区别在于被dependencyManagement引入的jar包在子POM中不一定会引入,除非子类明确引入了才可以使用,而dependencys引入的jar包无论子POM是否有使用到都会引入进去的,这样可以做到避免引入没必要的jar包更多maven的知识可以看看maven 学习

default生命周期

validate
initialize
generate-sources
process-sources:处理项目主资源文件
generate-resources
process-resources
compile:编译项目的主源码
process-classes
generate-test-sources
process-test-sources:处理项目测试资源文件
generate-test-resources
process-test-resources
test-compile:编译项目的测试代码
process-test-classes
test:使用单元测试框架运行测试,测试代码不会被打包或部署
prepare-package
package:接受编译好的代码,打包成可发布的格式
pre-integration-test
integration-test
post-integration-test
verify
install:将包安装到maven本地仓库,供本地其他maven项目使用
deploy:将最终的包复制到远程仓库,供其他开发人员和maven项目使用

澳门新濠3559 11

 

site生命周期

pre-site:执行一些在生成项目站点之前需要完成的工作
site:生成项目站点文档
post-site:执行一些在生成项目站点之后需要完成的工作
site-deploy:将生成的项目站点发布到服务器上

    c.创建完成后,项目结构如下,那么此时account-aggregator可以收缩起来了,我们操作具体子模块就好了。

POM关系:主要为依赖、继承、合成。

命令行与生命周期

从命令行执行maven任务的最主要方式就是调用maven的生命周期阶段。
mvn clean
mvn test
mvn clean install
mvn clean deploy site-deploy

                          澳门新濠3559 12澳门新濠3559 13

 

插件

     d.注意点,当我们打开包结构的子模块的pom文件时,发现离预期的多了一些内容,我们坐下处理就好了。

dependency属性介绍

插件目标

每个插件有很多功能,每个功能就是一个插件目标。
例如:maven-dependency-plugin的插件目标有dependency:analyze,dependency:tree等。冒号前面是插件前缀,冒号后面是该插件的目标。

澳门新濠3559 14

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
    <version>3.1</version>
</dependency>

插件绑定

maven的生命周期与插件项目绑定,用以完成实际的构建任务。

    e.那么编码完了之后,我们只需要构建account-aggregator就好了,所有的子模块都会构建。

type:表示组件的类型,默认为jar。

插件配置

parent

scope:表示当前组件的依赖范围。

聚合和继承

  继承,和java中的继承相当,作用就是复用

optional:设置依赖是否可选,默认false,子项目默认都继承。如果设置为true,子项目必须显示引入。与dependencyManagement里定义的依赖类似。

聚合

    <modules>
        <module>cpspool_index_base</module>
        <module>cpspool_index_batch</module>
        <module>cpspool_index_realtime</module>
        <module>cpspool_index_batch_signal_node</module>
        <module>cpspool_index_batch_create_index_node</module>
        <module>cpspool_index_batch_node</module>
        <module>cpspool_index_batch_online_index_node</module>
    </modules>
  • 目标
    一次构建多个项目,而不是到多个项目目录下分别构建。
  • 打包方式
    对于聚合模块,其打包方式packaging的值必须是pom,否则无法构建。
  • 目录结构
    可以是父子关系,可以是平行关系。

  1.需求场景

exclusions:如果X需要A,A包含B依赖,则可以用此属性声明exclusion。

继承

    <parent>
        <artifactId>union_cpspool_index</artifactId>
        <groupId>com.jd.ads.union.cps</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
  • 目标
    消除重复和潜在的问题
  • 打包方式
    作为父模块的POM,打包类型也必须是pom。
  • 继承元素
    groupId
    version
    properties:自定义的maven属性
    dependencies:项目的依赖配置
    dependencyManagement:项目的依赖管理配置
    repositories:项目的仓库配置
    build:包括项目的源码目录配置、输出目录配置、插件配置、插件管理配置等。
  • dependencies和dependencyManagement
    继承父POM的dependencies后,可以移除子POM中的依赖配置,从而简化配置,但是无法确定将来添加的子模块是否一定需要父POM的所有配置。
    dependencyManagement元素既能让子模块继承到父模块的依赖配置,又能保证子模块依赖使用的灵活性。在dependencyManagement元素下的依赖声明不会引入实际的依赖,不过它能够约束dependencies下的依赖使用。
    import依赖范围,只在dependencyManagement元素下有效,使用该范围的依赖通常指向一个POM,作用是将目标POM中的dependencyManagement配置导入并合并到当前POM的dependencyManagement元素中。

    若每个子模块都都用的了spring,那么我们是不是每个子模块都需要单独配置spring依赖了?,这么做是可以的,但是我们有更优的做法,那就是继承,用parent来实现。

exclusion:将B从依赖树中删除。

聚合与继承的关系

聚合主要是为了方便快速构建项目,继承主要是为了消除重复配置。
对于聚合模块来说,它知道有哪些被聚合的模块,但那些被聚合的模块不知道这个聚合模块的存在。
对于继承关系的父POM来说,它不知道有哪些子模块继承于它,但那些子模块都必须知道自己的父POM是什么。

  2.具体实现

如上图中的三个属性为必要属性。

构建顺序

maven按序读取POM,如果该POM没有依赖模块,那么就构建该模块,否则就先构建其依赖模块,如果该依赖还依赖于其他模块,则进一步先构建依赖的依赖。

    a.配置父pom.xml

groupId artifactId version组成了该组件在maven仓库里的准确路径。假如仓库路径为D:apache-maven-3.5.0repository。则如上配置后,对应的文件位置应该在D:apache-maven-3.5.0repositoryorgapachecommonscommons-lang33.1文件夹下。

灵活性三大特性

      我就用聚合pom来做父pom,配置子模块的公共依赖。

 

属性

使用properties元素定义,使用${属性名称}的方式引用,可以消除重复。
内置属性:${basedir}表示项目跟目录,即包含pom.xml文件的目录;${version}表示项目的版本。
POM属性:可以引用POM文件对应的元素的值。${project.artifactId}
自定义属性:用户在properties元素自定义的属性。
Settings属性澳门新濠3559,:引用settings.xml文件中XML元素的值,${settings.localRepository}
Java系统属性:
环境变量属性:

      父(account-aggregator)pom.xml :

如果一个工程是parent或aggregation(即mutil-module的),则packaging必须设置为pom。

profile

根据环境不同进行不同的配置,例如数据库配置。
可以使用-P参数激活profile

    <profiles>
        <profile>
            <id>dev</id>
            <properties>
                <deploy.type>dev</deploy.type>
            </properties>
        </profile>      
        <profile>
            <id>prod</id>
            <properties>
                <deploy.type>prod</deploy.type>
            </properties>
        </profile>    
    </profiles>

澳门新濠3559 15澳门新濠3559 16

子工程从父工程继承的包括:dependencies,developers,contributors,plugin lists,reports lists,plugin execution with matching ids,plugin configuration

资源过滤

<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.youzhibing.account</groupId>
  <artifactId>account-aggregator</artifactId>
  <version>1.0.0-SNAPSHOT</version>
  <packaging>pom</packaging>

  <name>Account Aggrregator</name>
  <url>http://maven.apache.org</url>

  <modules>
      <!-- 模块都写在此处 -->
      <module>account-register</module>
      <module>account-persist</module>
  </modules>

  <dependencies> <!-- 配置共有依赖 -->
      <!-- spring 依赖 -->
      <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>4.0.2.RELEASE</version>
    </dependency>
      <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-beans</artifactId>
        <version>4.0.2.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>4.0.2.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context-support</artifactId>
        <version>4.0.2.RELEASE</version>
    </dependency>

      <!-- junit 依赖 -->
      <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.7</version>
      <scope>test</scope>
    </dependency>
  </dependencies>

</project>

 

推荐

官网:http://maven.apache.org/
<<maven权威指南>>
教程:http://www.yiibai.com/maven/

View Code

一个maven项目想要继承另一个maven项目,可以在pom.xml文件中做如下配置

    b.account-register的pom.xml :

<parent> 
    <groupId>org.codehaus.mojo</groupId> 
    <artifactId>my-parent</artifactId> 
    <version>2.0</version> 
    <relativePath>../my-parent</relativePath> 
</parent>

澳门新濠3559 17澳门新濠3559 18

其中relativePath属性是可选的,maven在搜索本地仓库之前会优先搜索这个地址。上面其余三个属性可以唯一确定一个父工程。

<?xml version="1.0"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>com.youzhibing.account</groupId>
    <artifactId>account-aggregator</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <relativePath>../pom.xml</relativePath> <!-- 与不配置一样,默认就是寻找上级目录下得pom.xml -->
  </parent>
  <artifactId>account-register</artifactId>
  <name>account-register</name>
  <url>http://maven.apache.org</url>
  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>
  <dependencies>    <!-- 配置自己独有依赖 -->
      <dependency>
          <groupId>javax.mail</groupId>
          <artifactId>mail</artifactId>
          <version>1.4.3</version>
      </dependency>
    <dependency>
      <groupId>com.icegreen</groupId>
      <artifactId>greenmail</artifactId>
      <version>1.4.1</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
</project>

 

View Code

dependencyManagement:用来帮助管理children的dependencies。

    c.account-persist的pom.xml :

<dependencyManagement>
    <dependencies>
    <dependency>
        <groupId>joda-time</groupId>
        <artifactId>joda-time</artifactId>
        <version>2.2</version>
        </dependency>
    </dependencies>
</dependencyManagement>

澳门新濠3559 19澳门新濠3559 20

如上图在父工程中定义后,子工程只能引用groupId和artifactId,version则由父工程控制。

<?xml version="1.0"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>com.youzhibing.account</groupId>
    <artifactId>account-aggregator</artifactId>
    <version>1.0.0-SNAPSHOT</version>
  </parent>
  <artifactId>account-persist</artifactId>
  <name>account-persist</name>
  <url>http://maven.apache.org</url>
  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>
  <dependencies>    <!-- 配置自己独有依赖 -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-jdbc</artifactId>
        <version>4.0.2.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid</artifactId>
        <version>1.0.16</version>
    </dependency>
  </dependencies>
</project>

这样做的优点是可以集中管理依赖的详情。

View Code

 

    d.依赖的jar包全部ok,需要做的则是在各个模块中进行代码开发了!

modules:父工程(或聚合工程)表现它有哪些子模块。顺序是不重要的,maven会根据依赖关系来拓扑排序

  3.依赖管理

<modules>
      <module>e3.manager-dao</module>
      <module>e3.manager-interface</module>
      <module>e3.manager-pojo</module>
      <module>e3.manager-service</module>
      <module>e3.manager-web</module>
</modules>

    继承可以消除重复,那是不是就没有问题了? 答案是存在问题,假设将来需要添加一个新的子模块account-util,该模块只是提供一些简单的帮助工具,不需要依赖spring、junit,那么继承后就依赖上了,有没有什么办法了? 有,maven已经替我们想到了,那就是dependencyManagement元素,既能让子模块继承到父模块的依赖配置,又能保证子模块依赖使用的灵活性。在dependencyManagement元素下得依赖声明不会引入实际的依赖,不过它能够约束dependencies下的依赖使用。

 

    在父pom.xml中配置dependencyManagement元素

properties:为pom定义一些常量,在pom的其他地方可以直接引用。

澳门新濠3559 21澳门新濠3559 22

<properties>
    <junit.version>4.12</junit.version>
</properties>
<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.youzhibing.account</groupId>
  <artifactId>account-aggregator</artifactId>
  <version>1.0.0-SNAPSHOT</version>
  <packaging>pom</packaging>

  <name>Account Aggrregator</name>
  <url>http://maven.apache.org</url>

  <modules>
      <!-- 模块都写在此处 -->
      <module>account-register</module>
      <module>account-persist</module>
  </modules>

  <dependencyManagement>
      <dependencies> <!-- 配置共有依赖 -->
      <!-- spring 依赖 -->
      <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>4.0.2.RELEASE</version>
    </dependency>
      <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-beans</artifactId>
        <version>4.0.2.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>4.0.2.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context-support</artifactId>
        <version>4.0.2.RELEASE</version>
    </dependency>

      <!-- junit 依赖 -->
      <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.7</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
  </dependencyManagement>
</project>

使用方式:${junit.version}

View Code

也可以获取pom里定义的其他属性,如${project.version} 获取项目版本。如${project.artifactId} 获取项目名。

    account-persist的pom.xml(account-register也一样) :

 

澳门新濠3559 23澳门新濠3559 24

build以下属性:

<?xml version="1.0"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>com.youzhibing.account</groupId>
    <artifactId>account-aggregator</artifactId>
    <version>1.0.0-SNAPSHOT</version>
  </parent>
  <artifactId>account-persist</artifactId>
  <name>account-persist</name>
  <url>http://maven.apache.org</url>
  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>
  <dependencies>
      <!-- spring 依赖 -->
      <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
    </dependency>
      <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-beans</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context-support</artifactId>
    </dependency>

      <!-- junit 依赖 -->
      <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-jdbc</artifactId>
        <version>4.0.2.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid</artifactId>
        <version>1.0.16</version>
    </dependency>
  </dependencies>
</project>

finalName:指定去掉后缀的工程名。${project.artifactId}

View Code

directory:指定build target目标的目录,默认为根目录下的target

     使用这种依赖管理机制似乎不能减少太多的POM配置,就少了version(junit还少了个scope),感觉没啥作用呀;其实作用还是挺大的,父POM使用dependencyManagement能够统一项目范围中依赖的版本,当依赖版本在父POM中声明后,子模块在使用依赖的时候就无须声明版本,也就不会发生多个子模块使用版本不一致的情况,帮助降低依赖冲突的几率。如果子模块不声明依赖的使用,即使该依赖在父POM中的dependencyManagement中声明了,也不会产生任何效果。

filters:定义指定filter属性的位置。

import

<filters> 
    <filter>src/main/filters/filter-${env}.properties</filter> 
</filters> 

  import只在dependencyManagement元素下才有效果,作用是将目标POM中的dependencyManagement配置导入并合并到当前POM的dependencyManagement元素中,如下就是讲account-aggregator中的dependencyManagement配置导入并合并到当前POM中。

resource:描述工程中资源的位置。

<dependencyManagement>
      <dependencies>
        <dependency>
            <groupId>com.youzhibing.account</groupId>
              <artifactId>account-aggregator</artifactId>
              <version>1.0.0-SNAPSHOT</version>
            <type>pom</type>
              <scope>import</scope>
        </dependency>
      </dependencies>
  </dependencyManagement>
<resource> 
    <targetPath>META-INF/plexus</targetPath> 
    <filtering>false</filtering> 
    <directory>${basedir}/src/main/plexus</directory> 
    <includes> 
        <include>configuration.xml</include> 
    </includes> 
    <excludes> 
        <exclude>**/*.properties</exclude> 
    </excludes> 
</resource>

properties(Maven属性)

其中:targetPath指定build资源到哪个目录。

  通过<properties>元素用户可以自定义一个或多个Maven属性,然后在POM的其他地方使用${属性名}的方式引用该属性,这种做法的最大意义在于消除重复和统一管理。

  filtering:指定filter文件值在这个resource中是否有效。例如这里指定的是在configuration.xml文件中无效。

  Maven总共有6类属性,内置属性、POM属性、自定义属性、Settings属性、java系统属性和环境变量属性;

  directory:指定属性文件的目录,build过程需要找到它,并将其放到targetPath目录下。默认的directory是src/main/resources

  1.内置属性

  includes:指定包含文件的patterns,符合样式,并且在directory目录下的文件,将会包含进project的资源文件。

    两个常用内置属性 ${basedir} 表示项目跟目录,即包含pom.xml文件的目录;${version} 表示项目版本

  excludes:指定不包含在内的patterns,如果与includes有冲突,以excludes为主。

  2.POM属性

testResources:包含测试资源元素,定义内容与resources类似,不同的是默认测试资源路径是src/test/resources,并且测试资源是不部署的。

    用户可以使用该类属性引用POM文件中对应元素的值。如${project.artifactId}就对应了<project> <artifactId>元素的值,常用的POM属性包括:

 

    ${project.build.sourceDirectory}:项目的主源码目录,默认为src/main/java/

plugins配置(plugins是在build标签内):

    ${project.build.testSourceDirectory}:项目的测试源码目录,默认为src/test/java/

<plugin> 
    <groupId>org.apache.maven.plugins</groupId> 
    <artifactId>maven-jar-plugin</artifactId> 
    <version>2.0</version> 
    <extensions>false</extensions> 
    <inherited>true</inherited> 
    <configuration> 
        <classifier>test</classifier> 
    </configuration> 
    <dependencies>...</dependencies> 
    <executions>...</executions> 
</plugin>

    ${project.build.directory} : 项目构建输出目录,默认为target/

extensions:决定是否load这个plugin的extensions,默认为true。

    ${project.outputDirectory} : 项目主代码编译输出目录,默认为target/classes/

inherited:是否让子工程集成,默认为true。

    ${project.testOutputDirectory}:项目测试主代码输出目录,默认为target/testclasses/

configuration:通常用于私有不开源的plugin,也可以指定字符集,类似<encoding>UTF-8</encoding>。

    ${project.groupId}:项目的groupId

pluginManagement:类似denpendencyManagement,只是后者用于管理项目jar包依赖,前者用于管理plugin。pluginManagement与plugin区别是前者列出来,让子工程决定是否引用。

    ${project.artifactId}:项目的artifactId

 

    ${project.version}:项目的version,与${version} 等价

    ${project.build.finalName}:项目打包输出文件的名称,默认为${project.artifactId}-${project.version}

  3.自定义属性

    如下account-aggregator的pom.xml,那么继承了此pom.xml的子模块也可以用此自定义属性

澳门新濠3559 25澳门新濠3559 26

<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.youzhibing.account</groupId>
  <artifactId>account-aggregator</artifactId>
  <version>1.0.0-SNAPSHOT</version>
  <packaging>pom</packaging>

  <name>Account Aggrregator</name>
  <url>http://maven.apache.org</url>

  <modules>
      <!-- 模块都写在此处 -->
      <module>account-register</module>
      <module>account-persist</module>
      <module>account-another</module>
  </modules>

  <properties>
      <!-- 定义 spring版本号 -->
    <spring.version>4.0.2.RELEASE</spring.version>
    <junit.version>4.7</junit.version>
  </properties>

  <dependencyManagement>
      <dependencies> <!-- 配置共有依赖 -->
      <!-- spring 依赖 -->
      <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>${spring.version}</version>
    </dependency>
      <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-beans</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context-support</artifactId>
        <version>${spring.version}</version>
    </dependency>

      <!-- junit 依赖 -->
      <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>${junit.version}</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
  </dependencyManagement>
</project>

View Code

  4.Settings属性

    与POM属性同理,用户使用以settings. 开头的属性引用settings.xml文件中的XML元素的值。

  5.Java系统属性

    所有java系统属性都可以用Maven属性引用,如${user.home}指向了用户目录。

  6.环境变量属性

    所有环境变量属性都可以使用以env. 开头的Maven属性引用,如${env.JAVA_HOME}指代了JAVA_HOME环境变量的的值。

聚合与继承的关系

  1.聚合主要是为了方便快速构建项目,继承主要是为了消除重复配置;

  2.对于聚合模块而言,它知道有哪些被聚合的模块,但那些被聚合的模块不知道这个聚合模块的存在;对于继承的父pom而言,它不知道有哪些子模块继承它,但那些子模块都必须知道自己的父POM是什么;

  3.聚合POM与继承中的父POM的packaging都必须是pom;同时,聚合模块与继承中的父模块除了POM外,都没有实际的内容

结束语

  maven越来越流行,这方面的资料也是越来越多,《Maven实战》给我的感觉就相当不错,本博客的内容大多取自其中;网上资料也越来越多,就博客园中就有不少;

  最后强调一点:看了是好,实践更好,写博客记录下来那是最好!

编辑:编程 本文来源:在通过maven引入jar包的时候,pom包括了所有的项目

关键词: 澳门新濠3559