Как управлять мультимодулями Maven в Java-проектах Dachang

maven

Что такое многомодульное управление

Простое понимание многомодульного управления состоит в том, что в проекте Java есть более одного файла pom.xml, и таких файлов будет несколько в разных каталогах, тем самым реализуя многомодульное управление Maven.

Зачем использовать многомодульное управление

По мере роста бизнеса код будет иметь следующие проблемы:

  • Коды между различными службами связаны друг с другом, что затрудняет различение и быстрое обнаружение проблем.
  • Увеличить стоимость разработки и увеличить сложность запуска
  • Границы развития размыты, и трудно определить конкретного ответственного лица
  • Модули с особыми потребностями нельзя дизассемблировать, например: для загрузки репозитория maven требуется только часть кода, но поскольку модуль всего один, приходится загружать их все

Поэтому после разделения модулей вышеперечисленных проблем можно избежать

Схема разделения модуля

Обычно есть 2 варианта разделения

Разделить по структуре

- project
  - project-service
  - project-controller
  - project-dao

Разделить по бизнесу

- project
  - project-order
  - project-account
  - project-pay

фактическая структура проекта

Возьмите обычный проект Spring Boot в качестве примера, сначала поместите картинку, чтобы увидеть структуру общего проекта после завершения

где структура каталогов

- detail-page
  - detail-client
  - detail-service
  - detail-start
  • детальный клиент используется для размещения кода, который необходимо упаковать и передать в библиотеку maven.
  • деталь-сервис используется для размещения основного кода бизнес-логики
  • detail-start используется для ввода кода запуска

Среди них необходимо обратить внимание на конфигурацию файла pom.xml, который определяет взаимосвязь между родительским и дочерним модулями.

1. 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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.6.RELEASE</version>
    </parent>

    <modelVersion>4.0.0</modelVersion>
    <groupId>com.drawcode</groupId>
    <artifactId>detail-page</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>pom</packaging>  <!-- 此处必须为pom -->
    <name>detail-page</name>

    <properties>
        <java.version>1.8</java.version>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>

    <!-- modules即为父子关系 -->
    <modules>
        <module>detail-client</module>
        <module>detail-service</module>
        <module>detail-start</module>
    </modules>

    <!-- dependencyManagement非常重要,决定了子pom.xml是否可以直接引用父pom.xml的包 -->
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter</artifactId>
                <version>2.2.6.RELEASE</version>
            </dependency>

            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
                <version>2.2.6.RELEASE</version>
            </dependency>

            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
                <exclusions>
                    <exclusion>
                        <groupId>org.junit.vintage</groupId>
                        <artifactId>junit-vintage-engine</artifactId>
                    </exclusion>
                </exclusions>
            </dependency>

            <!--注意这个包就是项目本身的模块-->
            <dependency>
                <groupId>com.drawcode</groupId>
                <artifactId>detail-service</artifactId>
                <version>${project.version}</version>
                <!-- 这个版本就表示0.0.1-SNAPSHOT -->
            </dependency>

            <!--注意这个包就是项目本身的模块-->
            <dependency>
                <groupId>com.drawcode</groupId>
                <artifactId>detail-client</artifactId>
                <version>${project.version}</version>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <!-- 注意此处为空 -->
        </plugins>
    </build>

</project>

2. 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 https://maven.apache.org/xsd/maven-4.0.0.xsd">

    <!--parent使用的即为父pom.xml的信息-->
    <parent>
        <groupId>com.drawcode</groupId>
        <artifactId>detail-page</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <relativePath>../pom.xml</relativePath>
    </parent>

    <modelVersion>4.0.0</modelVersion>
    <artifactId>detail-start</artifactId>
    <packaging>jar</packaging> <!-- 注意此处要配置为jar -->
    <name>detail-start</name>

    <!--子pom.xml不必添加dependencyManagement-->
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <!--这里可以看到因为父pom.xml已经引用了自身项目的包模块,所以这里可以不加version直接使用-->
        <dependency>
            <groupId>com.drawcode</groupId>
            <artifactId>detail-service</artifactId>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <!--因为启动类在detail-start中,所以此处必须添加该plugin-->
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

3. 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 https://maven.apache.org/xsd/maven-4.0.0.xsd">

    <parent>
        <groupId>com.drawcode</groupId>
        <artifactId>detail-page</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <relativePath>../pom.xml</relativePath> <!-- lookup parent from repository -->
    </parent>

    <modelVersion>4.0.0</modelVersion>
    <artifactId>detail-service</artifactId>
    <packaging>jar</packaging>
    <name>detail-service</name>

    <!--detail-service依赖于detail-client-->
    <dependencies>
        <dependency>
            <groupId>com.drawcode</groupId>
            <artifactId>detail-client</artifactId>
        </dependency>
    </dependencies>
</project>

4. pom.xml детализации-начало

Проще, потому что у detail-start нет зависимостей

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">

    <parent>
        <groupId>com.drawcode</groupId>
        <artifactId>detail-page</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <relativePath>../pom.xml</relativePath> <!-- lookup parent from repository -->
    </parent>

    <modelVersion>4.0.0</modelVersion>
    <artifactId>detail-client</artifactId>
    <packaging>jar</packaging>
    <name>detail-client</name>

    <dependencies>
    </dependencies>

    <build>
    </build>

</project>

С помощью вышеуказанных документов мы можем проанализировать следующие отношения:

- detail-page:父模块
  - detail-client:子模块,无依赖
  - detail-service:子模块,依赖detail-client
  - detail-start:子模块,依赖detail-service

Примечание: В процессе ссылки на зависимости не должно быть циклической зависимости.Например, клиент ссылается на сервис, а сервис тоже ссылается на клиента.Если это произойдет, maven сообщит об ошибке непосредственно при упаковке

Рекомендуется настроить информацию о пакете в pom.xml в родительском модуле, за исключением пакетов, используемых каждым подмодулем отдельно, чтобы облегчить контроль версий пакета.

После того, как в проекте существует зависимость пакета, можно использовать код между различными модулями.Например, если служба_детали зависит от клиента-детали, то Test2 в клиенте-детали может использоваться службой-детали.

Но в свою очередь, деталь-клиент не может использовать классы в детали-службе, потому что зависимость является односторонней связью.

Как начать

Команда запуска выглядит следующим образом

$ mvn clean install && mvn spring-boot:run -pl detail-start

Среди них можно использовать spring-boot:run из-за наличия spring-boot-maven-plugin.

-pl detail-start представляет каталог подмодуля с классом запуска приложения.

Код ссылки

https://github.com/guanpengchn/detail-page/tree/demo1

В этой статье используетсяmdniceнабор текста