BT

最新技術を追い求めるデベロッパのための情報コミュニティ

寄稿

Topics

地域を選ぶ

InfoQ ホームページ ニュース John Heintz氏による、Javaアノテーションのベストプラクティス

John Heintz氏による、Javaアノテーションのベストプラクティス

Java アプリケーションに再利用可能な振る舞いを追加する方法として、カスタムアノテーションはとても効果の高い方法である。しかし、開発者がアプリケーション内のどの部分でアノテーションを利用するのがいいかというのを理解するためには、カスタムアノテーションのためのガイドラインやベストプラクティスが必要となる。これらがあると、通常のコードや、インタフェースの利用などといった他の手法よりも、カスタムアノテーションを使用する効果が高い領域が分かるようになる。New Aspects of Software社のJohn Heintz氏はNo Fluff Just Stuff(NFJS(リンク) )コミュニティが主催する、Central Ohio Software Symposium(COSS(リンク)) で、Java Custom Annotationを使用して振る舞いを追加するための特別な設計テクニックに関するプレゼンテーション(リンク)を行った。

このプレゼンテーションの中で、John氏はバイトコードの中を探索してメタプログラミングを行うテクニックについて説明し、今までどのようにJavaアプリケーション内でメタデータがどのように使用されてきたか、という歴史(リンク)、XML, そしてアノテーション(リンク)の振り返りを行った。彼は、メタデータの仕組みをJava言語に対して提供する JSR-175(リンク)に触れた。Java 5(リンク)でアノテーションは言語に追加されている。

アノテーションの定義は、インタフェースの定義と似ている。アノテーションは@Interfaceタイプを使用して宣言されている。アノテーションはパッケージレベル、あるいはクラスメンバー(フィールド、メソッド、コンストラクタ)、メソッド引数にも使用することができる。

保持(Retention)ポリシーはアノテーションの実装についての重要な部分である。保持ポリシーは、そのデータをメモリ内でどれだけの期間保持するのか、という設定をするのに使用される。保持のポリシーには以下の3種類が存在する。

  • Runtime (常にデータが保持され、リフレクションを使用してアクセスすることができる)
  • Class (データはバイトコード中に保持されるが、実行時にアクセスすることはできない)
  • Sourceレベル (コンパイラによって切り捨てられる)

EJB3(リンク), Hibernate(リンク), Spring(リンク), Seam(リンク), Struts 2(リンク), RIFE(リンク), JAX-WS(リンク)などの、いくつかの有名なフレームワークの現在のバージョンはアノテーションをサポートしている。John氏は3種類のアノテーション実行の種類について解説を行った。

ジェネレータ:
このアノテーションは、ソースコードを読み、新しいソースコードを生成したり、既存のソースコードに変更を加えたりする。コード以外にもXMLやドキュメントを生成したり変更することもある。ジェネレータはコンテナや、それ以外の(フレームワークなどの上の)ルール化されたプログラムと一緒に良く使用される。このアノテーションはすべての保持ポリシーで使用することができる。

ジェネレータを使用した例としては Annotation Processing Tool(APT(リンク))やプロセッサ, XDoclet(リンク), Spoon(Javaの拡張コンパイラ)、APT-Jelly(リンク)(テンプレートライブラリ)がある。APTを使ってソースコードの編集をすることはできないが、これはそれ以外の副産物(WSDL, ドキュメント)を作成するのに便利である。

バイトコード変換:
これらのアノテーションは、アノテーションのついたクラスファイルを調べ、既存のクラスに変更を加えたり、クラスを生成したりする。これらはXMLの設定ファイルなど、クラス以外のものを生成することも可能である。バイトコード変換はオフライン(コンパイル時)と、ロード時、JVMTI API(リンク)を使用しての実行時の動的動作のそれぞれで実行することができる。このアノテーションは、ClassおよびRuntimeの保持ポリシーを使用して実現される。

バイトコード変換の例としてはAspectJ(リンク), Spring, Hibenate, CGLib(リンク), Javassist(リンク), ASM(リンク), BCEL(リンク)などがある。

実行時のリフレクション:
このアノテーションは、リフレクションAPI(リンク)を使用して、実行時にプログラム的にオブジェクトを調査するのに使用される。このアノテーションはコンテナや、それ以外の(フレームワークなどの上の)ルール化されたプログラムと一緒に良く使用される。また、保持ポリシーにはRuntimeを使用する。

実行時のリフレクションの例としてはJava 5+ reflectionや、Commons Attributes(リンク)といったライブラリがある。 JUnit(リンク)やTestNG(リンク)のようなテスティングフレームワークも実行時リフレクションを使用してアノテーションを処理している。

John氏はサンプルのJavaアプリケーションを使用して、APTやJavassist, AspectJ, Reflection(Java動的プロキシを使用している)のように、さまざまな設計テクニックを使用したカスタムアノテーションの実装についてのデモンストレーションを行った。それ以外にも、振る舞いをクラスやフィール、メソッドに追加する方法や、アスペクトとアノテーションを付加したタイプ、メソッドとの関係についての説明も行った。

John 氏はアスペクト処理のメリットについて説明を行った。これには、ツールのサポートが強化されることによる実装容易性の向上、(リフレクションやAPT以外で)影響のあるメソッド呼び出しやフィールドアクセスに対して特別な意味を与えること、さまざまなライブラリのアノテーションの統合、ドメイン志向の抽象化のサポートが含まれる。彼は、インタフェースとして実装できるJavaのコードは、アノテーションを使用した設計にしていくべきであると提案した。彼は HAJO(Heavily Annotated Java Object)よりもPOJO(Plain Old Java Object)の方が優れていると決めつけて、カスタムアノテーションをまったく使用しない開発者に対して警告を行った。彼のプレゼンテーション中で触れられている、その他のベストプラクティスには以下のようなものがあった。

  • アノテーションは抽象化できるなるべく大きなレベルの要素について付加すべきである。(例: メソッドよりもクラス)
  • 気の利いたデフォルト動作を設定すべきである。ルールに対して例外がある場合のみ記述するようにする。パラメータは必要最低限にする。
  • "Convention over Configuration(設定に勝る規約)"の補完のためにアノテーションの実装を行う。(例: Spring)
  • 既存のフレームワークの強化のためにリフレクションを使用する。(例: テスト)
  • 新しいオブジェクトの生成や、低レベルでバイトコードのチューニングを行う場合には、JavassistやCGLIBフレームワークを使用する。
  • コード以外の副産物を生成する場合にはAPTを使用する。

原文はこちらです:http://www.infoq.com/news/2008/08/nfjs2008-annotations

この記事に星をつける

おすすめ度
スタイル

BT