Skip to content

Spring Boot でマルチモジュールアプリを作成

依存関係を持つ複数のプロジェクトを用いてアプリをビルドする手順です。
cf. https://spring.pleiades.io/guides/gs/multi-module/

プロジェクト構成

multi-module
  ├─app-project
  │   └─(Spring Bootプロジェクト)
  ├─web-project
  │   └─(Spring Bootプロジェクト)
  ├─.mvn
  ├─mvnw
  └─pom.xml

web-projectapp-projectに依存します。

実装

app および web の実装方法を記載します。

app-project

web 側から呼ばれるモジュールです。

サービスインターフェース

ドキュメントとしてわかりやすいようにエンドポイントは設けませんが、こちらにも@RequestMapping などのアノテーションによってエンドポイントを付与できます。

package com.example.appproject.service;

import org.springframework.stereotype.Service;

/**
 * サンプルのappインターフェースです。
 *
 */
@Service
public interface SampleAppService {

    /**
     * サンプルのappメソッドです。
     *
     * @return 固定メッセージ
     */
    String greeting();
}

サービス実装

固定メッセージを返却するだけの実装です。

package com.example.appproject.service.impl;

import org.springframework.stereotype.Service;

import com.example.appproject.service.SampleAppService;

/**
 * サンプルappサービスの実装クラスです。
 *
 */
@Service
public class SampleAppServiceImpl implements SampleAppService {

    /**
     * {@inheritDoc}
     *
     */
    @Override
    public String greeting() {

        return "Hello, multi module!";
    }
}

pom.xml

実行可能 jar をビルドしないようにするため、<build>ブロックを丸ごと消します。

<?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">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.2.0</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>app-project</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>app-project</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>17</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <!-- <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build> -->
</project>

web-project

app-projectを呼び出すモジュールです。

メインクラス

依存関係に含まれる自作パッケージをスキャンする旨を追記します。

package com.example.webproject;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication(scanBasePackages = { "com.example" }) // 自身を含む、依存するパッケージを記載する
public class WebProjectApplication {

    public static void main(String[] args) {
        SpringApplication.run(WebProjectApplication.class, args);
    }
}

サービスインターフェース

エンドポイントを設けて公開 API 実装とします。

package com.example.webproject.service;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * サンプルのwebインターフェースです。
 *
 */
@RestController
@RequestMapping(value = "/web")
public interface SampleWebService {

    /**
     * サンプルのwebメソッドです。
     *
     * @return
     */
    @GetMapping(value = "/greet")
    String greeting();
}

サービス実装クラス

@Autowiredで app 側のサービスを Bean 宣言して呼び出します。

package com.example.webproject.service.impl;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.example.appproject.service.SampleAppService;
import com.example.webproject.service.SampleWebService;

/**
 * サンプルwebサービスの実装クラスです。
 *
 */
@Service
public class SampleWebServiceImpl implements SampleWebService {

    // app serviceをBean宣言
    @Autowired
    private SampleAppService sampleAppService;

    /**
     * {@inheritDoc}
     *
     */
    @Override
    public String greeting() {

        // app service呼び出し
        return sampleAppService.greeting();
    }
}

pom.xml

app-project を依存関係に追加:

<dependency>
    <groupId>com.example</groupId>
    <artifactId>app-project</artifactId>
    <version>0.0.1-SNAPSHOT</version>
</dependency>

する以外はデフォルトのままです。

<?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">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.2.0</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>web-project</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>web-project</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>17</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <!-- for app project -->
        <dependency>
            <groupId>com.example</groupId>
            <artifactId>app-project</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

multi-module

親プロジェクトの設定です。

pom.xml

packagingタグをpomとし、modulesタグにビルドするモジュールたちを記載します。

<?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">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.springframework</groupId>
    <artifactId>gs-multi-module</artifactId>
    <version>0.1.0</version>
    <packaging>pom</packaging>

    <modules>
        <module>app-project</module>
        <module>web-project</module>
    </modules>

</project>

mvn 関連

VSCode の機能で自動生成したものを app-project 等からコピーしてくるのが楽です。

cp -r mvnw* .mvn ..

ビルド

プロジェクトのルートディレクトリにて、下記コマンドで各モジュールがビルドされます。

./mvnw package

web-projectの jar を起動してエンドポイントにアクセスすると、app-projectモジュールを呼び出していることが確認できます。