●動的プロキシによるアスペクトとしての実装

JDK 1.3以上

アスペクト志向の実装を動的プロキシ(または、ダイナミックプロキシ)と呼ばれる方法でJDK標準で
提供される機能だけで行うことが出来ます。

実現には
java.lang.reflect.Proxy
java.lang.reflect.InvocationHandler
を使用します。

まずは、
java.lang.reflect.InvocationHandler
の実装クラスを用意します。
これは、「呼び出しハンドラ」と呼ばれProxyクラス経由で実行されるメソッドをフックする為に実装します。

public class MyInvocationHandler implements InvocationHandler{
	private Object target;
	public MyInvocationHandler(Object target){
		// 本来のインスタンスを保持しておきます。
		this.target = target;
	}
	@Override
	public Object invoke( Object proxy , Method method , Object[] args ) throws Throwable {
		
		System.out.println("invoke method:"+method.getName());
		
		// 本来呼ばれるべきメソッドを本来のインスタンスで実行します。
		// 必要に応じて実行すべきでない場合、実行する必要はありません。
		Object ret = method.invoke( this.target , args );
		
		System.out.println("invoke result:"+ret.toString());
		
		// 通常の場合、戻り値は本来呼ばれるべきメソッドの結果を返します。
		// 但し、必要に応じてそうでなくてもかまいません。
		return ret;
	}
}

次に、Proxy経由で実行するクラスを用意します。
このときに注意が必要です。
Proxyクラスの動作の特性上、必ずinterfaceとその実装クラスを用意しなければなりません。

interface MyInterface{
	String sayHello(String name);
}

class MyClass implements MyInterface{
	@Override
	public String sayHello( String name ) {
		// hello! 名前をコンソールに出力するだけ。
		System.out.println("hello! "+name);
		// 戻り値としてhello!を返す。
		return "hello!";
	}
	
}

最後にProxy経由でインスタンスを生成し、
後は通常の呼び出しと同じようにメソッドを実行します。

public static void main(String[] args) throws Exception{
	// 通常のnewで得られるインスタンスを用意しておきます。
	MyInterface myInterfaceReal = new MyClass();
	// 呼び出しハンドラクラスを生成します。
	// その際に実際のインスタンスを渡しておきます。
	InvocationHandler handler = new MyInvocationHandler(myInterfaceReal);
	
	// Proxy.newProxyInstanceメソッドを使ってインスタンスを生成します。 
	MyInterface myInterface = (MyInterface)Proxy.newProxyInstance(
						// ClassLoader
						MyClass.class.getClassLoader() ,
						// メソッドフックに使われるinterface.
						MyClass.class.getInterfaces() ,
						// 呼び出しハンドラ
						handler );
	// 実行は通常と変わりません。myInterfaceの方であることに注意してください。
	String ret = myInterface.sayHello( "JAVA" );
	
	System.out.println(ret);
}

Proxyインスタンスの生成などは概ね定型的な処理になります。
最後にこの実行結果は次のようになります。

invoke method:sayHello
hello! JAVA
invoke result:hello!
hello!