目錄
動態代理中存在的概念
JDK動態代理
代理工廠【ProxyFactory】實現【InvocationHandler】
目標類的接口【TargetInterface】
目標類【Target】實現了接口
測試類【JDKDynamicProxyTest】
CGLIB動態代理
添加Maven依賴
代理工廠【ProxyFactory】實現【MethodInterceptor】
目標類【Target】沒有實現接口?
?測試類【CGLIBDynamicProxyTest】
動態代理中存在的概念
- 目標類、目標對象【target】
- 代理類、代理對象【proxy】
- 增強邏輯【advice】
JDK動態代理
- 要求:目標類必須要實現接口
- 原理:和目標類實現同一個接口,對目標類進行增強
代理工廠【ProxyFactory】實現【InvocationHandler】
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;public class ProxyFactory<T> implements InvocationHandler {// 目標對象private final T target;public ProxyFactory(T target) {this.target = target;}/*** 獲取代理對象*/@SuppressWarnings("all")public T getProxy() {// 類加載器ClassLoader classLoader = getClassLoader();// 接口Class<?>[] interfaces = getInterfaces(target);// 返回代理對象return (T) Proxy.newProxyInstance(classLoader, interfaces, this);}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {Object obj;try {// 前置增強before();obj = method.invoke(target, args);// 返回后增強afterReturning();return obj;} catch (Throwable throwable) {// 異常后增強afterThrowing();throw throwable;} finally {// 后置增強after();}}private ClassLoader getClassLoader() {return Thread.currentThread().getContextClassLoader();}private Class<?>[] getInterfaces(T target) {return target.getClass().getInterfaces();}private void before() {System.out.println("before...");}private void after() {System.out.println("after...");}private void afterThrowing() {System.out.println("afterThrowing...");}private void afterReturning() {System.out.println("afterReturning...");}
}
目標類的接口【TargetInterface】
public interface TargetInterface {void method();
}
目標類【Target】實現了接口
public class Target implements TargetInterface {public void method() {System.out.println("執行目標方法...");}
}
測試類【JDKDynamicProxyTest】
/*** 測試JDK動態代理*/
public class JDKDynamicProxyTest {public static void main(String[] args) {// 目標對象TargetInterface target = new Target();ProxyFactory<TargetInterface> proxyFactory = new ProxyFactory<>(target);// 代理對象TargetInterface proxy = proxyFactory.getProxy();// 目標對象方法執行邏輯 + 增強邏輯proxy.method();}
}
CGLIB動態代理
- 要求:目標類非final關鍵字修飾
- 原理:將目標類作為父類,通過子類來對父類進行增強
添加Maven依賴
<!--CGLIB依賴-->
<dependency><groupId>cglib</groupId><artifactId>cglib</artifactId><version>3.3.0</version>
</dependency>
代理工廠【ProxyFactory】實現【MethodInterceptor】
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;import java.lang.reflect.Method;public class ProxyFactory<T> implements MethodInterceptor {/*** 獲取代理對象*/@SuppressWarnings("all")public T getProxy(Class<T> cls) {Enhancer enhancer = new Enhancer();// 設置父類enhancer.setSuperclass(cls);// 設置回調enhancer.setCallback(this);// 返回創建的代理對象return (T) enhancer.create();}@Overridepublic Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {Object result;try {System.out.println("前置增強...");// 調用目標對象的方法result = methodProxy.invokeSuper(o, args);System.out.println("正常返回時增強...");return result;} catch (Throwable throwable) {System.out.println("異常時增強...");throw throwable;} finally {System.out.println("后置增強...");}}
}
目標類【Target】沒有實現接口?
public class Target {public void method() {System.out.println("目標方法執行++++++++");}
}
?測試類【CGLIBDynamicProxyTest】
public class CGLIBDynamicProxyTest {public static void main(String[] args) {ProxyFactory<Target> proxyFactory = new ProxyFactory<>();// 代理對象Target proxy = proxyFactory.getProxy(Target.class);// 原始邏輯 + 增強邏輯proxy.method();}
}