一部の Java プロジェクトでは、mybatis と spring の統合に MapperScannerConfigurer が使用され、このクラスはリバース プロキシを通じてインターフェイス ベースの動的プロキシ クラスを自動的に生成します。
これを考慮して、この記事では Java の動的プロキシを簡単に分析します。
この記事では、動的プロキシを使用して、トランザクションを処理するインターセプターをシミュレートします。
インタフェース:
パブリックインターフェイスUserService {パブリックボイド追加ユーザー();パブリックボイド削除ユーザー();}実装クラス:
public class UserServiceImpl は UserService { public void addUser() { System.out.println("ユーザーの追加"); } public void RemoveUser() { System.out.println("remove user") } public void searchUser(); System.out.println("ユーザーの検索");Java動的プロキシを実装するには2つの方法があります
1. jdk に付属する動的プロキシ
jdk に付属の動的プロキシを使用するには、InvocationHandler インターフェイスと Proxy クラスを理解する必要があります。これらは両方とも java.lang.reflect パッケージの下にあります。
InvocationHandler の紹介:
InvocationHandler は、プロキシ インスタンスの呼び出しハンドラーによって実装されるインターフェイスです。
各プロキシ インスタンスには、関連付けられた InvocationHandler があります。プロキシ インスタンスでメソッドを呼び出す場合、このメソッドは InvocationHandler の invoke メソッドを呼び出します。
プロキシの紹介:
プロキシは、動的プロキシ クラスとインスタンスを作成するための静的メソッドを提供します。
例 (AOP トランザクション処理のシミュレーション):
public class TransactionInterceptorimplements InvocationHandler { private Object target; public void setTarget(Object target) { this.target = target; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println ("トランザクションの開始"); system.out.println("トランザクションの終了");テストコード:
public class TestDynamicProxy { @Test public void testJDK() { TransactionInterceptortransactionInterceptor = new UserService userService = new UserServiceImpl(userService); UserService userServiceProxy = (userService) Proxy.newProxyInstance(); .getClassLoader()、 userService.getClass().getInterfaces()、transactionInterceptor);テスト結果:
start トランザクションadd userend トランザクション
明らかに、userServiceProxy プロキシ クラスを通じてメソッド呼び出しを行うと、メソッド呼び出しの前後にトランザクションがオープンおよびクローズされます。
2. サードパーティライブラリ cglib
CGLIB は、Java クラスを拡張し、実行時に Java インターフェイスを実装するための、強力で高性能、高品質のコード生成ライブラリです。
JDK の動的プロキシとの最大の違いは次のとおりです。
JDK の動的プロキシはインターフェイス用ですが、cglib はクラス用のプロキシを実装します。ただし、cglib の原理は、指定されたターゲット クラスのサブクラスを生成し、メソッドを上書きして拡張を実現することです。ただし、継承が使用されるため、変更されたクラスは次のようになります。プロキシされました。
コード例は次のとおりです。
public class UserServiceCallBackimplements MethodInterceptor { @Override public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable { System.out.println("start Transaction by cglib"); ); System.out.println("cglib によるトランザクションの終了");テストコード:
public class TestDynamicProxy { @Test public void testCGLIB() { エンハンサー エンハンサー = new Enhancer(); エンハンサー.setSuperclass(UserServiceImpl.class); エンハンサー.setCallback(new UserServiceImpl) プロキシ = (UserServiceImpl)enhancer.create(); ; プロキシ.addUser();テスト結果:
start cglibadd によるトランザクション userend cglib によるトランザクション
興味のある読者は、この記事の例を実際に試してみると、多くのことが得られると思います。