AJDTを使って規約違反のコードを検出する方法
AspectJというと、メソッドなどに処理を織り込むAOPのイメージが強いと思いますが、AJDTというeclipseのプラグインを使うと強力なコード検証ツールとして利用できることは意外と知られていないようです。(AJDTはSpring Tool Suiteには最初から内蔵されています。)
実際、
- コントローラークラスのメソッド内でフィールドの設定を行う
- サービス層を経由せずに直接DAOを呼び出している
- 日付オブジェクトを直接newしている*1
などの箇所をコンパイル時に検証して、警告やエラーとして検出できます。
たとえば、Spring MVCのコントローラークラスのメソッド内でフィールドの設定を行っている箇所を警告として検出するには以下のようなアスペクトを書くだけです。
package sample.mvc; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; public aspect CondingRules { pointcut setFieldInHandlerMethod() : withincode(@RequestMapping * (@Controller *).*(..)) && set(* *); declare warning : setFieldInHandlerMethod() : "コントローラークラスのリクエストハンドラーメソッド中でフィールドに設定しています。"; }
こうすると、
のように警告してくれます。FindBugsなどの静的解析ツールと併用することで、かなり強力な規約チェックが実施できます。
(補足)
構文的には
declare warning : ポイントカット : 警告メッセージ; declare error : ポイントカット : エラーメッセージ;
のようにアスペクト中で指定するだけなのですが、一番難しいのは警告やエラー対象の場所指定をするポイントカット式の書き方の部分ですね。この部分は例を参考にしながら書き方を覚えるしかありません。
AspectJ/ポイントカット - アスペクト指向なWiki
http://www.limy.org/program/aspect/
あと、制約としてポイントカットの部分にcflowとかcflowbelowなど動的なものは使えません。こうした動的なポイントカットによるチェックが必要な場合は、例外を発生させるアドバイスを適用して、自動化テストなどでアプリを動作させて検証させるしかありません。
*1:多くの場合、システム試験時に時刻を容易に変更可能なようにサービスモジュール経由で日付を生成することが普通