サービス指向アーキテクチャー (SOA) およびサービス指向プログラミングは、ビジネス・ロジックをモジュラー・サービスとしてカプセル化するソフトウェア・エンジニアリングのスタイルを示す用語です。これらのサービスは、サービス・プロバイダーとサービス・コンシューマー間の関連性が緩やかな動的ランタイム環境をターゲットにしています。疎結合されたサービスは一般的にコンパイル時間の関連性を持たないため、実行時に動的に結び付けることができ、デプロイメント担当者は、必要に応じてデプロイメントに関する決定を柔軟に行うことができます。疎結合に加えて、サービス指向の環境には以下の共通の概念があります。
- 粗い細分度: サービスにおける細分度とは、サービスが公的に提供する機能の範囲を示します。きめの細かいサービスは、専門的な機能を定義するパブリック・インターフェースを提供します。きめの粗いサービスは、通常は特定のビジネス・ドメインに合わせたより一般的なレベルの機能を提供します。
- 場所の透過性: 場所の透過性は、クライアントがネットワーク上の場所を意識せずにサービスにアクセスできるという考え方を指します。
- プロトコルの独立性: プロトコルの独立性は、クライアントが通信/ネットワーク・プロトコルを意識せずにサービスにアクセスできるという考え方を指します。
これらの概念を念頭においてサービスを作成するのは、困難な作業です。POJOプログラミングは、この作業を単純化することを目指しています。
POJO は、特定の外部インターフェースまたはサード・パーティーの API に従う必要のないJava クラスです。この機能自体は、基本的に外部関連からコードを分離します。このように分離することの主な利点の1 つは、ソフトウェア開発者が、パーシスタンス、トランザクション・サポート、およびリモート処理などの補助的な作業を自由に行えるという点です。多数の手法によって、コンポーネント/クラスの分離がなくなり、次のようなPOJO プログラミングが簡単になります。
- アノテーションは、開発ツールがクラスまたはクラスの一部を「飾る」コードを生成するために使用するメタデータです。これは、リモート処理、パーシスタンス、およびフレームワーク・サポートなどの特定のタイプの機能をサポートするために行われます。
- 依存性注入は、オブジェクト作成および関連がコンポーネントから除去され、コンテナーまたはアセンブラー・コンポーネントによって実行されるプラグ可能なコンポーネントを構築するための手法です。
- リフレクションは、特定のクラスやインターフェースに関するメソッド、フィールド、およびコンストラクターなどの情報を実行時に発見することです。
それぞれの分離手法には、利点と欠点があります。この資料では、リフレクションおよびGeronimo の GBean 依存性注入を使用してコンポーネントの分離を可能にする、POJOプログラミングによる単純な SOA フレームワークを紹介します。
Geronimo は、Java Management Extensions (JMX) および GBean という管理対象コンポーネントの依存性注入フレームワークを使用する汎用カーネルの上に構築されています。事実上、Geronimoのすべて (アダプター、アプリケーション、コンテナーなど) が GBean であるか、GBeanに基づいているかのいずれかです。GBean は、数多くの類似点および基礎となるインフラストラクチャーをJMX および JMX Managed Bean (MBean) と共有しています。
GBean は、GBeanInfo という名前のクラスに従って属性および操作を公開する点など、数多くの類似点および関係をJMX MBean と共有する Geronimo の管理対象コンポーネントです。これは、JMXで同等の MBeanInfo クラスと著しく似ていているクラスです。Geronimo は、MX4Jライブラリー (リンクについては、この資料の最後にある参考文献を参照してください)を JMX の実装として使用します。
GBean は、状態と関連の依存関係を維持して、ライフ・サイクル・イベントを処理します。GBeanは、他の GBean の状況について興味のある対象として登録することができます。興味のあるGBean が開始されると、関心を持った GBean は、依存性注入によって興味のあるGBean への参照を受け取ります。GBean は、常に以下の 7 つのライフ・サイクル状態のいずれかになります。
- ロード済み
- アンロード済み
- 開始中
- 実行中
- 停止中
- 停止済み
- 失敗
リスト 1 は、1 つの属性 (メッセージ) を含む単純な GBean を示します。
リスト 1. 標準的な GBean
public class TestGBean
implements GBeanLifecycle
{
private static GBeanInfo GBEAN_INFO = null;
static
{
GBeanInfoBuilder infoFactory =
GBeanInfoBuilder.createStatic(TestGBean.class);
infoFactory.addAttribute("message", String.class, true);
infoFactory.addOperation("getMessage");
GBEAN_INFO = infoFactory.getBeanInfo();
}
private String message;
public String getMessage()
{
return message;
}
...
}
|
リスト 2 に示すコードを使用して、GBean を開始 (アクティブ化) および停止することができます。
リスト 2. 標準的な GBean を開始する
ObjectName testGBeanOName =
ObjectName.newInstance("jeffhanson.test:ID=test");
GBeanData gBeanData =
new GBeanData(testGBeanOName, TestBean.GBEAN_INFO);
gBeanData.setAttribute("message", "Hello world");
geronimoKernel.loadGBean(gBeanData,
Thread.currentThread().
getContextClassLoader());
geronimoKernel.startGBean(testGBeanOName);
...
geronimoKernel.stopGBean(testGBeanOName);
geronimoKernel.unloadGBean(testGBeanOName);
|
Geronimo カーネル全体で GBeans を広範囲に使用することができます。
Geronimo カーネルは GBeans のフレームワークです。このフレームワークを使用すると、状態、関係、およびイベント処理を管理するために、高度なシステムをGBean コンテナーおよび GBean コンポーネントのセットとしてモデル化および構築することができます。
プログラマチックな Geronimo カーネルの作成は、KernelFactory クラスを使用すると簡単に行うことができます。リスト3 は、TestGeronimo という名前の新しい Geronimo カーネルの作成方法を示しています。ここでは、カーネルのブート、ブート時間のロギング、およびサーブレットGBean のロードと開始を行います。
リスト 3. 単純な Geronimo カーネルを作成する
try
{
Kernel geronimoKernel =
BasicKernelFactory.newInstance().
createKernel("TestGeronimo");
geronimoKernel.boot();
log.debug("Geronimo BootTime: "
+ geronimoKernel.getBootTime());
// add the servlet GBean
ObjectName servletObjName =
new ObjectName("jeffhanson.test:ID=MyGBean");
GBeanData servletGBeanData = new GBeanData(servletObjName,
GBEAN_INFO);
ClassLoader classLoader = getClass().getClassLoader();
geronimoKernel.loadGBean(servletGBeanData, classLoader);
geronimoKernel.startGBean(servletObjName);
}
catch (Exception e)
{
log.error(e);
}
|
カーネルを作成して実行した後は、POJO サービスでメソッドを呼び出して、リスト4 に示すように、Geronimo カーネル・サーバーおよびリフレクション機能を使用する練習をします。
リスト 4. カーネルに登録されたサービスで呼び出しを行う
private static
Object invokePOJOService(ObjectName serviceObjName,
String operationName,
String[] params)
throws Exception
{
String[] paramTypes = null;
if (params != null && params.length > 0)
{
paramTypes = new String[params.length];
for (int i = 0; i < params.length; i++)
{
paramTypes[i] = params[i].getClass().getName();
}
}
Kernel geronimoKernel =
KernelManager.getInstance().getGeronimoKernel();
Object retVal =
geronimoKernel.invoke(serviceObjName,
operationName,
(Object[])params,
paramTypes);
return retVal;
} |
Geronimo におけるサービス指向 POJO の柔軟性のあるフレームワーク
この資料で言及されている SOA フレームワークでの POJO は、Geronimo カーネルのインスタンスを使用して、興味のあるクライアントが追加のインターフェースまたはAPI を必要とせずに POJO を照会して呼び出すことができる GBean として POJOを登録します。このフレームワークは、複数層のエンタープライズ・アプリケーション環境のビジネス層にあります。サービス・ロケーター・クラスは、サービスとして使用されるPOJO を見つけて、必要に応じて登録するために、カーネルと相互作用します。その後、POJOを呼び出すビジネス処理代理コンポーネントに POJO を戻します。図 1 は、フレームワークでのコンポーネントの関係を示しています。
図 1. SOA フレームワークでの POJO
フレームワークは、クライアントから HTTP 要求を受け取ってから、ディスパッチャー・コンポーネントにその要求をパススルーするように設計されています。このコンポーネントは、要求をビジネス処理代理コンポーネントに伝えてディスパッチします。次に、ビジネス処理代理コンポーネントは、サービス・ロケーターを活用して、特定の要求のサービスを見つけます。ビジネス処理代理コンポーネントはサービスを呼び出して、戻り値をモデル・オブジェクトとしてラップします。適切なビュー・コンポーネントがモデル・オブジェクトを処理して、フォーマット済みの応答としてクライアントに戻します。図2 のシーケンス図は、これらのステップを示します。
図 2. 一般的な HTTP 要求とサービス呼び出しの双方向シーケンス
図 3 のクラス図は、フレームワークのクラス間の関係を示しています。
図 3. フレームワーク・クラス間の関係
フレームワークは、エンタープライズ・アプリケーション・システムのビジネス層にあります。フレームワークは、HTTP要求を受け取って、その内容を処理するためにフレームワークにディスパッチする1 つのサーブレットを公開します。次のセクションでは、簡単なデプロイメント・プロセスについて説明します。
フレームワークおよびエンタープライズ・アプリケーションのクラスを .war ファイルにパッケージして、geronimo_home/deployディレクトリー内に入れることができます。このディレクトリーが存在しない場合は、作成してください。
Geronimo は、始動時にこの .war ファイルを自動的にデプロイします。デプロイ・ディレクトリーに入れられたアプリケーションはホットロードされ、変更を行った場合に、Geronimoが実行時にアプリケーションを再ロードすることができます。これによって、アプリケーションのデバッグに便利になります。
geronimo_home/bin ディレクトリーにある始動スクリプト (startup.bat またはstartup.sh) を使用して、Geronimo アプリケーション・サーバーを始動します。Geronimo始動スクリプトを呼び出すと、Geronimo コンソール・ウィンドウが表示されます。フレームワークおよびアプリケーションをデプロイした後、始動時のGeronimo のコンソール・ウィンドウには、リスト 5 に示すような行が含まれています。これらの行は、Webアプリケーションが正常に開始されたことを確認します。
リスト 5. Web アプリケーションが正常に開始されたことの確認
0 [main] DEBUG org.apache.geronimo.kernel.basic.BasicKernel -
Starting boot
422 [main] DEBUG org.apache.geronimo.gbean.runtime.GBeanInstanceState
- GBeanInstanceState for: :role=Kernel State changed from stopped to
starting
422 [main] DEBUG org.apache.geronimo.gbean.runtime.GBeanInstanceState
- GBeanInstanceState for: :role=Kernel State changed from starting to
running
422 [main] DEBUG org.apache.geronimo.kernel.basic.BasicKernel -
Booted
640 [main] DEBUG com.jeffhanson.apptier.FrontController - Geronimo
BootTime: Sat May 20 18:51:08 MDT 2006
656 [main] DEBUG org.apache.geronimo.gbean.runtime.GBeanInstanceState
- GBeanInstanceState for: jeffhanson.test:ID=FrontController State
changed from stopped to starting
656 [main] DEBUG org.apache.geronimo.gbean.runtime.GBeanInstanceState
- GBeanInstanceState for: jeffhanson.test:ID=FrontController State
changed from starting to running
|
次に、以下の URL を Web ブラウザー・ウィンドウに入力して、HelloWorld サービスでsetMessage 操作を実行します。
フレームワークが要求を処理すると、コンソール出力はリスト 6 に示すようになります。
リスト 6. setMessage 操作処理の出力
719 [main] DEBUG com.jeffhanson.businesstier.ServiceLocator -
Adding service [HelloWorld] to kernel...
719 [main] DEBUG com.jeffhanson.businesstier.ServiceLocator -
Loading GBean: jeffhanson.test:Name=HelloWorld,Type=GenericService
734 [main] DEBUG org.apache.geronimo.gbean.runtime.GBeanInstanceState
- GBeanInstanceState for:
jeffhanson.test:Name=HelloWorld,Type=GenericService State changed
from stopped to starting
734 [main] DEBUG org.apache.geronimo.gbean.runtime.GBeanInstanceState
- GBeanInstanceState for:
jeffhanson.test:Name=HelloWorld,Type=GenericService State changed
from starting to running
|
以下の URL を Web ブラウザー・ウィンドウに入力して、HelloWorld サービスでsayHello 操作を実行します。
フレームワークが要求を処理すると、コンソール出力はリスト 7 に示すようになります。
リスト 7. sayHello 操作処理の出力
750 [main] DEBUG com.jeffhanson.businesstier.ServiceLocator -
serviceObjName: jeffhanson.test:Name=HelloWorld,Type=GenericService
750 [main] DEBUG com.jeffhanson.businesstier.ServiceLocator -
Service [HelloWorld] already in kernel
1156 [main] DEBUG com.jeffhanson.businesstier.ServiceLocator -
serviceObjName: jeffhanson.test:Name=HelloWorld,Type=GenericService
1156 [main] INFO com.jeffhanson.businesstier.services.HelloWorld -
Hello everybody!
|
サーブレット・エンジンがサーブレットをシャットダウンして、サーブレットでdestroy メソッドを呼び出すと、サーブレットは Geronimo カーネルをシャットダウンします。サーブレット・エンジンがサーブレットをシャットダウンすると、コンソール出力はリスト8 に示すようになります。
リスト 8. サーブレットのシャットダウン後の出力
1156 [main] DEBUG org.apache.geronimo.kernel.basic.BasicKernel -
Starting kernel shutdown
1156 [main] DEBUG org.apache.geronimo.kernel.basic.BasicKernel -
Kernel shutdown complete
|
HelloWorld クラスは、setMessage メソッド、getMessage メソッド、および sayHelloWorldメッセージを持つ単純な POJO です。このクラスのインスタンスを Geronimo カーネルに登録したら、インスタンスを動的に呼び出して、依存性注入を使用して実行時に他のサービスおよびコンポーネントに関連付けることができます。リスト9 のコードは、単純な HelloWorld POJO クラスを示しています。
リスト 9. 単純な HelloWorld サービス
package com.jeffhanson.businesstier.services;
import org.apache.log4j.Logger;
public class HelloWorld
{
private static Logger log = Logger.getLogger(HelloWorld.class);
private String message = "Hello world";
public void setMessage(String message)
{
if (message == null || message.length() <= 0)
{
throw new RuntimeException("HelloWorld.setMessage "
+ "param is not set");
}
this.message = message;
}
public String getMessage()
{
return message;
}
public void sayHello()
{
log.info(message);
}
}
|
ビジネス・ドメインの変更およびイベントにタイミングよく対応できる柔軟かつ効果的なSOA を設計することは、複雑な作業です。しかし、適切に設計された POJO 層を中心に構築されたSOA は、この作業を単純化することができます。Geronimo プラットフォームは、POJOを使用して柔軟かつスケーラブルで保守可能な SOA を構築するために使用できるフレームワークおよびツールを提供します。
| 内容 | ファイル名 | サイズ | ダウンロード形式 |
|---|---|---|---|
| SOA with POJOs framework | GeronimoSOAwithPOJOs.zip | 14KB | HTTP |
学ぶために
-
POJO プログラミングの基礎の明確な定義および説明をお読みください。
-
SOA および依存性注入に関するこれらの資料を使用してください。
-
MX4J に関する情報を見つけてください。
-
JMX に関する見識を深めてください。
-
Java リフレクションに関する資料を入手してください。
- developerWorks の Apache Geronimo プロジェクト・ゾーンに用意されている、今日から Geronimo での開発を開始するための記事、チュートリアル、その他の資料をご覧ください。
- developerWorks の Get started now with Apache Geronimo セクションには、初心者から上級者まで利用できる役に立つ資料が用意されています。
-
IBM® Support for Apache Geronimoo が提供するサービスについて調べてください。このサービスを利用すると、世界クラスのIBM サポートを受けながら Geronimo アプリケーションを開発することができます。
-
developerWorks の Open source ゾーンをご覧ください。オープン・ソース技術を使用した開発や、IBM 製品でオープン・ソース技術を使用するためのハウ・ツー情報やツール、プロジェクトの更新情報など、豊富な情報が用意されています。
- developerWorks の Open source ゾーンに用意されている Apache に関するすべての記事や無料の Apache チュートリアルをご覧ください。
- この記事で紹介した技術やその他の技術に関する書籍については、Safari bookstore を参照してください。
製品や技術を入手するために
-
Apache Geronimo バージョン 1.0 をダウンロードしてください。
- ダウンロードまたは DVD で入手可能な IBM トライアル・ソフトウェアを次のオープン・ソース開発プロジェクトに取り入れてください。
-
IBM WebSphere® Application Server Community Edition V1.0 のフリー・コピーをダウンロードしてください。これは、Apache Geronimo オープン・ソース・テクノロジーの上に構築された単純なJ2EE アプリケーションで、開発およびデプロイメントの作業を促進するために設計されています。
議論するために
-
Apache Geronimo blog に参加して、Geronimo 開発の最新情報を入手してください。
-
developerWorks blogs に参加して、developerWorks コミュニティーに加わってください。

Jeff Hansonはソフトウェア業界で20年以上の経験を持っており、シニア・エンジニアとしてOpenDocのMicrosoft® Windows®への移植プロジェクトや、中心アーキテクトとしてNovellのRoute 66フレームワークなどに従事してきました。現在はeReinsure.com, Inc.の中心アーキテクトであり、Java EEベースの再保険システム用のWebサービス・フレームワークやプラットフォームの構築を行っています。彼は数多くの記事や本を執筆しており、その一部には『.NET versus J2EE Web Services』や『A Comparison of Approaches, Pro JMX』、『Java Management Extensions, and Web Services Business Strategies and Architectures』などがあります。