maven多模块使用,父模块(modules使用,package替pom),子模块(parent使用)

maven多模块使用,父模块(modules使用,package为pom),子模块(parent使用)

转自:http://blog.csdn.net/eclipser1987/article/details/5739177

一个多模块项目通过一个父POM 引用一个或多个子模块来定义。父项目,通过以下配置,将子项目关联。

 

[xhtml] view plaincopy
 
  1. <packaging>pom</packaging>  
  2. <modules>  
  3.           <module>simple-weather</module>  
  4.           <module>simple-webapp</module>  
  5. </modules>  

     其中值得注意的是<packaging>pom</packaging>这个父项目不像之前的项目那样创建一个JAR 或者一个WAR,它仅仅是一个引用其它Maven 项目的POM。pom.xml 中下一部分列出了项目的子模块。这些模块在modules元素中定义,每个modules 元素对应了一个simple-parent/目录下的子目录。Maven知道去这些子目录寻找pom.xml 文件,并且,在构建的simp-parent 的时候,它会将这些子模块包含到要构建的项目中。

     当然,仅仅在父项目,配置子项目是不能够真正实现关联的,因为,这毕竟需要子项目的同意,故!子项目中需要配置:

 

[xhtml] view plaincopy
 
  1. <parent>  
  2.         <groupId>org.sonatype.mavenbook.ch06</groupId>  
  3.         <artifactId>simple-parent</artifactId>  
  4.         <version>1.0</version>  
  5. </parent>  

     现在,通过父pom.xml将2个子项目进行了关联,那么我们需要从simple-parent 项目运行mvn clean install 命令,将2个子项目打包,编译为一个项目!

     当Maven 执行一个带有子模块的项目的时候,Maven 首先载入父POM,然后定位所有的子模块POM。Maven 然后将所有这些项目的POM 放入到一个称为Maven 反应堆(Reactor)的东西中,由它负责分析模块之间的依赖关系。这个反应堆处理组件的排序,以确保相互独立的模块能以适当的顺序被编译和安装。

     当,通过父pom.xml进行完成多个子项目的关联后,我们可以像前几章一样,分别进入某个单独的模块,进行运行,以移动程序!

 

 注意:子项目的文件,位于父项目pom.xml同级,也就是,子项目的pom.xml位于父pom.xml的下一级文件中!




  对于一个pom.xml来说有几个元素是必须定义的,一个是project根元素,然后就是它里面的modelVersion、groupId、artifactId和version。由上面的超级pom.xml的内容我们可以看到pom.xml中没有groupId、artifactId和version的定义,所以我们在建立自己的pom.xml的时候就需要定义这三个元素。和java里面的继承类似,子pom.xml会完全继承父pom.xml中所有的元素,而且对于相同的元素,一般子pom.xml中的会覆盖父pom.xml中的元素,但是有几个特殊的元素它们会进行合并而不是覆盖。这些特殊的元素是:

Ø  dependencies

Ø  developers

Ø  contributors

Ø  plugin列表,包括plugin下面的reports

Ø  resources

6.2.1继承

6.2.1.1被继承项目与继承项目是父子目录关系

       现在假设我们有一个项目projectA,它的pom.xml定义如下:

Xml代码   收藏代码
  1. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  2.   xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">  
  3.   <modelVersion>4.0.0</modelVersion>  
  4.   <groupId>com.tiantian.mavenTest</groupId>  
  5.   <artifactId>projectA</artifactId>  
  6.   <packaging>jar</packaging>  
  7.   <version>1.0-SNAPSHOT</version>  
  8. </project>  

       然后我们有另一个项目projectB,而且projectB是跟projectA的pom.xml文件处于同一个目录下,这时候如果projectB需要继承自projectA的话我们可以这样定义projectB的pom.xml文件。

Xml代码   收藏代码
  1. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  2.   xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">  
  3.   <parent>  
  4.     <groupId>com.tiantian.mavenTest</groupId>  
  5.     <artifactId>projectA</artifactId>  
  6.     <version>1.0-SNAPSHOT</version>  
  7.   </parent>  
  8.   <modelVersion>4.0.0</modelVersion>  
  9.   <groupId>com.tiantian.mavenTest</groupId>  
  10.   <artifactId>projectB</artifactId>  
  11.   <packaging>jar</packaging>  
  12.   <version>1.0-SNAPSHOT</version>  
  13. </project>  

       由projectB的pom.xml文件的定义我们可以知道,当需要继承指定的一个Maven项目时,我们需要在自己的pom.xml中定义一个parent元素,在这个元素中指明需要继承项目的groupId、artifactId和version。

6.2.1.2被继承项目与继承项目的目录结构不是父子关系

       当被继承项目与继承项目的目录结构不是父子关系的时候,我们再利用上面的配置是不能实现Maven项目的继承关系的,这个时候我们就需要在子项目的pom.xml文件定义中的parent元素下再加上一个relativePath元素的定义,用以描述父项目的pom.xml文件相对于子项目的pom.xml文件的位置。

       假设我们现在还是有上面两个项目,projectA和projectB,projectB还是继承自projectA,但是现在projectB不在projectA的子目录中,而是与projectA处于同一目录中。这个时候projectA和projectB的目录结构如下:

       ------projectA

              ------pom.xml

       ------projectB

              ------pom.xml

       这个时候我们可以看出projectA的pom.xml相对于projectB的pom.xml的位置是“../projectA/pom.xml”,所以这个时候projectB的pom.xml的定义应该如下所示:

Xml代码   收藏代码
  1. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  2.   xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">  
  3.   <parent>  
  4.     <groupId>com.tiantian.mavenTest</groupId>  
  5.     <artifactId>projectA</artifactId>  
  6.     <version>1.0-SNAPSHOT</version>  
  7.        <relativePath>../projectA/pom.xml</relativePath>  
  8.   </parent>  
  9.   <modelVersion>4.0.0</modelVersion>  
  10.   <groupId>com.tiantian.mavenTest</groupId>  
  11.   <artifactId>projectB</artifactId>  
  12.   <packaging>jar</packaging>  
  13.   <version>1.0-SNAPSHOT</version>  
  14. </project>  

6.2.2聚合

       对于聚合这个概念搞java的人应该都不会陌生。先来说说我对聚合和被聚合的理解,比如说如果projectA聚合到projectB,那么我们就可以说projectA是projectB的子模块, projectB是被聚合项目,也可以类似于继承那样称为父项目。对于聚合而言,这个主体应该是被聚合的项目。所以,我们需要在被聚合的项目中定义它的子模块,而不是像继承那样在子项目中定义父项目。具体做法是:

Ø  修改被聚合项目的pom.xml中的packaging元素的值为pom

Ø  在被聚合项目的pom.xml中的modules元素下指定它的子模块项目

对于聚合而言,当我们在被聚合的项目上使用Maven命令时,实际上这些命令都会在它的子模块项目上使用。这就是Maven中聚合的一个非常重要的作用。假设这样一种情况,你同时需要打包或者编译projectA、projectB、projectC和projectD,按照正常的逻辑我们一个一个项目去使用mvn compile或mvn package进行编译和打包,对于使用Maven而言,你还是这样使用的话是非常麻烦的。因为Maven给我们提供了聚合的功能。我们只需要再定义一个超级项目,然后在超级项目的pom.xml中定义这个几个项目都是聚合到这个超级项目的。之后我们只需要对这个超级项目进行mvn compile,它就会把那些子模块项目都进行编译。

6.2.2.1被聚合项目和子模块项目在目录结构上是父子关系

还拿上面定义的projectA和projectB来举例子,现在假设我们需要把projectB聚合到projectA中。projectA和projectB的目录结构如下所示:

------projectA

       ------projectB

              -----pom.xml

       ------pom.xml

这个时候projectA的pom.xml应该这样定义:

Xml代码   收藏代码
  1. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  2.   xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">  
  3.   <modelVersion>4.0.0</modelVersion>  
  4.   <groupId>com.tiantian.mavenTest</groupId>  
  5.   <artifactId>projectA</artifactId>  
  6.   <version>1.0-SNAPSHOT</version>  
  7.   <packaging>pom</packaging>  
  8.   <modules>  
  9.        <module>projectB</module>  
  10.   </modules>  
  11. </project>  
 

由上面的定义我们可以看到被聚合的项目的packaging类型应该为pom,而且一个项目可以有多个子模块项目。对于聚合这种情况,我们使用子模块项目的artifactId来作为module的值,表示子模块项目相对于被聚合项目的地址,在上面的示例中就表示子模块projectB是处在被聚合项目的子目录下,即与被聚合项目的pom.xml处于同一目录。这里使用的module值是子模块projectB对应的目录名projectB,而不是子模块对应的artifactId。这个时候当我们对projectA进行mvn package命令时,实际上Maven也会对projectB进行打包。

6.2.2.2被聚合项目与子模块项目在目录结构上不是父子关系

那么当被聚合项目与子模块项目在目录结构上不是父子关系的时候,我们应该怎么来进行聚合呢?还是像继承那样使用relativePath元素吗?答案是非也,具体做法是在module元素中指定以相对路径的方式指定子模块。我们来看下面一个例子。

继续使用上面的projectA和projectB,还是需要把projectB聚合到projectA,但是projectA和projectB的目录结构不再是父子关系,而是如下所示的这种关系:

------projectA

       ------pom.xml

------projectB

       ------pom.xml

这个时候projectA的pom.xml文件就应该这样定义:

Xml代码   收藏代码
  1. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  2.   xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">  
  3.   <modelVersion>4.0.0</modelVersion>  
  4.    
  5.   <groupId>com.tiantian.mavenTest</groupId>  
  6.   <artifactId>projectA</artifactId>  
  7.   <version>1.0-SNAPSHOT</version>  
  8.   <packaging>pom</packaging>  
  9.   <modules>  
  10.        <module>../projectB</module>  
  11.   </modules>  
  12. </project>  
 

注意看module的值是“../projectB”,我们知道“..”是代表当前目录的上层目录,所以它表示子模块projectB是被聚合项目projectA的pom.xml文件所在目录(即projectA)的上层目录下面的子目录,即与projectA处于同一目录层次。注意,这里的projectB对应的是projectB这个项目的目录名称,而不是它的artifactId

6.2.2.3聚合与继承同时进行

       假设有这样一种情况,有两个项目,projectA和projectB,现在我们需要projectB继承projectA,同时需要把projectB聚合到projectA。然后projectA和projectB的目录结构如下:

       ------projectA

              ------pom.xml

       ------projectB

              ------pom.xml

       那么这个时候按照上面说的那样,projectA的pom.xml中需要定义它的packaging为pom,需要定义它的modules,所以projectA的pom.xml应该这样定义:

Xml代码   收藏代码
  1. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  2.   xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">  
  3.   <modelVersion>4.0.0</modelVersion>  
  4.   <groupId>com.tiantian.mavenTest</groupId>  
  5.   <artifactId>projectA</artifactId>  
  6.   <version>1.0-SNAPSHOT</version>  
  7.   <packaging>pom</packaging>  
  8.   <modules>  
  9.        <module>../projectB</module>  
  10.   </modules>  
  11. </project>  

       而projectB是继承自projectA的,所以我们需要在projectB的pom.xml文件中新增一个parent元素,用以定义它继承的项目信息。所以projectB的pom.xml文件的内容应该这样定义:

Xml代码   收藏代码
  1. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  2.   xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">  
  3.   <modelVersion>4.0.0</modelVersion>  
  4.   <parent>  
  5.        <groupId>com.tiantian.mavenTest</groupId>  
  6.        <artifactId>projectA</artifactId>  
  7.        <version>1.0-SNAPSHOT</version>  
  8.        <relativePath>../projectA/pom.xml</relativePath>  
  9.   </parent>  
  10.   <groupId>com.tiantian.mavenTest</groupId>  
  11.   <artifactId>projectB</artifactId>  
  12.   <version>1.0-SNAPSHOT</version>  
  13.   <packaging>jar</packaging>  
  14. </project>  

6.2.3依赖Dependency

       项目之间的依赖是通过pom.xml文件里面的dependencies元素下面的dependency元素进行的。一个dependency元素定义一个依赖关系。在dependency元素中我们主要通过依赖项目的groupId、artifactId和version来定义所依赖的项目。

       先来看一个简单的项目依赖的示例吧,假设我现在有一个项目projectA,然后它里面有对junit的依赖,那么它的pom.xml就类似以下这个样子:

Xml代码   收藏代码
  1. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  2.   xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">  
  3.   <modelVersion>4.0.0</modelVersion>  
  4.   <groupId>com.tiantian.mavenTest</groupId>  
  5.   <artifactId>projectB</artifactId>  
  6.   <version>1.0-SNAPSHOT</version>  
  7.   <packaging>jar</packaging>  
  8.    
  9.   <dependencies>  
  10.     <dependency>  
  11.       <groupId>junit</groupId>  
  12.       <artifactId>junit</artifactId>  
  13.       <version>3.8.1</version>  
  14.       <scope>test</scope>  
  15.               <optional>true</optional>  
  16.     </dependency>  
  17.   </dependencies>  
  18. </project>  

       在dependency元素中除了可以指定依赖项目的groupId、artifactId和version之外,还可以指定以下元素:

Ø  type:对应于依赖项目的packaging类型,默认是jar

Ø  scope:表示依赖项目的一个作用范围。scope的主要取值范围如下(还有一个是在Maven2.0.9以后版本才支持的import,关于import作用域将在后文《Dependency介绍》中做介绍):

n  compile:这是它的默认值,这种类型很容易让人产生误解,以为只有在编译的时候才是需要的,其实这种类型表示所有的情况都是有用的,包括编译和运行时。而且这种类型的依赖性是可以传递的。

n  provided:这个跟compile很类似,但是它表示你期望这个依赖项目在运行时由JDK或者容器来提供。这种类型表示该依赖只有在测试和编译的情况下才有效,在运行时将由JDK或者容器提供。这种类型的依赖性是不可传递的。

n  runtime:这种类型表示该依赖在编译的时候不是必须的,只有在运行的时候才是必须的。

n  test:这表示这种依赖只有测试的时候才需要,正常情况下是不需要的。

n  system:这种类型跟provided类似,唯一不同的就是这种类型的依赖我们要自己提供jar包,这需要与另一个元素systemPath来结合使用。systemPath将指向我们系统上的jar包的路径,而且必须是给定的绝对路径。

Ø  systemPath:上面已经说过了这个元素是在scope的值为system的时候用于指定依赖的jar包在系统上的位置的,而且是绝对路径。该元素必须在依赖的 jar包的scope为system时才能使用,否则Maven将报错。

Ø  optional:当该项目本身作为其他项目的一个依赖时标记该依赖为可选项。假设现在projectA有一个依赖性projectB,我们把projectB这个依赖项设为optional,这表示projectB在projectA的运行时不一定会用到。这个时候如果我们有另一个项目projectC,它依赖于projectA,那么这个时候因为projectB对于projectA是可选的,所以Maven在建立projectC的时候就不会安装projectB,这个时候如果projectC确实需要使用到projectB,那么它就可以定义自己对projectB的依赖。当一个依赖是可选的时候,我们把optional元素的值设为true,否则就不设置optional元素。

Ø  exclusions:考虑这样一种情况,我们的projectA依赖于projectB,然后projectB又依赖于projectC,但是在projectA里面我们不需要projectB依赖的projectC,那么这个时候我们就可以在依赖projectB的时候使用exclusions元素下面的exclusion排除projectC。这个时候我们可以这样定义projectA对projectB的依赖:

Xml代码   收藏代码
  1. <dependencies>  
  2.      <dependency>  
  3.             <groupId>com.tiantian.mavenTest</groupId>  
  4.             <artifactId>projectB</artifactId>  
  5.             <version>1.0-SNAPSHOT</version>  
  6.             <exclusions>  
  7.                    <exclusion>  
  8.                           <groupId>com.tiantian.mavenTest</groupId>  
  9.                           <artifactId>projectC</artifactId>  
  10.                    </exclusion>  
  11.             </exclusions>  
  12.      </dependency>  
  13. </dependencies>  

6.3     属性

在pom.xml文件中我们可以使用${propertyName}的形式引用属性。这个propertyName有以下几种形式:

Ø  env.propertyName:这种形式表示引用的是环境变量,比如我们需要引用当前系统的环境变量PATH的时候,就可以使用${env.PATH}。

Ø  project.propertyName:这种形式表示引用的是当前这个pom.xml中project根元素下面的子元素的值。比如我们需要引用当前project下面的version的时候,就可以使用${project.version}。

Ø  settings.propertyName:这种形式引用的是Maven本地配置文件settings.xml或本地Maven安装目录下的settings.xml文件根元素settings下的元素。比如我们需要引用settings下的本地仓库localRepository元素的值时,我们可以用${settings.localRepository}

Ø  java的系统属性,所有在java中使用java.lang.System.getProperties()能够获取到的属性都可以在pom.xml中引用,比如${java.home}。

Ø  pom.xml中properties元素下面的子元素作为属性。假如在pom.xml中有如下一段代码<properties><hello.world>helloWorld</hello.world></properties>,那么我们就可以使用${hello.world}引用到对应的helloWorld。

发布了9 篇原创文章 · 获赞 20 · 访问量 7万+

猜你喜欢

转载自blog.csdn.net/Aaron_Zhang939/article/details/78663538
今日推荐