Java代理總結(Proxy,CGLib,靜態代理,動態代理)

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爲代理對象本身


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章