そらとぶへび

仕事・プライベートを通しての気づき、JavaやPHP、データベースやサーバの話などこつこつと書いていきます

アノテーションによるコード呼び出し

アノテーションを定義する例と、リフレクションによるアノテーションのコード呼び出し例。
MyFilterというアノテーションを定義する。
実行時にリフレクションによる呼び出しを行うので、RetentionはRUNTIMEを指定する。

MyFilter.java  アノテーションを定義する。

import java.lang.annotation.*;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyFilter {
	enum Potion{
		BEFORE,
		AFTER,
	}
	Potion value();
}


CapitalizeFilter.java 定義したアノテーションを適用する。

public class CapitalizeFilter {
	@MyFilter(MyFilter.Potion.BEFORE)
	public String doJob(String input) {
		return input.toUpperCase();
	}
}

次のコードでCapitalizeFilterクラスから、MyFilterアノテーションを適用したメソッドを呼び出しを行う。
isAnnotationPresentでアノテーションの有無を判定を行う。
getAnnotationでもアノテーションの参照を取得しているので、やや冗長かもしれない。

MyEcho.java

import java.io.*;
import java.lang.reflect.*;
import java.util.*;

public class MyEcho {
	
	private static class Filter{
		Filter(Object obj, Method method){
			this.obj = obj;
			this.method = method;
		}
		final Object obj;
		final Method method;
	}
	
	
	private final List<Filter> filters = new ArrayList<>();

	public MyEcho(String... classNames) throws ReflectiveOperationException{
		// プラグインコードのロード
		
		for(String className : classNames) {
			Class clazz = Class.forName(className); // リフレクションを使用してクラス名を取得
			
			for(Method method : clazz.getMethods()) {
				System.out.println("MyFilter.class " + MyFilter.class);
				if(method.isAnnotationPresent(MyFilter.class)) {  // アノテーションの有無を判定
					System.out.println("method " + method);
					MyFilter myfilter = method.getAnnotation(MyFilter.class);
					if(myfilter != null) {
						switch(myfilter.value()) {
						case BEFORE:
							filters.add(0,new Filter(clazz.newInstance(),method));
							break;
						case AFTER:
							filters.add(new Filter(clazz.newInstance(),method));
						}
					}
				}
			}
		}
	}
	
	
	public void exec() {
		try(BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in))) {
			while(true) {
				System.out.println("Input any text");
				
				String msg = stdin.readLine();
				
				String output = msg;
				for(Filter filter : filters) {
					output = (String)filter.method.invoke(filter.obj, output);
				}
				
				System.out.println("You sey " + output);
			}
		}catch(IOException| ReflectiveOperationException e) {
			e.printStackTrace();
		}
	}
	
	public static void main(String... args) throws ReflectiveOperationException{
		MyEcho echo = new MyEcho(args);
		echo.exec();
	}

}

実行結果

java MyEcho CapitalizeFilter 
Input any text
abc
You sey ABC