aptでアノテーションを処理する。
JDK添付のアノテーション処理ツール「apt」を使ってみます。これを利用して、
などアノテーションを元にしたソースコードやリソースの生成が可能です。
手順
基本的な作業手順は次のとおりです。アノテーションとアノテーションの処理クラスを作成し、aptを実行します。
- アノテーションの処理クラス(AnnotationProcessorFactoryの派生クラス)を作成します。(注:AnnotationProcessorFactoryはtools.jarに含まれています。)
- 処理対象のアノテーション/ソースコード作成します。
- アノテーション処理クラスをコンパイルします。
- 処理対象のアノテーションをコンパイルします。
- aptを実行します。
構文:
apt -cp <クラスパス> -factory <アノテーションの処理クラス> <処理対象のソースコード>
例:
apt -cp bin/ -factory apt.TestApf java/apt/TestService.java
サンプル
以下は、アノテーションされたクラスとそのメソッドを出力するサンプルです。
package apt; public @interface Hoge {}
クラス:
package apt; @Hoge public class Test { private void test1() {} public String test2( int i, String str ) { return null; } }
アノテーション処理クラス:
package apt; import static java.util.Collections.emptySet; import static java.util.Collections.unmodifiableCollection; import java.util.Arrays; import java.util.Collection; import java.util.Iterator; import java.util.Set; import com.sun.mirror.apt.AnnotationProcessor; import com.sun.mirror.apt.AnnotationProcessorEnvironment; import com.sun.mirror.apt.AnnotationProcessorFactory; import com.sun.mirror.declaration.AnnotationTypeDeclaration; import com.sun.mirror.declaration.MethodDeclaration; import com.sun.mirror.declaration.ParameterDeclaration; import com.sun.mirror.declaration.TypeDeclaration; /** * AnnotationProcessorFactoryの派生クラス。 * */ public class TestApf implements AnnotationProcessorFactory { /**処理できるアノテーションの指定*/ private static final Collection<String> supportedAnnotations = unmodifiableCollection(Arrays.asList("apt.Hoge")); /**アノテーションが受け取るパラメータ*/ private static final Collection<String> supportedOptions = emptySet(); /* * 処理できるアノテーションの指定を返す */ public Collection<String> supportedAnnotationTypes() { return supportedAnnotations; } /* * アノテーションが受け取るパラメータを返す。 */ public Collection<String> supportedOptions() { return supportedOptions; } /* * アノテーションに対応するアノテーションプロセッサを返す。 */ public AnnotationProcessor getProcessorFor( Set<AnnotationTypeDeclaration> atds, AnnotationProcessorEnvironment env) { return new TestAnnotationProcessor(env); } /**アノテーションプロセッサーの実装。*/ static class TestAnnotationProcessor implements AnnotationProcessor { /**環境情報*/ private final AnnotationProcessorEnvironment env; /** * コンストラクタ * @param env 環境情報 */ TestAnnotationProcessor(AnnotationProcessorEnvironment env) { this.env = env; // 環境情報を記録しておく。 } /* * 処理を実行。 */ public void process() { // 環境情報よりソースコードにアクセス。 for (TypeDeclaration typeDecl : env.getSpecifiedTypeDeclarations()) { // クラス名を出力 System.out.println( typeDecl.getQualifiedName()) ; // メソッドを出力 for ( MethodDeclaration md : typeDecl.getMethods()) { StringBuffer buff = new StringBuffer(" "); buff.append( md.getReturnType().toString() ); buff.append( " "); buff.append( md.getSimpleName() ).append( " (" ); Iterator<ParameterDeclaration> pdi = md.getParameters().iterator(); while ( pdi.hasNext() ) { ParameterDeclaration pd = pdi.next(); buff.append( pd.getType().toString() ).append( " " ).append( pd.getSimpleName() ); if ( pdi.hasNext() ) { buff.append( "," ); } } buff.append( " );"); System.out.println( buff.toString() ); } } } } }
実行:
apt -cp bin -factory apt.TestApf apt/Test.java
出力:
apt.Test void test1 ( ); java.lang.String test2 (int i,java.lang.String str );