代理模式是經常使用的設計模式,通常可分爲靜態和動態代理。java
實現步驟設計模式
Proxy.newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h);
public class AHandler implements InvocationHandler { private Object target; public AHandler(A target) { super(); this.target = target; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("\n================="); method.invoke(target); System.out.println("================="); Class<? extends Object> proxyClass = proxy.getClass(); System.out.println(" --- proxy class:" + proxyClass.getName()); Class<?> fooProxyClass = proxyClass.getSuperclass(); System.out.println(" --- super proxy class:" + fooProxyClass.getName()); System.out.println(" --- method:" + method.getName()); // 如下是一個死循環 // Method[] methods = proxyClass.getDeclaredMethods(); // for (Method m : methods){ // System.out.println(m.getName()); // if("say".equals(m.getName())){ // System.out.println(" --- 讓$Proxy0這個代理對象調用say方法"); // m.invoke(proxy); // } // } return 2; } }
public class A implements InterA{ @Override public void say() { System.out.println(" --- i love m --- "); } @Override public int hear() { System.out.println(" --- Saturday --- "); return 1; } public static void main(String[] args) { A a = new A(); Class<? extends A> aclass = a.getClass(); AHandler handler = new AHandler(a); Object proxy = Proxy.newProxyInstance(aclass.getClassLoader(), aclass.getInterfaces(), handler); System.out.println(" --- return proxy class:" + proxy.getClass().getName()); InterA aProxy = (InterA) proxy; aProxy.say(); int i = aProxy.hear(); System.out.println(i); int h = aProxy.hashCode(); System.out.println(h); } }
//console --- return proxy class:com.sun.proxy.$Proxy0 ================= --- i love m --- ================= --- proxy class:com.sun.proxy.$Proxy0 --- super proxy class:java.lang.reflect.Proxy --- method:say ================= --- Saturday --- ================= --- proxy class:com.sun.proxy.$Proxy0 --- super proxy class:java.lang.reflect.Proxy --- method:hear 2 ================= ================= --- proxy class:com.sun.proxy.$Proxy0 --- super proxy class:java.lang.reflect.Proxy --- method:hashCode 2
以上是根據視頻本身寫的測試類,關於JDK動態代理,總結以下:ide
JDK動態代理的實現原理,基本上就是反射,以say()爲例,代理對象調用say(),實際上是去調用Handler的invoke方法,其中參數是封裝say()的Method對象。測試
JDK動態代理this
cglib動態代理設計
如下是一個cglib的基本用法代理
public class BProxy implements MethodInterceptor{ //代理類實例 private Enhancer enhancer = new Enhancer(); //獲取代理類 public Object getProxy(Class<?> cls){ //設置父類,即原類 enhancer.setSuperclass(cls); //回調 enhancer.setCallback(this); //建立代理類 return enhancer.create(); } /** * 攔截因此目標類方法的調用 * @param obj 目標類的實例 * @param m 目標方法的反射對象 * @param arg 目標方法的參數 * @param proxy 代理類的實例 */ @Override public Object intercept(Object obj, Method m, Object[] arg, MethodProxy proxy) throws Throwable { System.out.println("\n================="); //代理類調用父類的方法,即原方法 proxy.invoke(obj, arg); System.out.println("================="); return null; } }
注:以上爲我的感悟,未讀源碼驗證。code