第1回「アスペクト指向の基礎とさまざまな実装」ではアスペクト指向とAOPの概要について解説したが、今回からはAOPのさまざまな実装を取り上げていきたい。まず始めに紹介するのはAspectJである。
AspectJはもともとXeroxのPalo Alto 研究所で開発されていたAOPの実装であり、現在はeclipse.orgの開発プロジェクトに受け継がれて活発に開発活動が続けられている。AspectJはJava言語を拡張したような言語仕様とライブラリ、コンパイラなどのツール群から構成されている。
ではここから実際にAspectJをインストールし、基本的な実装方法をみながら、アスペクト指向の特徴(例えば「ロギング」)や振る舞いを検証していこう。
AspectJのツール群にはコンパイラが含まれているが、実行環境は含まれていない。なぜなら、AspectJのコンパイラによって生成されたクラスファイルは通常のJavaの実行環境で動かすことができるからである。またAspectJはeclipseをはじめとしたさまざまなIDEツールをサポートしており、AOPによる開発の生産性を高めることが可能だ。この記事の最後でもAJDTと呼ばれるeclipse用プラグインの導入を紹介する。
先述したように、AspectJは現在eclipse.orgの下で「aspectj project」として開発されている(technology projectのサブプロジェクト)。
まずはAspectJをダウンロードしてインストールするところから始めよう(この原稿執筆時の最新リリースは「AspectJ 1.2.1 rc1」であり、本稿でもそのバージョンを使って説明をしていく)。
「aspectj project」のページより、左側にあるメニューからDownloadsのリンクをクリックする。そして「Latest Stable Release」である「aspectj-1.2.1rc1.jar」を任意のディレクトリにダウンロードする。このJARファイルはインストーラとなっているため、Windowsでjavaw.exeに関連付けされていればJARファイルをダブルクリックするだけでインストールが開始される。コマンドプロンプトから起動するのであれば、次のようにjavaコマンドを実行すればよい。
java -jar aspectj-1.2.1rc1.jar |
JARファイルを実行するとAspectJのインストーラが起動するので、以下のようにインストールウィザードを進めていく。
ここまででAspectJのインストールは完了である。デフォルトではC:\に「aspectj1.2」というディレクトリが作成され、その配下にライブラリやツールなどの構成ファイルが展開される。
C:\aspectj1.2 |
コンパイラなどのツールはbinディレクトリに格納されているため、インストールが完了後に「bin」ディレクトリを環境変数PATHに追加しておこう。
新しいテクノロジを試してみる際には、まずはできるだけシンプルで簡単なものを題材にすることが望ましい。プログラミングの世界では取っ掛かりのプログラムとして「HelloWorld」が有名であるが、ここでもAspectJ版HelloWorldプログラミングを紹介しよう。
次のリスト1に示すプログラム「Messenger」はごく普通のJavaのプログラムである。このクラスにはprintMessage()というメソッドが1つだけ定義されている。このメソッドは引数に受け取った文字列のメッセージを画面に表示するだけの単純なstaticメソッドである。
|
リスト1 Messengerクラス |
この「Messenger」クラスを呼び出すテスト用クラスは次のリスト2のようになる。
|
リスト2 Testerクラス |
プログラムを見れば分かるように、Testerクラスを実行すれば単純に「AspectJ」という文字列が画面に表示されるだけである。普通にjavacを使ってコンパイルし、実行すれば次のように「AspectJ」と表示される。
|
では、この単純なアプリケーションに「アスペクト」を適用してみよう。AspectJではアスペクトを適用することを「ウィーブ(Weave)」あるいは「ウィービング(Weaving)」と呼んでいる。Weaveとは「織り込む」という意味であり、「Cross-Cutting Concern(横断的関心事)」であるアスペクトを「Core Concern(中心的関心事)」に、文字通り織り込むことを意味する。
このサンプルプログラムでウィーブするのは、メッセージの前に「Hello,」という文字列を挿入する「アスペクト」である。具体的にはMessengerクラスのprintMessage()メソッドが出力する文字列の先頭に「Hello, 」を追加するというものである。
では実際に「アスペクト」を作成してみよう(リスト3)。AspectJの言語仕様ではアスペクトの定義にキーワード「aspect」を用いる。ファイルの拡張子は通常のJavaプログラム同様に「.java」で構わない。このアスペクトには「GreetingAspect」と名付けることにしよう。
|
リスト3 GreetingAspect |
このアスペクトコードは通常のJavaプログラムのようにも見えるが、「aspect」や「pointcut」といった、Java言語には定義されていないキーワードや構文を使っていることが分かる。これらはAspectJの言語仕様で定義されているキーワードである。このように、AspectJによるAOPではAspectJの言語仕様に従ったアスペクトを記述することになる。しかしAspectJの言語仕様はJava言語を拡張するような形で定義されているため、Javaのプログラマであればそれほど違和感なくAspectJプログラムを書くことができるだろう。
アスペクトが作成できたらコンパイルしよう。AspectJではバイトコードに対してアスペクトをウィービングするため、通常のJavaコンパイラではなく専用のコンパイラが必要となる。AspectJには「ajc」と呼ばれるコンパイラが付属しており、このajcによってコンパイルされたクラスファイルが「アスペクトウィービング済み」のクラスファイルとなる。
|
ajcを使ったコンパイル |
コンパイルの結果、生成されるのは通常のクラスファイルである。次のように普通にjavaコマンドを実行すればよい。「Hello, AspectJ」と表示されるはずである。
|
ここで実行結果に注目してほしい。TesterクラスやMessengerクラスのコードは一切変更していないにもかかわらず(つまりHello,という文字列の追加は行っていない)、実行結果には「Hello,」の文字が先頭に記述されている。GreetingAspectによって「Hello,」を追加する処理がウィービングされていることが分かる。
もしAspectJを使わずに同じような結果を望むのであれば、つまり「Hello,」という文字列を先頭に加えるようにprintMessage()メソッドの振る舞いを変更するのであれば、次のようなコード修正が必要である(赤字部分)。
|
リスト4 Messengerクラス(AspectJを使わない例) |
しかし、AspectJを使うことで、Messengerクラスには一切手を入れることなく機能追加を実現できている。このように元のソースコードにできるだけ手を入れたくない状態で機能追加できるということはAOPの大きな特徴の1つである。
Copyright © ITmedia, Inc. All Rights Reserved.