簡易AOPフレームワークの作成
ちょっと現場で必要なので、CGLIBを使って簡易なAOPフレームワークを作ります。
トランザクション管理やコネクションのクローズを管理するフレームワークを作ることにします。
アノテーションを使ってプラグイン式に機能を追加できるようにします。
ただし、このフレームワークは対象オブジェクトの生成を管理しておく必要があります。
new演算子を使ってオブジェクト生成をすることを禁止し、
下記に紹介するFactoryクラスでオブジェクトを生成するルールを徹底します。
【準備】
以下のライブラリをダウンロードして、クラスパスに通しておきます。
■CGLIB
http://cglib.sourceforge.net/
・cglib-2.2.jar
■ASM
http://asm.ow2.org/
・asm-3.2.jar
【Factory.java】
フレームワーク側のソースコードは以下です。
FactoryのgetInstanceメソッドによってオブジェクトを生成するというルール付けが必要です。
package kronosjp; import java.lang.annotation.*; import java.lang.reflect.Method; import net.sf.cglib.proxy.*; public class Factory{ @SuppressWarnings("unchecked") public static <T> T getInstance(Class<T> targetClass){ return (T) Enhancer.create(targetClass,new TransactionMethodIntercepter()); } } class TransactionMethodIntercepter implements MethodInterceptor{ public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { System.out.println("before:" + method.getName()); boolean isTransactional = method.isAnnotationPresent(Transactional.class); if (isTransactional){ System.out.println("transaction start"); } // オリジナルメソッドの実行 Object result = proxy.invokeSuper(obj, args); if (isTransactional){ System.out.println("transaction end"); } System.out.println("after:"+ method.getName()); return result; } } @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) @interface Transactional{ }
【Start.java】
ビジネスロジック側のソース。
@Transactionalメソッドをつけたメソッドがトランザクションメソッドになる仕組みです。
package kronosjp; // 起動クラス public class Start { public static void main(String[] args) throws Exception{ LogicObject foo = Factory.getInstance(LogicObject.class); foo.logic(); } } // ビジネスロジッククラス class LogicObject { @Transactional public void logic(){ System.out.println("do logic"); } }