はじめに (対象読者・この記事でわかること)
この記事は、Spring Bootで開発しているが共通処理をライブラリ化したい方、マルチモジュールプロジェクトの構築に興味がある方向けです。Spring Bootアプリケーションをライブラリとして切り出し、複数のプロジェクトで再利用する方法について解説します。この記事を読むことで、Spring Bootアプリをライブラリ化する具体的な手順、マルチモジュール構成のメリット、Gradleでの設定方法がわかります。また、実際に動作するサンプルコードも提供するので、すぐに実践できるようになります。
前提知識
この記事を読み進める上で、以下の知識があるとスムーズです。 - Javaの基本的な知識(クラス、インターフェース、パッケージ) - Spring Bootの基礎(アノテーション、DI、AutoConfiguration) - Gradleでのビルド設定の基礎
なぜSpring Bootアプリをライブラリ化するのか?
Spring Bootアプリケーションを開発していると、「この処理、別のプロジェクトでも使いたいな」と思うことはありませんか?認証処理、ロギング、カスタムアノテーション、共通のユーティリティクラスなど、プロジェクトをまたいで使いたい処理は意外と多くあります。
従来の方法だと、コードをコピー&ペーストしたり、jarファイルを手動でコピーしていたりすると思います。しかし、これではバージョン管理が大変で、バグ修正や機能追加が面倒です。
そこで登場するのがSpring Bootアプリケーションのライブラリ化です。Spring BootのAutoConfiguration機能を活用することで、ライブラリとして利用する側は「依存関係を追加するだけ」で、簡単に機能を利用できるようになります。
主なメリットは以下の通りです:
- 再利用性の向上:一度実装した機能を複数プロジェクトで共有
- 保守性の向上:ライブラリを修正するだけで、すべてのプロジェクトが更新
- 開発効率の向上:共通処理に時間をかけずに、ビジネスロジックに集中できる
- テスタビリティ:ライブラリ単体でテストを実行可能
Spring Bootライブラリの作り方〜マルチモジュール構成で実装する〜
それでは、実際にSpring Bootアプリケーションをライブラリ化する方法を見ていきましょう。ここでは、認証処理を担当するライブラリを作成する例で説明します。
プロジェクト構成の設計
まず、マルチモジュールプロジェクトの構成を設計します。今回は以下のような構成にします:
spring-boot-library-example/
├── authentication-library/ # ライブラリモジュール
│ ├── src/main/java/
│ │ └── com/example/auth/
│ │ ├── config/
│ │ │ └── AuthAutoConfiguration.java
│ │ ├── service/
│ │ │ └── AuthenticationService.java
│ │ └── annotation/
│ │ └── EnableAuth.java
│ └── src/main/resources/
│ └── META-INF/
│ └── spring.factories
└── sample-application/ # ライブラリを使用するアプリケーション
└── src/main/java/
└── com/example/app/
└── Application.java
ステップ1:ライブラリモジュールの作成
まず、ルートディレクトリでsettings.gradleを作成します:
GroovyrootProject.name = 'spring-boot-library-example' include 'authentication-library' include 'sample-application'
次に、ライブラリモジュールのbuild.gradleを設定します:
Groovyplugins { id 'java-library' id 'org.springframework.boot' version '3.2.0' id 'io.spring.dependency-management' version '1.1.4' } group = 'com.example' version = '1.0.0' java { sourceCompatibility = '17' } dependencyManagement { imports { mavenBom org.springframework.boot.gradle.plugin.SpringBootPlugin.BOM_COORDINATES } } dependencies { implementation 'org.springframework.boot:spring-boot-starter' implementation 'org.springframework.boot:spring-boot-autoconfigure' annotationProcessor 'org.springframework.boot:spring-boot-autoconfigure-processor' annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor' testImplementation 'org.springframework.boot:spring-boot-starter-test' } tasks.named('bootJar') { enabled = false } tasks.named('jar') { enabled = true archiveClassifier = '' }
bootJarを無効にしてjarを有効にしている点が重要です。これにより、実行可能なjarではなく、ライブラリとして利用できるjarが生成されます。
ステップ2:AutoConfigurationの実装
Spring Bootの自動設定機能を利用するため、AuthAutoConfigurationクラスを作成します:
Javapackage com.example.auth.config; import com.example.auth.service.AuthenticationService; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration @ConditionalOnClass(AuthenticationService.class) @EnableConfigurationProperties(AuthProperties.class) public class AuthAutoConfiguration { @Bean @ConditionalOnMissingBean public AuthenticationService authenticationService(AuthProperties properties) { return new AuthenticationService(properties); } } @ConfigurationProperties(prefix = "app.auth") class AuthProperties { private String secretKey = "default-secret"; private long tokenExpiration = 3600; // getters and setters public String getSecretKey() { return secretKey; } public void setSecretKey(String secretKey) { this.secretKey = secretKey; } public long getTokenExpiration() { return tokenExpiration; } public void setTokenExpiration(long tokenExpiration) { this.tokenExpiration = tokenExpiration; } }
@ConditionalOnMissingBeanアノテーションを使用することで、アプリケーション側で同じ型のBeanを定義している場合は、自動設定を上書きできます。
ステップ3:spring.factoriesの設定
Spring Boot 2.7以降はspring/org.springframework.boot.autoconfigure.AutoConfiguration.importsを使用しますが、互換性のためにここではspring.factoriesを使用します:
Properties# src/main/resources/META-INF/spring.factories org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ com.example.auth.config.AuthAutoConfiguration
これにより、Spring Bootアプリケーションが起動時に自動的にAuthAutoConfigurationを読み込みます。
ステップ4:カスタムアノテーションの作成
ライブラリを使用する側が、明示的に認証機能を有効化できるように、カスタムアノテーションを作成します:
Javapackage com.example.auth.annotation; import com.example.auth.config.AuthAutoConfiguration; import org.springframework.context.annotation.Import; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Import(AuthAutoConfiguration.class) public @interface EnableAuth { }
これにより、アプリケーション側で@EnableAuthを付けるだけで、認証機能が有効になります。
ステップ5:実装例 - 認証サービス
実際の認証処理を行うサービスクラスを実装します:
Javapackage com.example.auth.service; import com.example.auth.config.AuthProperties; import io.jsonwebtoken.Jwts; import io.jsonwebtoken.SignatureAlgorithm; import org.springframework.stereotype.Service; import java.util.Date; @Service public class AuthenticationService { private final AuthProperties properties; public AuthenticationService(AuthProperties properties) { this.properties = properties; } public String generateToken(String username) { Date now = new Date(); Date expiry = new Date(now.getTime() + properties.getTokenExpiration() * 1000); return Jwts.builder() .setSubject(username) .setIssuedAt(now) .setExpiration(expiry) .signWith(SignatureAlgorithm.HS512, properties.getSecretKey()) .compact(); } public boolean validateToken(String token) { try { Jwts.parser().setSigningKey(properties.getSecretKey()).parseClaimsJws(token); return true; } catch (Exception e) { return false; } } }
ステップ6:ライブラリの公開(ローカルリポジトリ)
開発中は、ローカルリポジトリに公開してテストすると便利です:
Groovy// authentication-library/build.gradleに追加 publishing { publications { maven(MavenPublication) { from components.java } } }
そして、以下のコマンドで公開:
Bash./gradlew publishToMavenLocal
ハマった点やエラー解決
問題1:AutoConfigurationが読み込まれない
症状:ライブラリを追加しても、Beanが作成されない
原因:spring.factoriesの場所が正しくない、または内容に誤りがある
解決策:src/main/resources/META-INF/spring.factoriesに正確に配置し、完全修飾クラス名を記載
問題2:Beanの競合が発生する
症状:アプリケーション側で同じ型のBeanを定義すると、エラーになる
原因:@ConditionalOnMissingBeanを付け忘れている
解決策:AutoConfigurationクラスの@Beanメソッドに@ConditionalOnMissingBeanを付与
問題3:設定プロパティが読み込まれない
症状:@ConfigurationPropertiesで定義したプロパティがデフォルト値のまま
原因:@EnableConfigurationPropertiesを付け忘れている
解決策:AutoConfigurationクラスに@EnableConfigurationPropertiesを追加
ライブラリを使用する側の実装
最後に、作成したライブラリを実際に使用するサンプルアプリケーションを実装します:
Javapackage com.example.app; import com.example.auth.annotation.EnableAuth; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication @EnableAuth // 認証ライブラリを有効化 public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }
application.propertiesで設定をカスタマイズ:
Properties# 認証ライブラリの設定 app.auth.secret-key=my-custom-secret-key app.auth.token-expiration=7200
そして、認証サービスを使用する例:
Javapackage com.example.app.controller; import com.example.auth.service.AuthenticationService; import org.springframework.web.bind.annotation.*; @RestController @RequestMapping("/api/auth") public class AuthController { private final AuthenticationService authService; public AuthController(AuthenticationService authService) { this.authService = authService; } @PostMapping("/login") public String login(@RequestParam String username) { return authService.generateToken(username); } @GetMapping("/validate") public boolean validate(@RequestParam String token) { return authService.validateToken(token); } }
まとめ
本記事では、Spring Bootアプリケーションをライブラリ化する方法について解説しました。マルチモジュール構成を採用することで、共通処理を効率的に管理・再利用できることがわかりました。
- Spring BootのAutoConfiguration機能を活用することで、ライブラリの利用者は最小限の設定で機能を利用可能
- @ConditionalOnMissingBeanなどの条件付きアノテーションを使用することで、柔軟な設定が可能
- カスタムアノテーション(@EnableAuth)を作成することで、明示的な機能の有効化が可能
- マルチモジュール構成により、ライブラリとアプリケーションを同一プロジェクト内で管理でき、開発効率が向上
この記事を通して、Spring Bootアプリケーションのライブラリ化が難しくないことが理解できたでしょう。ぜひ、プロジェクトで共通処理をライブラリ化して、開発効率を向上させてください。
今後は、Spring Boot 3.xでの新しい自動設定方法(spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports)や、Maven Centralへの公開方法についても記事にする予定です。
参考資料
- Spring Boot Reference Documentation - Creating Your Own Auto-configuration
- Spring Boot - Publishing Auto-configuration
- Building Java Libraries with Gradle
- Spring Boot - Multi-module Projects
