maven多模块web项目完整实例详解(附项目源码)

版权声明:欢迎转载,但是请附上原文链接! https://blog.csdn.net/zixiao217/article/details/53270692

使用maven构建多模块项目。在一个项目中使用多个模块的一个方法是将模块添加为依赖项,正常情况下,我们会添加一个外部模块作为依赖。但是,当模块是一个项目的一部分,并密切相关的时候,该项目应被构造为一个多模块项目。在一个多模块项目中,Maven可以确保所有子模块在主模块之前被构建。

maven构建多模块项目实例

我们的实例简单易懂:将一个获取指定格式的当前时间的方法拆分成两个子模块:app和util。util提供一个使用apache commons lang库格式化日期的静态方法,app模块依赖util模块打印格式化的日期。

(本文章分享在CSDN平台,更多精彩请阅读 东陆之滇的csdn博客:http://blog.csdn.net/zixiao217 ,如在其他平台看到此文可能会出现内容不完整的现象,请移至东陆之滇http://blog.csdn.NET/zixiao217查看原文)

首先,使用如下命令创建工程和模块目录:

-- create directory for top level project

$ mkdir multi-app

-- create directories for modules

$ cd multi-app
$ mkdir app
$ mkdir util

-- create source and test dir for util module

$ mkdir -p util/src/main/java/com/xyz/util
$ mkdir -p util/src/test/java/com/xyz/util

-- create source dir for app module

$ mkdir -p app/src/main/java/com/xyz

这里写图片描述

multi-app目录作为多模块项目的顶层目录,它包含两个子模块:apputil

顶层pom.xml

多模块项目的顶层目录中需要包含一个pom.xml,multi-app/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/maven-v4_0_0.xsd">

        <modelVersion>4.0.0</modelVersion>

        <!-- project coordinates项目坐标 -->
        <groupId>com.xyz</groupId>
        <artifactId>multi-app</artifactId>
        <version>1.0</version>
        <!--多模块项目的顶层目录的pom.xml打包类型必须为pom-->
        <packaging>pom</packaging>

        <!--包含两个子模块-->
        <modules>
                <module>app</module>
                <module>util</module>
        </modules>

</project>

在顶层POM中,我们定义了多模块项目的坐标和它的模块。顶层项目目录中仅仅包含一个pom.xml,并且打包类型为pom。modules/module元素中,给多模块项目添加了两个子模块。顶层项目是父项目,它的坐标被正如我们接下来看到的,将会在子模块中引用。

Maven Reactor

你可能已经注意到了,在上面的模块定义中,我们将util放在app模块之后,但实际上util模块必须在app模块之前构建,因为app依赖于它。而在父模块(顶层模块)的pom.xml定义中使我们感到困惑的子模块构建顺序实际上会被mavan的一个反应堆(reactor)组件根据子模块的依赖合理安排它们的构建顺序。当我们构建multi-app时,reactor会先构建util再构建app。

util模块

util模块只有一个简单个DateUtil 类提供了一个静态发方法getToday()用来返回一个格式化的日期,也包含了一个测试方法。
multi-app/util/src/main/java/com/xyz/util/DateUtil.java:

package com.xyz.util;

import java.util.Date;
import org.apache.commons.lang.time.DateFormatUtils;

public class DateUtil {

        public static String getToday() {
                String today = DateFormatUtils.format(new Date(), "dd-MMM-yyyy");
                return today;
        }
}

multi-app/util/src/test/java/com/xyz/util/DateUtilTest.java:

package com.xyz.util;

import static org.junit.Assert.assertEquals;

import java.text.SimpleDateFormat;
import java.util.Date;

import org.junit.Test;

public class DateUtilTest {

        @Test
        public void testGetToday() {
                String actual = DateUtil.getToday();
                String expected = new SimpleDateFormat("dd-MMM-yyyy")
                                .format(new Date());
                assertEquals(expected, actual);
        }
}

util模块的pom.xml定义了该模块的坐标和依赖,另外还使用了parent元素包含了multi-app的坐标。
multi-app/util/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/maven-v4_0_0.xsd">

        <modelVersion>4.0.0</modelVersion>

        <!-- parent coordinates父模块坐标 -->
        <parent>
                <groupId>com.xyz</groupId>
                <artifactId>multi-app</artifactId>
                <version>1.0</version>
        </parent>

        <!-- project coordinates -->
        <groupId>com.xyz</groupId>
        <artifactId>util</artifactId>
        <version>1.0</version>

        <!-- project dependencies -->
        <dependencies>
                <dependency>
                        <groupId>junit</groupId>
                        <artifactId>junit</artifactId>
                        <version>4.12</version>
                        <scope>test</scope>
                </dependency>
                <dependency>
                        <groupId>commons-lang</groupId>
                        <artifactId>commons-lang</artifactId>
                        <version>2.4</version>
                </dependency>
        </dependencies>
</project>

app模块

app模块仅仅包含一个App.java类依赖util模块输出格式化的日期。

multi-app/app/src/main/java/com/xyz/App.java:

package com.xyz;

import com.xyz.util.*;

public class App {

        public static void main(String[] args) {
                System.out.println("Hello World! Today is " + DateUtil.getToday());
        }

}

app模块的pom.xml定义了该模块的坐标,并且依赖了util模块,同样的将multi-app模块作为父模块。
multi-app/app/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/maven-v4_0_0.xsd">

        <modelVersion>4.0.0</modelVersion>

        <!-- parent coordinates -->
        <parent>
                <groupId>com.xyz</groupId>
                <artifactId>multi-app</artifactId>
                <version>1.0</version>
        </parent>

        <!-- project coordinates -->
        <groupId>com.xyz</groupId>
        <artifactId>app</artifactId>
        <version>1.0</version>

        <!-- project dependencies -->
        <dependencies>
                <dependency>
                        <groupId>com.xyz</groupId>
                        <artifactId>util</artifactId>
                        <version>1.0</version>
                </dependency>
        </dependencies>
</project>

至此整个项目结构如下所示:
这里写图片描述

构建maven多模块项目

构建maven多模块项目,我们需要在顶层目录中运行build命令。可以这样构建 multi-app:

$ cd multi-app
$ mvn test

maven处理顶层POM文件multi-app/pom.xml,它知道如何处理子模块 的POM文件app/pom.xmlutil/pom.xml。一旦POM被处理,根据使用的模块反应堆构reactor建建立顺序依赖性并构建各模块。上述命令,maven首先执行multi-app的测试阶段(但是发现顶层项目并没有任何源码,不做任何事情)然后编译和测试util模块,最后编译和测试app模块。

对于mvn clean命令,会按multi-app、util和app模块的顺序clean。
mvn install命令编译、测试、打包、安装( compiles, tests, packages and installs)顺序是:multi-app、util 和app。

Assembly装配

Assembly插件目的是提供一个把工程依赖元素、模块、网站文档等其他文件存放到单个归档文件里。
使用任何一个预定义的描述符你可以轻松的构建一个发布包。
而Maven多模块项目构建命令被执行,通常情况下,从项目的顶层目录开始,但是assembly 命令稍有不同。

在项目的顶层目录运行命令 assembly:assembly:

$ mvn assembly:assembly -DdescriptorId=project

为预先定义的描述符的src和bin,运行组件:组件的子模块的目录:

$ cd app
$ mvn assembly:assembly -DdescriptorId=src
$ cd ../util
$ mvn assembly:assembly -DdescriptorId=src

对于预定义描述符jar-with-dependencies,同样在app目录下执行assembly:assembly命令:

$ cd app
$ mvn assembly:assembly -DdescriptorId=jar-with-dependencies

Plugin Management插件管理

POM中的pluginManagement元素允许在父POM中进行配置,所有子模块均可以继承这些配置。

假设multi-app的所有子模块均使用jdk1.8,一种方式是在app、util模块中的POM均配置编译插件。但是更好的方式是在顶层父模块中使用pluginManagement元素,从而所有子模块均可继承插件配置。

multi-app/pom.xml:

...
  <build>
    <pluginManagement>
       <plugins>
         <plugin>    
           <artifactId>maven-compiler-plugin</artifactId>
           <configuration>
             <source>1.8</source>
             <target>1.8</target>
           </configuration>
         </plugin>
      </plugins>
    </pluginManagement>
  </build>
  ...

plugins/plugin元素直接在buile元素中使用的时候,插件定义会在当前POM生效。但是如果plugins/plugin元素是在pluginManagement元素中时,当前使用这种定义的POM位置并不会使用它,但是可以被子模块来继承配置生效。因此,multi-app的POM并不会使用maven-compiler-plugin插件指定的配置,而是会被app、util两个子模块继承使用。

maven构建多模块项目实例源码

戳这里下载项目源码: http://download.csdn.net/detail/zixiao217/9689359

展开阅读全文

没有更多推荐了,返回首页