nimbus (1.2.4) | 2018-01-25 20:02 |
nimbus-sample (1.2.4) | 2018-01-26 17:06 |
J2EEを使ってアプリケーション開発を行う場合、EJBを使用するが、EJB2.0には不便な点があります。
1つは、トランザクション制御が宣言的である事です。もう1つは、EJBの開発及び配置が複雑な事です。
EJBは、トランザクション制御が宣言的であるため、ある特定の処理を行うEJBを開発して、その処理を異なるトランザクション境界で呼び出そうとする場合、同じEJBを違うトランザクション宣言で2つ配置する必要があります。
呼び出される側がトランザクションを宣言するのではなく、呼び出す側がトランザクションを宣言したくなるのです。
これを実現するのがIOCです。IOCの言葉の由来は、Inversion Of Controlつまり"制御の反転"です。
EJBには、分散環境での透過的な呼び出しや、JMSとの組み合わせによる非同期呼び出し、トランザクション制御、流量制御などアプリケーションにとって便利な機能が色々とあります。
しかしながら、その利点を享受するために、複雑なEJB開発及び配置方法を理解する必要があります。
これらの利点を享受しつつ、アプリケーションを簡単に作りたいのです。そのためには、EJBをアプリケーションが直接実装せず、フレームワークとして組み上げられたEJBをアプリケーションが利用すればよいのです。
IOCは、EJBをフレームワークとして配置し、その先で業務フローを動かす事で、アプリケーションはEJBを意識せずに、EJBの機能を利用できるフレームワークです。
IOCでは、4つのEJBを配置します。
まず、呼び出し口として、Facade Stateless Session BeanとFacade Message Driven Beanです。それぞれ、同期呼び出しと非同期呼び出しの呼び出し口となります。
次が、Unit of Work Stateless Session Beanです。このEJBは、トランザクション宣言をRequired Newに宣言する事でトランザクション境界となります。
最後が、Command Stateless Session Beanです。このEJBは、末端で業務フローを呼び出します。
これらのEJBをどのような順番で呼び出し、業務フローを実行するのかを、FacadeValue、UnitOfWork、Commandを組み合わせる事で、制御してトランザクション境界を呼び出し側が決定します。
また、IOC自体は、EJBでありEJBの呼び出しが煩雑であるため、その呼び出しを隠ぺいするFacadeCallerを提供します。
IOCの機能性は、Nimbusの開発過程において業務フローの機能として取り込まれ、Nimbus2では機能自体が廃止されているため、非推奨です。
関連するパッケージは、以下です。
アプリケーション向けインタフェースFacadeCallerを使った簡単なアプリケーションのサンプルを示します。
- import java.util.*;
- import jp.ossc.nimbus.core.ServiceManagerFactory;
- import jp.ossc.nimbus.ioc.FacadeValueAccess;
- import jp.ossc.nimbus.ioc.FacadeValue;
- import jp.ossc.nimbus.ioc.UnitOfWork;
- import jp.ossc.nimbus.ioc.Command;
- import jp.ossc.nimbus.service.ioccall.FacadeCaller;
- // サービスを取得する
- FacadeCaller caller = (FacadeCaller)ServiceManagerFactory.getServiceObject("FacadeCaller");
- // トランザクション境界となるUnitOfWorkを生成する
- UnitOfWork uow = FacadeValueAccess.createUnitOfWork();
- // コマンドを生成する
- Command command1 = FacadeValueAccess.createCommand("Flow1", null);
- // コマンドをUnitOfWorkに追加する
- uow.addCommand(command1);
- // コマンドを生成する
- Command command2 = FacadeValueAccess.createCommand("Flow2", null);
- // コマンドをUnitOfWorkに追加する
- uow.addCommand(command2);
- // コマンドを生成する
- Command command3 = FacadeValueAccess.createCommand("Flow3", null);
- // FacadeValueを生成する
- FacadeValue fv = FacadeValueAccess.createCommandsValue();
- // UnitOfWorkをFacadeValueに追加する
- fv.addUnitOfWork(uow);
- // コマンドをUnitOfWorkに追加する
- fv.addCommand(command3);
- // 同期実行する
- FacadeValue result = caller.syncFacadeCall(fv);
- // 実行結果が成功しているか確認する
- if(result.getStatus() != CommandBase.C_STATUS_COMPLETE){
- System.out.println("実行失敗:" + result.getStatus());
- // 例外が発生しているか確認する
- if(result.getExceptionCount() != 0){
- Throwable[] exceptions = result.getExceptions();
- for(int i = 0; i < exceptions.length; i++){
- exceptions[i].printStackTrace();
- }
- }
- }
実装サービスの一覧は以下のとおりです。
実装サービス | 実装概要 |
jp.ossc.nimbus.service.ioccall.DefaultFacadeCallService | デフォルト実装 |
サンプルは、以下。