はじめに
弊PJでは新規にサービスをホストするにあたり、同期処理を行うSpring BootのWebと非同期処理を行うLambdaが必要となりました。(背景は割愛)
WebとLambdaは同じデータを参照しドメインを共有するため、別のマイクロサービスとして分割するとロジックの重複や、ロジックの重複を避けるための依存など分割損が発生すると考えました。(詳細は割愛)
そこで、弊PJではSpring BootのWebとLambdaをモノレポで構築する判断を行いました。
生成AIとモノレポの相性の良さも後押ししてます。
実施にあたり情報量の少なさを感じたため、留意点・最小構成の作成手順・商用展開に向けた構成概要を記載します。
留意点
SnapStartの制約
Spring Bootは起動(初期化)に時間を要するため、SnapStartを利用することで起動済の状態を保持します。
SnapStartの制約として以下が留意事項となりました。
- コンテナイメージがサポートされない
- SnapStart を使用できるのは、発行済みの関数バージョンと、バージョンをポイントするエイリアスのみ。
【参考】Lambda SnapStart による起動パフォーマンスの向上
※上記ではフィーチャーしたい制約のみ記載してます。詳細は公式を参照ください。
コンテナイメージがサポートされないためJarの利用が必須となります。
Jarの制約
Lambdaのファイルアップロードは50MBの制限があります。
S3経由にすることで50MB制限は回避できるものの、デプロイパッケージ全体の制約として250MBの制限があります。
【参考】Lambda クォータ
着手した当初は容量制限を回避するためコンテナイメージの利用を想定してましたが、SnapStartでJarが必須となるため容量制限を受けることとなります。
最小構成のサンプル作成
Spring BootのWebを作成した上で、Spring Cloud FunctionによるLambdaを追加するサンプルを作成します。
公式(AWS Lambda :: Spring Cloud Function - リファレンス)に準ずる内容となってますが、最低限の内容のみをピックアップしております。
ベースプロジェクト
Spring Initializrを利用してベースとなるプロジェクトを作成します。
Javaのバージョンは各環境のJavaのバージョンに合わせる必要があります。
| 項目 | 入力 |
|---|---|
| Project | Maven |
| Language | Java |
| Spring Boot | 4.0.2 |
| Project Metadata > Packaging | Java |
| Project Metadata > Configuration | YAML |
| Project Metadata > Java | 25 |
GENERATEボタンでZipファイルをDLし、任意の場所に展開します。
Webの追加・動作確認
追加
pom.xmlのproject > dependenciesに以下を追加。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
src/main/java/com/example/demo/にWeb用のRESTコントローラを作成。
package com.example.demo;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class DemoController {
@GetMapping("/hello")
public String hello() {
return "Hello, World!";
}
}
動作確認
以下のコマンドでサーバ起動。
./mvnw spring-boot:run
http://localhost:8080/helloへアクセスし、ページが表示されることを確認。

Lambdaの追加・動作確認
追加
pom.xmlのproject > dependenciesに以下を追加。
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-function-adapter-aws</artifactId>
<version>5.0.1</version>
</dependency>
Spring Boot 3系を利用する場合、spring-cloud-function-adapter-awsは4系に落とす必要があります。
※本サンプルはSpring Boot 4系
Java Lambdaで調べているとaws-lambda-java-coreを追加したくなりますが、追加せずとも動作します。
Lambdaからのリクエストを直接受け付けるのはSpring Cloud Functionであるため、依存の追加は必要ないと思われます。
src/main/java/com/example/demo/にSpring Cloud Functionを通してLambdaから呼び出されるBeanを作成。
package com.example.demo;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.function.Function;
@Configuration
public class DemoLambdaHandler {
@Bean
public Function<String, String> uppercase() {
return String::toUpperCase;
}
}
pom.xmlのproject > build > pluginsを以下に変更。
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.boot.experimental</groupId>
<artifactId>spring-boot-thin-layout</artifactId>
<version>1.0.31.RELEASE</version>
</dependency>
</dependencies>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.6.1</version>
<configuration>
<createDependencyReducedPom>false</createDependencyReducedPom>
<shadedArtifactAttached>true</shadedArtifactAttached>
<shadedClassifierName>aws</shadedClassifierName>
</configuration>
</plugin>
</plugins>
spring-boot-thin-layout
spring-boot-maven-pluginにspring-boot-thin-layoutを追加することによりjarのサイズを圧縮します。(ないと50MB超えます。)
spring-boot-thin-layoutはspring-projects-experimentalに属するExperimentalなプロジェクトで、Mavenの最新バージョンは2023年です
弊PJにおいてはspring-boot-thin-layoutは利用せず、モジュラーモノリスの構成にすることでLambda用に軽量Jarを生成しています。
spring-boot-thin-layoutについてClaude Opus 4.5に解説してもらったものが以下です。
正確な情報はspring-boot-thin-launcherを確認してください。
Claudeによるspring-boot-thin-layout の解説
概要
このプラグイン設定は、Spring BootアプリケーションをThin JAR形式でビルドするための構成です。
各要素の説明
1. spring-boot-maven-plugin
Spring Boot標準のMavenプラグインで、以下の機能を提供します:
- 実行可能JARの作成
-
mvn spring-boot:runでのアプリケーション起動 - 依存関係の管理
2. spring-boot-thin-layout
通常のSpring Boot JARとThin JARの違い:
| 項目 | Fat JAR(通常) | Thin JAR |
|---|---|---|
| サイズ | 大きい(数十〜数百MB) | 小さい(数KB〜数MB) |
| 依存関係 | JAR内に同梱 | 実行時にダウンロード |
| 初回起動 | 速い | 遅い(依存関係取得が必要) |
| 2回目以降 | 同じ | 速い(キャッシュ利用) |
Thin JARの仕組み
通常のFat JAR:
┌─────────────────────┐
│ アプリケーションコード │
│ すべての依存ライブラリ │ ← 全部入り
└─────────────────────┘
Thin JAR:
┌─────────────────────┐
│ アプリケーションコード │
│ pom.xml / 依存情報 │ ← 依存関係は実行時に取得
└─────────────────────┘
使用シーン
Thin JARが適しているケース:
- Docker/コンテナ環境 — レイヤーキャッシュを活用でき、イメージサイズを削減
- CI/CDパイプライン — アーティファクトの転送時間を短縮
- マイクロサービス — 多数のサービスをデプロイする際に効率的
- Lambda等のサーバーレス — デプロイパッケージサイズの制限対策
注意点
- 初回起動時にネットワーク接続が必要
- 依存関係のリポジトリが利用可能である必要がある
- バージョン
1.0.31.RELEASEはやや古いため、最新版の確認を推奨
maven-shade-plugin
Maven Shade Pluginを追加することでLambdaへアップロードするFat jarを生成します。
maven-shade-pluginについてClaude Opus 4.5に解説してもらったものが以下です。
正確な情報はshade:shade – Apache Maven Shade Pluginを確認してください。
ClaudeによるMaven Shade Plugin の解説
概要
maven-shade-plugin は、プロジェクトとその依存関係をすべて含む単一の「uber-jar」(fat jar)を作成するためのプラグインです。Spring Boot を AWS Lambda で動作させる場合によく使われます。
各設定の意味
createDependencyReducedPom
<createDependencyReducedPom>false</createDependencyReducedPom>
通常、Shade プラグインは uber-jar に含めた依存関係を除外した dependency-reduced-pom.xml を生成します。false にすると、このファイルを生成しません。ローカル開発やシンプルなデプロイでは不要なことが多いです。
shadedArtifactAttached
<shadedArtifactAttached>true</shadedArtifactAttached>
true にすると、shade された jar を別のアーティファクトとして元の jar に「添付」します。これにより元の jar が上書きされず、両方が target/ に出力されます。
shadedClassifierName
<shadedClassifierName>aws</shadedClassifierName>
添付されるアーティファクトの classifier 名を指定します。この例では aws なので、出力ファイルは以下のようになります:
| ファイル | 説明 |
|---|---|
| myapp-1.0.0.jar | 元の jar(依存関係なし) |
| myapp-1.0.0-aws.jar | shade された uber-jar |
ビルド・デプロイ
以下のコマンドでJarを作成。
./mvnw clean package
AWS上で以下を満たすLambdaを用意
※Lambdaの作成手順は省略。
コードタブ
| 設定値 | 確認内容 |
|---|---|
| ランタイム (ランタイム設定) |
Java 25 |
| ハンドラ (ランタイム設定) |
org.springframework.cloud.function.adapter.aws.FunctionInvoker::handleRequest |
設定タブ
| 設定値 | 確認内容 |
|---|---|
| SnapStart (一般設定) |
PublishedVersionsであること |
| 実行ロール (アクセス権限) |
AWSLambdaBasicExecutionRole相当が含まれるIAM Roleであること |
| 環境変数(環境変数) | 下表の通り |
環境変数
| キー | 値 |
|---|---|
| MAIN_CLASS | com.example.demo.DemoApplication |
| SPRING_CLOUD_FUNCTION_DEFINITION | uppercase |
target/demo-0.0.1-SNAPSHOT-aws.jarをアップロード
バージョンタブで新しいバージョンを発行
動作確認
SnapStartの作成完了後、テストタブでテスト
実際のサービス提供における構成
上記の最小構成サンプルでは、シングルモジュールの構成でspring-boot-thin-layoutにより容量を削減したLambda用のJarを作成しました。
ただし、spring-boot-thin-layoutはspring-projects-experimentalに属するExperimentalなプロジェクトで、Mavenの最新バージョンは2023年のリリースです。
正式サポートが継続するプロジェクトではないため、弊PJにおいてはspring-boot-thin-layoutは利用せず、シングルモジュールからマルチモジュール(モジュラーモノリス)にすることでLambda用に軽量Jarを生成しています。
以下のような構成とすることで、lambdaのjarにwebが含まれない構成となっております。
| モジュール名 | モジュールの内容 |
|---|---|
| parent | 親POM |
| web | Webのコンテキスト |
| lambda | Lambdaのコンテキスト |
| core | web・lambdaから依存される中核モジュール (ドメイン・サービス・共通処理・DBアクセス 等) |
さいごに
AWS Lambda :: Spring Cloud Function - リファレンスやspring-cloud-function-samplesの情報では適切な構成の検討が難しいと感じ、本記事を執筆しました。
同じ悩みを抱えている方の参考になりましたら幸いです。







