JDBC動態代理
對動態代理的原理的解釋
重要參考


對生成代理對象和方法調用的過程分析
-
1.調用Proxy.newProxyInstance()方法動態生成代理對象
在這個過程我們傳入了目標類的類加載器(即被代理類)和代理類需要實現的接口數組。JDK使用一種稱為“字節碼技術”的方法來生成代理類的字節碼。
1.JDK使用提供的類加載器加載生成的代理類的字節碼,并通過反射創建一個代理類的實例。這個實例就是最終的動態代理對象。
2.將InvocationHandler實現與代理對象關聯:在創建動態代理對象時,JDK會將你提供的InvocationHandler實現對象與代理對象關聯起來。這樣,當代理對象上的方法被調用時,就會調用InvocationHandler的invoke方法。 -
2.當代理對象調用方法時分析
jdk自動將我們的代理對象和InvocationHandler接口的實現類相關聯起來了,當我們調用代理對象中的方法的時候將會自動調用實現類中重寫的
invoke方法,實現方法增強
動態生成的代理類的腦補實現(示意圖,無法執行)
- 動態生成的代理類我們看不到類,但是我們可以分析一下他的組成結構
package com.itheima.domain;
public class LeaderProxy implements IWork{
//關聯InvocationHandler接口的實現類
WorkInvocationHandler handler = new WorkInvocationHandler();
@Override
public void meeting() {
//將方法調用轉發給WorkInvocationHandler中的invoke方法
//傳入動態生成的代理對象
//代理的方法
//方法需要的參數
return handler.invoke(proxy,method,args);
}
@Override
public int evaluate(String name) {
//將方法調用轉發給WorkInvocationHandler中的invoke方法
//傳入動態生成的代理對象
//代理的方法
//方法需要的參數
return handler.invoke(proxy,method,args);
}
}
發現和靜態代理相比
- 1.靜態代理關聯被代理類,增強部分在代理類中寫
- 2.動態代理類,關聯InvocationHandler接口的實現類,InvocationHandler接口的實現類關聯被代理類,增強部分在實現類中寫
但是動態代理類在間接上是管理被代理類的,增強部分間接是在動態代理類中寫的。所以本質上代理類和動態代理類是一樣的
package com.proxy;
public interface UserDao {
//計算2個整數的和
public void add ();
}
package com.proxy;
public class UserDaoImpl implements UserDao{
@Override
public void add() {
System.out.println("被增強方法執行");
}
}
package com.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
//代理類實現InvocationHandler接口
public class UserDaoImplProxy implements InvocationHandler {
//被代理類的對象
private Object obj;
//將被代理類的對象傳遞進來
public UserDaoImplProxy(Object obj){
this.obj=obj;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("前置增強....");
//被增強的方法執行
final Object res = method.invoke(obj, args);
System.out.println("后置增強.....");
return res;
}
}
package com.proxy;
import java.lang.reflect.Proxy;
public class Main {
public static void main(String[] args) {
//被代理類的接口(參數二)
Class[] interfaces = {UserDao.class};
//實現InvocationHandler接口的代理類
UserDaoImpl userDaoImpl = new UserDaoImpl();
final UserDao proxyInstance =
(UserDao) Proxy.newProxyInstance(UserDao.class.getClassLoader(), interfaces, new UserDaoImplProxy(userDaoImpl));
proxyInstance.add();
}
}
浙公網安備 33010602011771號