AccessAllow/Denyアノテーション
というものを作ってみた。
クラスやメソッドに
@AccessDeny("")
@AccessAllow("hoge.foo")
public class Hoge() {
//...
}
というアノテーションを書くと、public/protected/(無印)/privateよりももっと細かいレベルでアクセス制御ができる、というもの。
ある程度は既存アクセス記述子とパッケージ分けを駆使して実現すべきであるが(設計の観点からもこれは重要だし軽視してはいない)、複数パッケージから使われるためpublicにせざるを得ないクラス/メソッドであっても、あらかじめ利用クライアントが所属するパッケージは特定されていて、それ以外には使ってほしくない!という場合が少なからずある。
いや、それは単に設計が悪いのかもしれないけど。
とりあえず、そんなときにこれが使えないかと。
アノテーションの動作イメージは、上記の例だと、まずHogeクラスへのアクセスを
@AccessDeny("")
で全禁止にして、それから
@AccessAllow("hoge.foo")
で、hoge.fooパッケージのクラスに対してアクセスを許可している。
このアノテーションによるアクセス制御を有効にするには、javaagentをしかけてJVM実行時にこのアノテーションを宣言したクラス/メソッドの先頭にチェックロジックをjavassistで追加する、という手順をとる。
チェックロジックの実行コストが高いのであくまで開発時におけるコーディング規約の強制化と考えているけどどうかなと。
具体的には
- サービス層以下では使ってほしくないプレゼン層よりのクラス/メソッド
- プレゼン層以上では使ってほしくないDAO
とかにつかったらどうかなと。