Java 9のモジュールでServiceLoaderクラスを使うべきタイミングとは?
Java 9のモジュールとServiceLoaderクラス
Javaには、java.utilパッケージにServiceLoaderクラスが用意されています。このクラスは、クラスパスを検索することで、実行時にサービスプロバイダを自動的に検出してロードする役割を担います。
ServiceLoaderが特に威力を発揮するのは、次のようなケースです。
- 疎結合な設計:インターフェース(サービス)とその実装を分離し、呼び出し側が具象クラスを直接参照しなくて済むようにしたい場合
- プラグイン機構:後から追加・差し替え可能な拡張ポイントをアプリケーションに持たせたい場合
- モジュールシステムとの連携:Java 9以降のモジュールで「uses / provides ... with」によって宣言されたサービス実装を動的に取得したい場合
ここでは、モジュール内で定義されたサービスプロバイダを扱うサンプルアプリケーションを通じて、サービスを含むモジュールの宣言方法と、その仕組みがどのように動作するのかを見ていきましょう。
サンプル:LoggerFinderサービスを利用するモジュール
例として、「test.app」というモジュールを考えます。このモジュールでは、LoggerFinderサービスを介して、System.getLogger()ファクトリメソッドから取得できるLoggerを使用します。
まず、サービスを「使用する」側のモジュール宣言です。usesディレクティブで、利用するサービスのインターフェースを指定します。
module com.tutorialspoint.test.app {
requires java.logging;
exports com.tutorialspoint.platformlogging.app;
uses java.lang.System.LoggerFinder;
}MainAppクラス
続いて、実際にLoggerを取得して利用するMainAppクラスのコードです。
package com.tutorialspoint.platformlogging.app;
public class MainApp {
private static Logger LOGGER = System.getLogger();
public static void main(String args[]) {
LOGGER.log();
}
}サービス実装を提供するモジュール
次に、「test.logging」モジュール内でのLoggerFinderの実装例です。LoggerFinderを継承し、getLogger()メソッドをオーバーライドします。
package com.tutorialspoint.platformlogging.logger;
public class MyLoggerFinder extends LoggerFinder {
@Override
public Logger getLogger(String name, Module module) {
// 名前やモジュールに応じたLoggerを返す
}
}そして、「test.logging」モジュールの宣言では、「provides ... with」句を使って、LoggerFinderサービスの実装クラスを提供することを宣言します。
module com.tutorialspoint.test.logging {
provides java.lang.System.LoggerFinder
with com.tutorialspoint.platformlogging.logger.MyLoggerFinder;
}まとめ
このように、Java 9のモジュールシステムでは、usesでサービスの利用を宣言し、provides ... withで実装の提供を宣言することで、ServiceLoaderを通じた疎結合なサービス検出が可能になります。実装クラスへの直接依存を避けたい場合や、実行時に柔軟に実装を切り替えたい場合に、ServiceLoaderとモジュールシステムの組み合わせは非常に有効です。
-
Javaのpack()メソッドとは?使い方とsetSize()との違いを解説
pack()メソッドは、JavaのWindowクラスで定義されているメソッドで、フレーム内のすべてのコンポーネントがそれぞれの推奨サイズ(preferred size)以上で表示されるように、ウィンドウのサイズを自動的に調整します。 代替手段として、setSize()メソッドやsetBounds()メソッドを呼び出して、フレームのサイズを明示的に指定する方法もあります。しかし一般的には、pack()メソッドを使用する方がsetSize()よりも推奨されています。その理由は、pack()がフレームのサイズ決定をレイアウトマネージャーに委ねることができ、レイアウトマネージャーはプラットフォーム間の
-
【Java入門】SimpleDateFormatクラスでDate型を任意の形式の文字列に変換する方法
JavaのSimpleDateFormatクラスは、Dateオブジェクトを指定したパターンの文字列(String)に変換したり、その逆に文字列からDateへ変換したりするために使用されるクラスです。日付の表示形式を自由にカスタマイズできるため、実務でも非常によく利用されます。SimpleDateFormatの基本的な使い方以下のサンプルコードでは、今日の日付を取得し、「yyyy-MM-dd-hh.mm.ss」というパターンで文字列に変換してコンソールに出力しています。サンプルコードimport java.util.Date; import java.text.SimpleDateFormat;