目次

はじめに

設定ファイル地獄という言葉がある。 設定中心のフレームワークが、設定だらけになって メンテナンスが地獄のように面倒になる現象だ。

ここで、アノテーションと呼ばれるものの登場である。

最初アノテーションと言う言葉を知ったときには、何につかうのか?と使い道が思いつかなかったのだが、どうやら、設定中心のフレームワークに応用すると、地獄から抜けられる。たとえば、Strutsに対するSAStrutsの登場である。

自分は、当初SAStrutsがあるんだから、それを使えばよいと思っていた。

しかしながら、SAStrutsは、独自の規約で作成しなくてはならないため、プロジェクトに応用できないということがわかってきた。

だったら、自分で道を切り開くのみである。

というわけで、以下アノテーションについてまとめてみた。

目標

以下の方法を理解する。

  • クラスにつけるアノテーションを定義
  • メソッドにつけるアノテーションに定義

作り方

クラスにつけるアノテーションを定義

最小限の学習ですむように説明するならば、 たとえば、 StringValueAnnotation というアノテーションを作りたいとすると下記のようになる。 @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) @interface StringValueAnnotation { String value() default "デフォルト値"; } その他は、固定値だと思って差しつかえない。

メソッドにつけるアノテーションに定義

上記の例でTYPEとなっている箇所を FIELD に置き換えるだけでよい。

実装クラス一覧

知りたいのは、実装するクラスの一覧であるが、どういうわけか Javaらしからず、そのような一覧取得のメソッドは用意されていない、 自分で道を切り開くのみである。

ソースフォルダを指定すると、クラス一覧を取得するメソッドを作製する。

とりあえず作ったサンプル

ActionAnnotation

package kuniwiki;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;


@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@interface ActionAnnotation {
String value1() default "";
String value2() default "";
String value3() default "";

}

AnnoMain

package kuniwiki;

import java.io.File;
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;

public class AnnoMain {
public static void main(String[] args) throws IOException {
    String basePath = "C:/bin/pleiades/workspace/prjAno/src";

    FileSearch search = new FileSearch();
    File[] files = search.listFiles(basePath, "*.java");

    for(File f : files){
        Class clazz = toClass(basePath, files[4]);
        HashMap<String, HashMap<String, String>> ano = toAnoHash(clazz);
        if (ano != null) {
                System.out.println(ano.get("kuniwiki.ActionAnnotation").get("value1"));
                System.out.println(ano.get("kuniwiki.ActionAnnotation").get("value2"));
                System.out.println(ano.get("kuniwiki.ActionAnnotation").get("value3"));
        }
    }


}

private static HashMap toAnoHash(Class clazz) {
    HashMap ret = new HashMap<String, HashMap<String, String>>();
    Annotation[] as = clazz.getDeclaredAnnotations();
    for (Annotation a : as) {
        Class tp = a.annotationType();

        // アノテーション名を登録;
        HashMap<String, String> item = new HashMap<String, String>();
        ret.put(a.annotationType().getName(), item);
        // フィールドを追加

        ActionAnnotation an = (ActionAnnotation)a;
        //tp.getTypeParameters();


        Method[] ms = an.getClass().getMethods();
        //Annotation[][] ma = ms[0].getParameterAnnotations();
        try {
            Object[] param = {};
            item.put(ms[4].getName(),ms[4].invoke(an, param).toString());
        } catch (IllegalArgumentException e) {
            // TODO
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            // TODO
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            // TODO
            e.printStackTrace();
        }

        // item.put("value1",Class.forName("kuniwiki.ActionAnnotation").cast(a).getClass().getFields()[0].toString());

    }
    return ret;
}

private static boolean hasActionAnnotation(Class clazz) {
    Class ano = ActionAnnotation.class;

    Annotation[] as = clazz.getDeclaredAnnotations();
    for (Annotation a : as) {
        if (a instanceof ActionAnnotation) {
            return true;
        }
    }
    return false;
}

private static Class toClass(String src, File fi) {
    // ソースのパスを置換用に置き換える
    String srcpath = src.replaceAll("/", "\\\\\\\\");
    // ファイルの親パスからソースパスをさっぴいて、フォルダを意味する記号をドットに置き換え、ファイル名をクラス名として連結する。
    String classname = fi.getParent().replaceFirst(srcpath, "")
            .replaceAll("\\\\", ".").replaceFirst("\\.", "")
            + "." + fi.getName().replace(".java", "");

    try {
        System.out.println(classname);
        return Class.forName(classname);
    } catch (ClassNotFoundException e) {
        return null;
    }
}

}

参考ページ

http://sattontanabe.blog86.fc2.com/blog-entry-55.html

参考ページ

http://www.ne.jp/asahi/hishidama/home/tech/java/annotation.html


トップ   編集 凍結 差分 履歴 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   最終更新のRSS
Last-modified: 2026-05-22 (金) 23:17:12