J2EE関連の最新トピックをわかりやすく解説
J2EE Watch [7]
DIとAOPがサーバ・コンポーネント技術を変える
■EJBオブジェクトから「DI+AOP」へ
こうしたEJBの数々の問題点を解決しようとしているのが、DIとAOPの技術です。DIとAOPを使えば、素のJavaクラス、すなわちPOJO(Plain Old Java Object)に対してさまざまな機能を織り込めます。そのため、前ページで述べたようなEJBオブジェクトに縛られたEJBコンポーネントは不要になります(図3)。
図3 サーバ・コンポーネント技術の進化(ORM:O/Rマッピング、TX:TXインターフェイス、MVC:MVCフレームワーク、RPC:Remote Procedure Call)。TXインターフェイスとは、アプリケーションプログラムがトランザクションを開始したり、終了したり、また、その状態について問い合わせたりするためのAPIを規定するもの |
例えばSeasarでは、コンポーネントのメソッド呼び出しを以下の3行で記述できます。
S2Container container
= S2ContainerFactory.create(PATH); |
まず1行目を見れば分かるように、Seasarでは開発者が書いたコードのスレッドでコンテナを用意するので、アプリケーション・サーバを起動しておく必要がありません。そのため、開発環境の構築やユニットテストの記述がとても簡単になります。コンテナの構成も一枚岩ではなく、必要な機能だけを選んでコンポーネントに付加できる構成になっています。
続いて3行目では、POJOであるオブジェクトfooのメソッドhelloを呼び出しています。このときSeasarのコンテナは、メソッド呼び出しをインターセプトし、トランザクション制御をはじめとするさまざまな機能を付加します。Seasarでは、このインターセプトを実装する手段として、バイトコード変換ライブラリJavassistによるAOP(Aspect
Oriented Programming)を利用しています。バイトコードを動的に修正することで、POJOのメソッドにフックを挿入し、EJBオブジェクトのような代理オブジェクトを使わずに各種コンテナ機能の織り込みを実現しています。
また例えば、コンポーネント内部でデータベース・アクセスを行う場合、従来のEJBコンポーネントでは、DataSourceをJNDI経由で明示的に取得する必要がありました。これに対しSeasarでは、次のように記述してDataSourceを取得できます。
private DataSource
dataSource_; |
この例では、「コンストラクタ・インジェクション」と呼ばれるDIにより、コンポーネント内で使用するDataSourceがコンテナによって後から注入されます。つまり、コンポーネントが必要とするさまざまなリソース(DBやメールサーバとのコネクションや、ほかのコンポーネントへの参照など)を「コンポーネントがコンテナから取得する」のではなく、「コンテナがコンポーネントに注入する」という形態です。そのため、コンテナのAPIに依存するコードをコンポーネント内部に記述する必要がありません。
■XMLかアノテーションか
もっとも、SeasarやSpringにおいても、DIやAOPの適用対象をコンテナに指示するための設定用XMLファイルが欠かせません。例えばコンストラクタ・インジェクションを用いるには、以下のような.diconファイルが必要となります。
<components> |
このように、外部XMLファイルでDIやAOPを設定するという構成には一長一短があります。「コードの外部依存性を減らせる」「コードがすっきりする」というメリットの一方で、「XMLファイルのメンテナンスが面倒」というデメリット(XML Hellとも呼ばれる)が生じます。そこでEJB 3.0仕様では、Java 5.0以降に導入された「アノテーション」により、DIやAOPの適用をコンテナに指示する手法が採用されています。
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW) |
この例では、「メソッドaddをインターセプトしてトランザクション制御を実施してほしい」という内容をEJBコンテナに指示しています。
一方Seasarでも、データベース・アクセス機能を提供するコンテナS2Daoにおいて、ORMにおけるテーブルカラムとJavaフィールドの対応付けを実現する独自のアノテーションを採用しています(以下参照)。
public static final
String employeeNo_COLUMN = "EMPNO"; |
これらはいずれも、外部のXMLを用意する必要をなくし、XML Hellの負担から開発者を解放しようという試みです。
■コンポーネントはDI+AOPで進化する
コンポーネント・モデルの利点として「コンポーネントの再利用性」がしばしば挙げられます。しかしビジネス・ロジックは「個々のプロジェクト要件に固有なロジック」であるため、そもそも再利用や流通には向かないという印象を筆者は受けます。むしろ、普遍的なロジックをできるだけコンテナ側に追い出し、コンポーネントに織り込むことでそれを再利用するのが、コンポーネント・モデルの真価と考えます。
DIとAOPをベースとしたコンテナが革新的な点は、POJOをそのままコンポーネントとして利用できることです。ですからDIコンテナは、軽量コンテナというより、むしろ「コンポーネントを軽量にするコンテナ」と表現した方が分かりやすいでしょう。従来のEJBコンポーネントのようにさまざまなルールやAPIに縛られた重量級のコンポーネントを捨て、開発やテストの容易なPOJOをそのまま軽量コンポーネントとして利用する。このDI+AOPのアプローチは、Webアプリケーション開発で必要とされる多種多様な機能をPOJOに織り込む手段として、優れた威力を発揮するはずです。
■関連記事
1/2 |
INDEX |
||
J2EE Watch [7] | ||
Page1 DIコンテナ=軽量コンテナ? なぜコンテナが必要か コンポーネント・モデルEJBの長所と短所 EJBの「重さ」の理由 「一枚岩」なEJB仕様 |
||
Page2 EJBオブジェクトから「DI+AOP」へ XMLかアノテーションか コンポーネントはDI+AOPで進化する |
Java Solution全記事一覧 |
- 実運用の障害対応時間比較に見る、ログ管理基盤の効果 (2017/5/9)
ログ基盤の構築方法や利用方法、実際の案件で使ったときの事例などを紹介する連載。今回は、実案件を事例とし、ログ管理基盤の有用性を、障害対応時間比較も交えて紹介 - Chatwork、LINE、Netflixが進めるリアクティブシステムとは何か (2017/4/27)
「リアクティブ」に関連する幾つかの用語について解説し、リアクティブシステムを実現するためのライブラリを紹介します - Fluentd+Elasticsearch+Kibanaで作るログ基盤の概要と構築方法 (2017/4/6)
ログ基盤を実現するFluentd+Elasticsearch+Kibanaについて、構築方法や利用方法、実際の案件で使ったときの事例などを紹介する連載。初回は、ログ基盤の構築、利用方法について - プログラミングとビルド、Androidアプリ開発、Javaの基礎知識 (2017/4/3)
初心者が、Java言語を使ったAndroidのスマホアプリ開発を通じてプログラミングとは何かを学ぶ連載。初回は、プログラミングとビルド、Androidアプリ開発、Javaに関する基礎知識を解説する。
|
|