Java と Spring Boot の Web アプリ開発を AI コーディングエージェントで爆速化する — Claude Code と Codex 時代のリポジトリ整備指針
Spring Boot で Web アプリケーションを書くチームに Claude Code、OpenAI Codex、Cursor、GitHub Copilot を導入したい、というのは 2026 年時点で珍しい相談ではありません。新しいリリース(Spring Boot 4.0 と Java 25 LTS)が出揃って次のスタックを引き直す機運が出てきていることもあって、「ついでに AI 前提で組み直したい」という話は重なって増えています。
ここで多くのチームが落とし穴にハマるのは、AI ツール自体の選定やモデルの使い分けのような表面の議論に時間を吸われ、肝心のリポジトリ側を整える作業が後回しになる、というパターンです。実際は、ツール・モデル選定を含めても 1〜2 割の効果しか出ず、本当に効くのはコードベースを「AI が誤解しにくい形」に整備することの方です。
本記事では、Java と Spring Boot で Web アプリケーション開発を進めるチームが、Claude Code や Codex のような AI コーディングエージェントを爆速で走らせるためにやるべきことを、設計、CI ガードレール、Model Context Protocol(MCP)連携、セキュリティの順で整理します。先に Java と Spring Boot で構築された有名な OSS Web アプリケーション で扱ったエコシステムの広がりを前提に、新規プロジェクト立ち上げと既存プロジェクトのモダナイズの両方に効く形でまとめます。
なぜ Java と Spring Boot の AI 開発に「下準備」が必要か
Java は AI コーディングエージェントとの相性が、見た目以上に良い言語です。@RestController や @Service、@Repository、@Transactional といったアノテーション駆動のプログラミングモデル、強い型システム、Maven / Gradle が宣言する明確な依存関係グラフは、すべて AI にとって「読みやすい文脈」になります。Spring Boot のレイヤー慣習(Controller → Service → Repository)も、AI が「次に何を書けばいいか」を推測する手がかりとして強力です。
一方で、Java は AI 生成コードのセキュリティ品質という観点では難しい言語でもあります。Veracode の調査では、AI モデルのコード構文正答率が 95% を超えるなかで、Java のセキュリティ合格率は 28% と最低水準です。古い String + " " 連結による SQL 構築、javax.* と jakarta.* の混入、Lombok 全盛期の冗長なボイラープレートなど、AI が学習データから引きずってくるアンチパターンが多すぎるのが理由です。
つまり Java + Spring Boot の AI 開発は、放っておくと「速いけれど壊れたコードを大量に出す」状態になりやすく、整備すれば「速くて型安全で監査しやすいコードを出せる」状態になります。鍵になるのは、AI が読みやすい設計、AI が読むファイルを散らからせない統一、CI で機械的に検証されるガードレールの 3 層構造です。本記事はこの 3 層を順に積み上げていきます。
AI が読みやすい設計を最初に固める — Spring Modulith とヘキサゴナル
最初に決めるべきはバージョンとアーキテクチャです。2026 年 5 月時点での基準は次のとおりに置けます。
| 項目 | 推奨 | 理由 |
|---|---|---|
| Spring Boot | 4.0.x(先端)または 3.5.x(保守) | 3.5.x の OSS サポートは 2026/06/30 で終了予定。新規なら 4.0.x、依存ライブラリの 4 系対応待ちなら 3.5.x |
| Java | 21 LTS(安定)または 25 LTS(先端) | Virtual Threads / Pattern Matching が安定。25 LTS は Spring Boot 4.0 で first-class |
| ビルド | Gradle Kotlin DSL | 型安全な build.gradle.kts が IDE 補完で効きやすく、AI が誤った XML を作る事故を減らせる |
| JDK ベンダー | Eclipse Temurin または Amazon Corretto | 無償・運用実績ともに無難。Codex / Devin のサンドボックスでも標準 |
Maven は AI の学習データが圧倒的に多く、Spring 公式サンプルも Maven 寄りなので、Codex や Cursor は初手で pom.xml を書きがちです。Gradle で進めるなら、AGENTS.md や CLAUDE.md に「このプロジェクトは Gradle Kotlin DSL を使う、pom.xml 作成禁止」と明示しておかないと、何度も同じ修正をすることになります。
アーキテクチャは Spring Modulith 2.0 と、各モジュール内をヘキサゴナル構造(domain → application → adapter.in/out)にする組み合わせが現時点でのベターです。レイヤード Monolith は AI が「適切な層に置く」を学習しやすい反面、機能が増えるとパッケージ越境を平気でやらかします。マイクロサービスは初日から組むと運用コストが過剰です。Modular Monolith なら、AI に「機能の境界」を教えやすく、後から 1 モジュールだけ切り出せます。
com.example.app
├── AppApplication.java
├── design/ # 1 モジュール = 1 機能(Bounded Context)
│ ├── api/ # Driving Port(@NamedInterface)
│ ├── domain/ # Spring 非依存
│ │ ├── model/
│ │ └── service/
│ ├── application/ # ユースケース
│ └── adapter/
│ ├── in/web/ # @RestController
│ ├── in/event/ # @ApplicationModuleListener
│ └── out/persistence/ # JPA / jOOQ
├── catalog/
├── workspace/
└── shared/ # クロスモジュール utility(最小限)各モジュールは直下のサブパッケージを public、それ以外を package-private にする(Spring Modulith のデフォルト規約)。モジュール間連携は Application Events(@ApplicationModuleListener)で疎結合化する。これだけ決めておけば、AI が「他モジュールの @Service を直接 inject する」という事故を、後段の ArchUnit と Modulith verify で機械的に止められます。
エージェント別の指示ファイルはとっ散らかさず統一する
Claude Code の CLAUDE.md、Codex の AGENTS.md、GitHub Copilot の .github/copilot-instructions.md、Cursor の .cursor/rules/ を別々に手書きすると、規約がドリフトしてエージェントごとに違う前提で動き出します。1 つを真実のソースにして残りをシンボリックリンクで束ねるなどの方法で、Gradle Kotlin DSL を使う、pom.xml 作成禁止 や 既存の V*.sql は編集禁止 といった Spring Boot 固有の運用ルールが、どのエージェントから見ても同じ内容で読める状態を保ちます。
Claude Code の Skills、Subagents、Slash Commands で役割を増やす
Claude Code には、.claude/skills/(自動ロードされる知識パック)、.claude/agents/(独立コンテキストの専門家エージェント)、.claude/commands/(スラッシュコマンド)、.claude/hooks/(ライフサイクルフック)の 4 軸の拡張ポイントがあります。これらは AGENTS.md と組み合わせると、リポジトリ全体のルールに加えて、特定タスク専用の「副司令官」を準備できる仕組みになります。
.claude/
├── agents/
│ ├── spring-boot-engineer.md # 実装担当
│ ├── test-automator.md # JUnit 5 + Testcontainers
│ ├── security-engineer.md # Spring Security / OWASP(Opus 推奨)
│ ├── db-migrator.md # Flyway スクリプト専任
│ └── code-reviewer.md # PR レビュー(Sonnet)
├── skills/
│ ├── spring-boot-core/SKILL.md
│ ├── jpa-patterns/SKILL.md
│ ├── flyway-migrations/SKILL.md
│ ├── spring-security/SKILL.md
│ ├── testcontainers/SKILL.md
│ └── archunit-rules/SKILL.md
├── commands/
│ ├── plan.md
│ ├── tdd.md
│ ├── code-review.md
│ ├── api-design.md
│ └── build-fix.md
└── settings.local.jsonたとえば db-migrator のような Subagent は、「Flyway のマイグレーションを追加する」という危険を伴うタスクを限定的なツール権限で完遂させる用途に向きます。
---
name: db-migrator
description: スキーマ変更が必要なときに使う。新規 V*.sql を追加し、既存 V*.sql は絶対に編集しない。jOOQ 利用時は再生成し、テストを実行する。
tools: Read, Grep, Glob, Edit, Write, Bash
model: sonnet
---
あなたは Spring Boot + Flyway + PostgreSQL の慎重なマイグレーション担当です。
呼び出されたら:
1. `src/main/resources/db/migration/` を見て最新のバージョン番号を確認する
2. `V{yyyyMMddHHmm}__{snake_case_description}.sql` を作成する。冪等な DDL を優先する
3. 既存の V*.sql ファイルは絶対に編集しない(Flyway チェックサムが壊れる)
4. `./gradlew flywayMigrate -Pdev` と `./gradlew test` を実行する
5. jOOQ を使っている場合は `./gradlew generateJooq` を実行する
6. 人間レビュアー向けにロールバック手順を含めた変更サマリを書くこの設計のうれしさは、Claude Code 本体のセッションでは「データベースに触らないように」と注意し続けなくても、db-migrator Subagent を呼んだときだけマイグレーション操作を許可できる点にあります。Skills のほうは、たとえば「JPA の N+1 問題を避けるため、@OneToMany には JOIN FETCH または @EntityGraph を使う」のような JPA / Spring 規約の知識を SKILL.md に詰め、必要なときに Claude が自動でロードする形で運用します。
スラッシュコマンドは、/plan(実装計画作成)、/tdd(失敗テスト → 実装 → リファクタ)、/code-review、/api-design、/build-fix の 5 つを揃えておくとほぼ過不足ありません。スラッシュコマンドは Claude Code プラグインとしてバンドルすれば、社内チーム全体に同じ運用を配布できます。
ガードレールを CI に焼き込む — Spotless、ArchUnit、Modulith verify
AI に速くコードを書かせるほど、CI の品質ゲートは強くする必要があります。AI が層越境を犯した瞬間、依存方向を逆走させた瞬間、System.out.println を埋めた瞬間に、CI が即座に落ちる仕掛けを ./gradlew check 一発で実行できる状態にしておく、というのが理想です。
最低限揃えるべきツールは次のとおりです。
| 目的 | ツール | 理由 |
|---|---|---|
| フォーマット | Spotless + Spring Java Format | Spring 公式と同じスタイルを自動適用。エディタ設定不要で AI 出力もそのまま揃う |
| Lint | Checkstyle(最小ルール) | Spotless が大半をカバーするので命名規則・Javadoc の補完用途に絞る |
| バグ検出 | Error Prone + NullAway | コンパイル時に NPE / API 誤用を検出 |
| アーキ検証 | ArchUnit + Spring Modulith verify | AI が層越境した瞬間に CI が落ちる。最重要 |
| テストカバレッジ | JaCoCo | ライン 80% / ブランチ 70% を CI で必須化 |
| 静的解析 | CodeQL + Semgrep | 両方併用で OWASP 系の検出率が上がる |
| 依存性スキャン | OWASP Dependency-Check + Trivy | NVD ベースと FS / コンテナ両対応のハイブリッド |
| シークレット検出 | Gitleaks + GitHub Push Protection | .env / API キーの誤コミットを発生前に止める |
ArchUnit のルールは、Java で書ける宣言的なテストとして CI に乗ります。次のような書き方をしておけば、AI が @RestController から @Repository を直接呼んだり、domain/ パッケージに @Entity を生やそうとした瞬間に、ビルドが落ちるようになります。
@AnalyzeClasses(packages = "com.example.app", importOptions = DoNotIncludeTests.class)
class ArchitectureTest {
@ArchTest
static final ArchRule layered = layeredArchitecture().consideringAllDependencies()
.layer("Domain").definedBy("..domain..")
.layer("Application").definedBy("..application..")
.layer("AdapterIn").definedBy("..adapter.in..")
.layer("AdapterOut").definedBy("..adapter.out..")
.whereLayer("Application").mayOnlyBeAccessedByLayers("AdapterIn")
.whereLayer("Domain").mayOnlyBeAccessedByLayers("Application", "AdapterOut");
@ArchTest
static final ArchRule domainIsFrameworkFree = noClasses()
.that().resideInAPackage("..domain..")
.should().dependOnClassesThat().resideInAnyPackage(
"org.springframework..", "jakarta.persistence..", "com.fasterxml.jackson..");
@ArchTest
static final ArchRule controllersDontCallRepositories = noClasses()
.that().resideInAPackage("..adapter.in.web..")
.should().dependOnClassesThat().resideInAPackage("..adapter.out.persistence..");
@Test
void modulesAreVerified() {
ApplicationModules.of(AppApplication.class).verify();
}
}pre-commit 側は Lefthook(Go 製、cross-platform)が軽量で、Java バックエンドプロジェクトとの相性が良いです。
# lefthook.yml
pre-commit:
parallel: true
commands:
spotless:
glob: "*.java"
run: ./gradlew spotlessApply
stage_fixed: true
no-system-out:
glob: "src/main/java/**/*.java"
run: |
if grep -rn "System\.out\.println" {staged_files}; then
echo "System.out.println is forbidden. Use SLF4J Logger."; exit 1
fi
pre-push:
commands:
test:
run: ./gradlew checkAI への指示としては、AGENTS.md に「完了条件はコンパイル成功 + テスト成功 + 静的解析成功 + 依存性スキャン成功、検証コマンドは ./gradlew check」と明示しておきます。検証コマンドが単一化されていると、Claude Code や Codex が「タスクがいつ終わったか」を自分で判定できるようになり、人間の手戻りが大きく減ります。
テストを Testcontainers と TDD で AI に書かせる
AI に書かせたコードを安全に出荷する最大の保険は、テスト駆動開発(TDD)と Testcontainers の組み合わせです。Spring Boot 3.1 以降は @ServiceConnection が標準化されているため、設定ファイルを書き換えずに本物の PostgreSQL や Redis をテストコンテナで起動できます。
@TestConfiguration(proxyBeanMethods = false)
class TestcontainersConfiguration {
@Bean
@ServiceConnection
PostgreSQLContainer<?> postgresContainer() {
return new PostgreSQLContainer<>("postgres:16-alpine").withReuse(true);
}
@Bean
@ServiceConnection(name = "redis")
GenericContainer<?> redisContainer() {
return new GenericContainer<>("redis:7-alpine")
.withExposedPorts(6379)
.withReuse(true);
}
}
// ローカル開発も Testcontainers をそのまま使う(src/test/java)
public class TestAppApplication {
public static void main(String[] args) {
SpringApplication.from(AppApplication::main)
.with(TestcontainersConfiguration.class)
.run(args);
}
}./gradlew bootTestRun で TestAppApplication を起動すれば、AI エージェントが「ローカル DB が無い」で詰まることがなくなります。.testcontainers.properties に testcontainers.reuse.enable=true を入れておくと 2 回目以降が高速で、テスト体感も大きく変わります。
テストの粒度は、Web 層を @WebMvcTest + MockMvc で薄く、Repository 層を @DataJpaTest + Testcontainers PostgreSQL、統合は @SpringBootTest + @Import(TestcontainersConfiguration.class)、と切り分けます。AGENTS.md に「Controller テストに @SpringBootTest を使うな、Web スライスを使え」と明記しておくと、AI が重い統合テストを Controller 単体テストに使ってビルド時間を膨らませる事故を防げます。
TDD ループで Claude Code や Codex を回す場合は、/tdd のようなスラッシュコマンドにして「失敗するテストを書く → 実装する → リファクタする」の Red-Green-Refactor を 1 コマンドにまとめてしまうのが楽です。Claude Code は mvn test や ./gradlew test の出力からスタックトレースを読み取り、自己修正を繰り返す挙動が安定しているので、テストさえ正しく書けていれば実装の品質は AI 側でかなり詰められます。Parasoft の AI 駆動 Java ユニットテスト導入事例では、AI 駆動 TDD の導入でユニットテスト作成時間を 100% 高速化し、最重要マイクロサービスのコードカバレッジが数週間で 20% から 85% に到達したという報告もあります。
フィードバックループを縮める — Gradle ビルドキャッシュと Spring Boot DevTools
Java + Spring Boot は、TypeScript や Python のような、AI の学習データが豊富で得意とされる言語と比べると、AI に書かせて即座に動作確認まで回すフィードバックループが長くなりがちです。JVM 起動、Spring の Bean 初期化、Testcontainers のコンテナ起動など、避けにくいオーバーヘッドが多いためです。AI コーディングエージェントを爆速で回すには、このループを物理的に縮める仕組みを最初から仕込む必要があります。何もしないと、Claude Code や Codex が ./gradlew test の終了を 3〜5 分待つたびに人間が監督できない時間が積み上がり、結局「速くない」開発体験になります。
Gradle のキャッシュとデーモンを最大限使う
gradle.properties に次を入れておきます。
org.gradle.daemon=true
org.gradle.parallel=true
org.gradle.caching=true
org.gradle.configuration-cache=true
org.gradle.jvmargs=-Xmx4g -XX:+UseG1GCdaemon: Gradle 自体を常駐プロセスとして再利用し、毎回の JVM 起動を省くparallel: マルチモジュールのサブプロジェクトを並列ビルドcaching: ビルドキャッシュ。一度通ったタスクの結果を再利用configuration-cache: ビルド設定の解析結果をキャッシュ。2 回目以降の起動が秒で済む
組織で開発者数が多い場合は、Develocity や OSS の Build Cache 共有サーバを立てて、CI とローカルで成果物を共有すると、初回ビルドも数倍速くなります。
Continuous Build で AI を変更検出に乗せる
./gradlew test --continuous(短縮形 -t)を別ターミナルで起動しておくと、Gradle がファイル変更を監視して、変更があったタスクだけを自動再実行します。AI エージェントが編集 → 保存した瞬間にテストが裏で走り出すので、フィードバックの待ち時間がほぼゼロになります。Claude Code の Hooks で PostToolUse に「対象ファイルに対応するテストだけ実行」を仕込むのも代替手段ですが、Continuous Build の方が単純で壊れにくいです。
Spring Boot DevTools と bootTestRun
Spring Boot DevTools を developmentOnly で入れておくと、クラスパスの変更を検知して独立したクラスローダーでアプリを自動再起動します。コールドスタートより 5〜10 倍速く、@RestController のレスポンス変更や @Service のロジック修正が秒で反映されます。
dependencies {
developmentOnly("org.springframework.boot:spring-boot-devtools")
}./gradlew bootTestRun と Testcontainers @ServiceConnection(前述)と組み合わせれば、ローカル DB の起動コストも 1 回限りに抑えられます。AI が「動作確認したい」と言うより前に、エンドポイントが既に最新になっている状態を作れます。
テストを「軽い」種類に寄せる
実は最も効くのは、テストを物理的に軽くすることです。@SpringBootTest はアプリケーションコンテキスト全体を起動するので 1 件あたり 5〜10 秒かかりますが、@WebMvcTest は Web 層だけ、@DataJpaTest は JPA 層だけを起動するので 1 件 0.5 秒以下で済みます。
| テスト種別 | アノテーション | 1 件あたり所要時間 |
|---|---|---|
| 単体 | @ExtendWith(MockitoExtension.class) | 0.1 秒以下 |
| Web スライス | @WebMvcTest | 0.3〜0.8 秒 |
| JPA スライス | @DataJpaTest | 0.5〜1.5 秒 |
| 統合 | @SpringBootTest | 5〜15 秒 |
./gradlew test --tests "com.example.app.design.*" で対象を絞り、maxParallelForks で並列実行し、JaCoCo の重い計測は CI のみに寄せると、ローカルのフィードバックループは TypeScript ほどには届かなくても、十分実用速度に近づきます。
tasks.test {
useJUnitPlatform()
maxParallelForks = (Runtime.getRuntime().availableProcessors() / 2).coerceAtLeast(1)
}AI エージェント側のタイムアウト管理
フィードバックループを縮めても、AI が長時間待ち続けるなら意味がありません。Claude Code や Codex のシェル実行には既定でタイムアウトがあるので、timeout 60s ./gradlew test --tests TargetTest のように明示的にラップしておくか、Continuous Build を別ターミナルで走らせておいて AI には結果レポート(build/reports/tests/test/index.html)だけ読ませる運用にすると、「ビルド待ちで会話が止まる」事故を減らせます。
Spring AI MCP で「実行中のアプリ」を AI に渡す
AI コーディングエージェントは、ソースコードを読むだけでもかなりの作業ができますが、「実行中のアプリケーションの状態を直接見る」ことができると、デバッグ精度が一段上がります。これを実現するのが Model Context Protocol(MCP)で、Spring AI 1.1(2025 年 11 月 GA)の spring-ai-starter-mcp-server-webmvc を使えば、開発中の Spring Boot アプリ自体を AI のための MCP サーバーとして動作させられます。
@Service
public class SpecTools {
private final SpecQueryService specQueryService;
public SpecTools(SpecQueryService specQueryService) {
this.specQueryService = specQueryService;
}
@McpTool(description = "List design specs for a project")
public List<SpecSummary> listSpecs(
@McpToolParam(description = "Project ID") String projectId
) {
return specQueryService.list(projectId);
}
}@McpTool が付いた Java メソッドは、AI から自然言語で呼べる「ツール」として認識されます。これにより、たとえば「最近のユーザー登録に失敗している原因を調査し、修正せよ」という指示に対して、AI が MCP 経由で実行中の DB のエラーログを取得し、該当するバリデーションエラーの原因を特定し、ソースコードのリファクタリングとテスト実行までを 1 タスクで完遂できるようになります。OAuth2 で守る場合は、Spring AI コミュニティが提供する org.springaicommunity:mcp-server-security-spring-boot(2026-04 時点で v0.1.8 が公開済みで Boot starter の Quick Start も整っているが、Spring AI 本体への正式統合は今後の予定)を追加し、spring.security.oauth2.resourceserver.jwt.issuer-uri を設定するだけで、Streamable HTTP / Resource Indicators / Dynamic Client Registration まで自動でカバーされます。
MCP 経由で AI に何かを渡すときの鉄則は、「本番接続情報は絶対渡さない」ことです。AI に物理的に触れさせるのは、Devcontainer 内の Testcontainers ベースの環境か、ステージングの READ ONLY レプリカに限定するのが安全です。
AI 生成コードを安全に出荷する — Java と Spring 固有の落とし穴を潰す
冒頭で触れたとおり、Java は AI による安全なコード生成が最も難しい言語の 1 つです。30 年分の学習データに古い危険パターンが含まれていること、javax / jakarta の二重化、デシリアライゼーション・XXE・SpEL のような Java 特有の脆弱性カテゴリが多いこと、が原因です。CI とレビューでは、この Java / Spring 固有のパターンに絞って重点的に塞ぎます。
| 脆弱性 | AI が犯しやすい誤り | Java / Spring 固有である理由 |
|---|---|---|
| CWE-502(安全でないデシリアライゼーション) | ObjectInputStream.readObject() で外部入力を扱う | Java の標準シリアライゼーションが歴史的に RCE の温床。Apache Commons Collections / Spring4Shell の系譜 |
| CWE-611(XXE) | DocumentBuilderFactory.newInstance() をそのまま使う | Java 標準 XML パーサーがデフォルトで外部実体を読みにいく。明示的に disallow-doctype-decl を立てないと止まらない |
| SpEL インジェクション | @Value("#{...}") や @PreAuthorize("...") にユーザー入力を流す | Spring Expression Language は文字列を動的評価。Spring4Shell(CVE-2022-22965)と同系統 |
| CWE-117(ログ注入) | logger.info("input: " + userInput) 形式の未洗浄ログ | Log4Shell(CVE-2021-44228)の血統 |
| Spring Security の緩い設定 | http.csrf().disable()、permitAll()、@CrossOrigin(origins = "*") | チュートリアルに頻出する「とりあえず動かすコード」を AI がそのまま再現する |
| JPA の生 SQL 連結 | @Query("SELECT ... WHERE name = " + name) | derived query や ?1 プレースホルダの代わりに文字列連結を提案してくる |
これらを CI で機械的に止めるには、汎用 SAST に Java / Spring 専用のルールセットを足します。CodeQL の Java / Kotlin クエリパックは SpEL インジェクション、Spring Security バイパス、JPA クエリインジェクションをカバーし、Semgrep の Spring ルールセットは csrf().disable() や permitAll() を即座に検出します。さらに SpotBugs Find Security Bugs を入れると、Java バイトコードレベルで XXE や SQL 注入を捕捉できます。OWASP Dependency-Check と Trivy で Log4j のような既知 CVE 入りバージョンの混入を弾けば、Java エコシステム特有のサプライチェーン攻撃面もカバーできます。
もう 1 つ、Java + Spring Boot 固有の有効な防衛線が、@Profile と application-{profile}.yml による認証情報の物理的隔離です。AI エージェントが触れるのは application-test.yml(Testcontainers ベースの内部 DB を指す)と application-dev.yml のみとし、application-prod.yml は AI のサンドボックスから物理的に見えない場所に置きます。
# application-test.yml — AI が触ってよい
spring:
datasource:
url: jdbc:tc:postgresql:16-alpine:///test
# application-prod.yml — AI のサンドボックスから物理的に見えない
spring:
datasource:
url: ${DATABASE_URL}
username: ${DATABASE_USERNAME}
password: ${DATABASE_PASSWORD}Devcontainer 構成や .gitignore / .cursorignore で application-prod* を AI から隔離し、起動は --spring.profiles.active=test か dev 限定にします。AGENTS.md には「@Profile("prod") 配下を編集するな」「本番値は環境変数経由でしか読まない」と明記しておきます。
まとめ
Java と Spring Boot の Web アプリ開発で AI コーディングエージェントを爆速化する、というのは、単にモデルやツールを選ぶことではありません。AI が読みやすい設計(Spring Modulith とヘキサゴナル)、AI 向け指示ファイルの統一、AI を物理的に縛るガードレール(ArchUnit、Modulith verify、Spotless、CI ゲート)の 3 層を、初日から積み上げることが効果のほぼすべてです。
その上で、Testcontainers と TDD で出力品質を担保し、Spring AI 1.1 の MCP Server で「実行中のアプリ」を AI に渡す。ここまで揃えると、AI エージェントは単なる「アシスタント」を超え、リポジトリのコンテキストを把握した「自律的な開発メンバー」として動き始めます。
エンジニアの役割は、自分ですべてのコードを書くことから、AI が高品質なコードを生み続けるための環境を設計することへと移っていきます。Java と Spring Boot は、その移行を引き受けるのに最も向いた言語とフレームワークの 1 つだと考えています。
以上、Java と Spring Boot の Web アプリ開発を AI コーディングエージェントで爆速化する、という観点から整理しました。