Java代理總結
一,幾個名詞:
1.靜態代理
要求:代理對象和被代理對象(目標對象)都要同時實現相同的接口或繼承相同的父類。即沒有這個前提條件是沒法實現靜態代理的。
2.動態代理
動態代理又分:
Java JDK: Proxy 代理(又叫接口代理)
要求:目標類必須實現接口或繼承父類,代理則不需要。
CGLIB代理:子類代理
要求:目標方法無需實現接口或類。
二.代碼(動態代理)
1.Java JDK代理(Proxy 代理)
接口:
public interface IUser {
public void sayHello();
}
實現類(目標類):
public class User implements IUser {
@Override
public void sayHello() {
System.out.println("User sayHello()");
}
}
代理類:
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class ProxyFactory {
private Object target;
public ProxyFactory(Object target) {
this.target = target;
}
public Object getProxyInstance() {
// JDK Proxy靜態方法static Object newProxyInstance(ClassLoader loader,
// Class<?>[] interfaces,InvocationHandler h );實現動態JDK代理
/**
* newProxyInstance()方法有三個參數: ClassLoader loader:獲取目標對象的類加載器 Class<?>[]
* interfaces:以泛型的方式拿到目標對象實現的接口類型 InvocationHandler
* h:目標對象執行方法得到加強,目標對象的方法會被以參數的形式傳入
*/
return Proxy.newProxyInstance(target.getClass().getClassLoader(),
target.getClass().getInterfaces(), new InvocationHandler() {
// InvocationHandler對象中的invoke方法
/**
* invoke方法的三個參數:
* Object proxy:代理對象本身
* Method method:目標對象方法
* Object[] args: 方法的參數
*
*/
public Object invoke(Object proxy, Method method,
Object[] args) throws Throwable {
System.out.println("proxy:" + proxy.getClass());
System.out.println("功能增強1.。。。。");
Object returnValue = method.invoke(target, args);
System.out.println("功能增強2.。。。。");
return returnValue;
}
});
}
}
測試類:
public class ProxyTest {
public static void main(String[] args) {
IUser target = new User();
System.out.println("User對象:" + target.getClass());
//代理實現User
IUser proxy = (IUser) new ProxyFactory(target).getProxyInstance();
System.out.println("代理實現User對象:" + proxy.getClass());
//運行方法,執行增強的代理對象
proxy.sayHello();;
}
}
輸出:
從圈出部分可以看出invoke(Object Proxy,..)方法中的Proxy爲代理對象本身