ソース表示: Function/ioc/IOC #96856

= ![応用機能]IOC
J2EEを使ってアプリケーション開発を行う場合、EJBを使用するが、EJB2.0には不便な点があります。[[BR]]
1つは、トランザクション制御が宣言的である事です。もう1つは、EJBの開発及び配置が複雑な事です。

EJBは、トランザクション制御が宣言的であるため、ある特定の処理を行うEJBを開発して、その処理を異なるトランザクション境界で呼び出そうとする場合、同じEJBを違うトランザクション宣言で2つ配置する必要があります。[[BR]]
呼び出される側がトランザクションを宣言するのではなく、呼び出す側がトランザクションを宣言したくなるのです。[[BR]]
これを実現するのがIOCです。IOCの言葉の由来は、'''__I__'''nversion '''__O__'''f '''__C__'''ontrolつまり"制御の反転"です。

EJBには、分散環境での透過的な呼び出しや、JMSとの組み合わせによる非同期呼び出し、トランザクション制御、流量制御などアプリケーションにとって便利な機能が色々とあります。[[BR]]
しかしながら、その利点を享受するために、複雑なEJB開発及び配置方法を理解する必要があります。[[BR]]
これらの利点を享受しつつ、アプリケーションを簡単に作りたいのです。そのためには、EJBをアプリケーションが直接実装せず、フレームワークとして組み上げられたEJBをアプリケーションが利用すればよいのです。[[BR]]

IOCは、EJBをフレームワークとして配置し、その先で[wiki:Function/service/beancontrol 業務フロー]を動かす事で、アプリケーションはEJBを意識せずに、EJBの機能を利用できるフレームワークです。[[BR]]
IOCでは、4つのEJBを配置します。[[BR]]
まず、呼び出し口として、Facade Stateless Session BeanとFacade Message Driven Beanです。それぞれ、同期呼び出しと非同期呼び出しの呼び出し口となります。[[BR]]
次が、Unit of Work Stateless Session Beanです。このEJBは、トランザクション宣言をRequired Newに宣言する事でトランザクション境界となります。[[BR]]
最後が、Command Stateless Session Beanです。このEJBは、末端で業務フローを呼び出します。[[BR]]

これらのEJBをどのような順番で呼び出し、業務フローを実行するのかを、[http://nimbus.sourceforge.jp/reports/apidocs/jp/ossc/nimbus/service/ioc/FacadeValue.html FacadeValue]、[http://nimbus.sourceforge.jp/reports/apidocs/jp/ossc/nimbus/service/ioc/UnitOfWork.html UnitOfWork]、[http://nimbus.sourceforge.jp/reports/apidocs/jp/ossc/nimbus/service/ioc/Command.html Command]を組み合わせる事で、制御してトランザクション境界を呼び出し側が決定します。[[BR]]
また、IOC自体は、EJBでありEJBの呼び出しが煩雑であるため、その呼び出しを隠ぺいするのが、[wiki:#header_FacadeCaller FacadeCaller]です。

IOCの機能性は、Nimbusの開発過程において[wiki:Function/service/beancontrol 業務フロー]の機能として取り込まれ、Nimbus2では機能自体が廃止されているため、非推奨です。[[BR]]

関連するパッケージは、以下です。
 * [http://nimbus.sourceforge.jp/reports/apidocs/jp/ossc/nimbus/service/ioc/package-summary.html jp.ossc.nimbus.service.ioc]
 * [http://nimbus.sourceforge.jp/reports/apidocs/jp/ossc/nimbus/service/ioc/ejb/package-summary.html jp.ossc.nimbus.service.ioc.ejb]
 * [http://nimbus.sourceforge.jp/reports/apidocs/jp/ossc/nimbus/service/ioc/ejb/command/package-summary.html jp.ossc.nimbus.service.ioc.ejb.command]
 * [http://nimbus.sourceforge.jp/reports/apidocs/jp/ossc/nimbus/service/ioc/ejb/facade/package-summary.html jp.ossc.nimbus.service.ioc.ejb.facade]
 * [http://nimbus.sourceforge.jp/reports/apidocs/jp/ossc/nimbus/service/ioc/ejb/unitofwork/package-summary.html jp.ossc.nimbus.service.ioc.ejb.unitofwork]
 * [http://nimbus.sourceforge.jp/reports/apidocs/jp/ossc/nimbus/service/ioccall/package-summary.html jp.ossc.nimbus.service.ioccall]
 * [http://nimbus.sourceforge.jp/reports/apidocs/jp/ossc/nimbus/service/ioccall/interceptor/package-summary.html jp.ossc.nimbus.service.ioccall.interceptor]

== アプリケーション向けインタフェース FacadeCaller #header_FacadeCaller
アプリケーション向けインタフェース[http://nimbus.sourceforge.jp/reports/apidocs/jp/ossc/nimbus/service/ioccall/FacadeCaller.html FacadeCaller]を使った簡単なアプリケーションのサンプルを示します。

{{{ code java

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();
        }
    }
}
}}}

実装サービスの一覧は以下のとおりです。
||実装サービス||実装概要||
||[wiki:Function/service/ioccall/DefaultFacadeCallService jp.ossc.nimbus.service.ioccall.DefaultFacadeCallService]||デフォルト実装||

サンプルは、以下。
 * [cvs://nimbus/sample/example/ioc/ex1 サンプル1:Nimbus IOCを使ってみよう。]