多模块工程

在实际项目开发中,多模块工程更有利于划分清楚项目结构。

因此本节将介绍 Leap 推荐的多模块工程结构,指引读者创建一个 maven 多模块工程。

1. 结构

与之前工程结构一节介绍的工程结构不同,多模块工程在这些工程结构之上加多了一层结构,如下图所示:

myproject
|----api
|    |----src
|    |----pom.xml
|----core
|    |----src
|    |----pom.xml
|----deploy
|    |----src
|    |----pom.xml
|----pom.xml

以上结构中:

  • myproject 是我们多模块工程的父模块目录,该目录下除了子模块之外只有一个属于它的 pom.xml 文件;
  • api 是子模块之一,我们将用它来存放 API 开发相关代码和配置;
  • core 是子模块之一,我们将用它来存放项目所有核心代码和配置;
  • deploy 是子模块之一,是一个 web 模块,本身不存放代码,可存放部署相关的配置。主要用于引入其他模块一起打包部署;
  • 以上各个模块都各自有自己的 pom.xml文件。

各个子模块内部的结构与工程结构一节介绍的工程结构基本一致,不一致的地方在于:多模块工程中,只需要 deploy 子模块需要配置 web.xml 。

在实际开发中根据项目需要可能添加其他子模块,也是按照以上子模块的格式建立目录结构。

2. 配置 pom.xml

父模块的 pom.xml 示例如下:

<?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>com.demo.myproject</groupId>
    <artifactId>myproject</artifactId>
    <packaging>pom</packaging>
    <version>1.0-SNAPSHOT</version>
    <modules>
        <module>core</module>
        <module>api</module>
        <module>deploy</module>
    </modules>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <leap.version>0.6.4b</leap.version>
        <slf4j.version>1.7.10</slf4j.version>
        <logback.version>1.0.13</logback.version>
    </properties>

    <dependencies>
        <!-- leap -->
        <dependency>
            <groupId>org.leapframework</groupId>
            <artifactId>leap</artifactId>
            <version>${leap.version}</version>
            <type>pom</type>
        </dependency>
    </dependencies>
</project>
  • 在父模块 pom.xml 文件中我们需要使用 modules 元素列出所有子模块。

  • 我们可以在父模块中定义一些 properties 变量,这些变量在子模块中可直接使用。

  • 我们还可以在父模块中定义全局的依赖,所有子模块也会自动拥有这些依赖。在这里我们引入了 Leap 的依赖,因为几乎全部子模块都可能用到 Leap ,为了方便,我们直接在父模块引入。


api 子模块 pom.xml 文件示例如下:

<?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">
    <parent>
        <groupId>com.demo.myproject</groupId>
        <artifactId>myproject</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>api</artifactId>

    <dependencies>
        <dependency>
            <groupId>com.demo.myproject</groupId>
            <artifactId>core</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
    </dependencies>

</project>
  • 在子模块 pom.xml 中我们使用 parent 元素指定了父模块的 maven 坐标。

  • 由于 api 模块一般我们会用来放置 API controller 以及其它 api 相关的类,因此将可能需要调用 service 类完成操作,这些类一般会写在 core 子模块中,因此我们这里引用了 core 模块。

  • 实际项目中根据项目需要引用其它子模块依赖,需要注意要避免循环引用。


core 子模块 pom.xml 文件示例如下:

<?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">
    <parent>
        <groupId>com.demo.myproject</groupId>
        <artifactId>myproject</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>core</artifactId>

    <dependencies>

        <!-- db -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.26</version>
        </dependency>

        <!-- test -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.11</version>
            <scope>test</scope>
        </dependency>

        <!-- log -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>${slf4j.version}</version>
            <type>jar</type>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>jcl-over-slf4j</artifactId>
            <version>${slf4j.version}</version>
            <type>jar</type>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>${logback.version}</version>
            <type>jar</type>
            <scope>runtime</scope>
        </dependency>
    </dependencies>
</project>
  • core 子模块由于是核心模块,一般不会再引用其它子模块,因此这里的示例只是引入了一些项目常用外部依赖如单元测试、日志、数据库连接等依赖。

deploy 子模块的 pom.xml 示例文件如下:

<?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">
    <parent>
        <groupId>com.demo.myproject</groupId>
        <artifactId>myproject</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <packaging>war</packaging>

    <artifactId>deploy</artifactId>

    <dependencies>
        <dependency>
            <groupId>com.demo.myproject</groupId>
            <artifactId>core</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>

        <dependency>
            <groupId>com.demo.myproject</groupId>
            <artifactId>api</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.eclipse.jetty</groupId>
                <artifactId>jetty-maven-plugin</artifactId>
                <version>9.4.5.v20170502</version>
            </plugin>
        </plugins>
    </build>
</project>
  • 这里 deploy 子模块的打包格式必须为 war。

  • 依赖引用包含了 core 和 api 子模块,其实这里 core 可以不引用,因为根据 maven 的引用传递规则, api 引用了 core,那这里 deploy 也就间接地引用了 core。但是为了明确引用,我们还是写上来。

  • 这里可选配置一个 jetty 插件,方便在 IDEA 中调试运行。

3. 其他配置

由于剩下的配置其实与单模块工程差别不大,只是不同的配置需要配置到不同子模块中,因此这里只是做简单介绍:

  • deploy 子模块需要配置 web.xml 文件。

  • core 子模块需要配置 Leap 以及数据源。

  • api 子模块需要配置 API 相关配置。

需要注意的是,api 子模块的配置,除了按照之前这样配置:

<?xml version="1.0" encoding="UTF-8"?>
<apis xmlns="http://www.leapframework.org/schema/webapi">
    <api name="api" base-path="/">
    </api>
</apis>

还有另外一种配置方式,就是可以通过 base-package 属性指定一个包名,这个包名与 config.xml 文件中 base-package 指定的包名必须不同,且不能为包含关系

这样指定之后,这里的 base-path 就不需要固定为根目录,可以根据需求更改。示例如下:


<?xml version="1.0" encoding="UTF-8"?>
<apis xmlns="http://www.leapframework.org/schema/webapi">
    <api name="api" base-path="/myapi" base-package="myapi">
    </api>
</apis>

通过以上配置,我们在写代码的时候就需要注意将该模块相关的 Controller 类放到相关的 base-package 包下。

上一篇:使用 profile 切换配置 下一篇:依赖注入

results matching ""

    No results matching ""