本篇文章主要介紹了JAVA中的靜態代理、動態代理以及CGLIB動態代理總結,具有一定的參考價值,有興趣的可以了解一下
代理模式是java中最常用的設計模式之一,尤其是在spring框架中廣泛應用。對於java的代理模式,一般可分為:靜態代理、動態代理、以及CGLIB實作動態代理。
對於上述三種代理模式,分別進行說明。
1.靜態代理
靜態代理其實就是在程式運行之前,提前寫好被代理方法的代理類,編譯後運行。在程式運行之前,class已經存在。
下面我們實作一個靜態代理程式demo:
靜態代理程式
定義一個介面Target
package com.test.proxy; public interface Target { public String execute(); }
TargetImpl 實作介面Target
package com.test.proxy; public class TargetImpl implements Target { @Override public String execute() { System.out.println("TargetImpl execute!"); return "execute"; } }
代理程式類別
##
package com.test.proxy; public class Proxy implements Target{ private Target target; public Proxy(Target target) { this.target = target; } @Override public String execute() { System.out.println("perProcess"); String result = this.target.execute(); System.out.println("postProcess"); return result; } }測試類別:
package com.test.proxy; public class ProxyTest { public static void main(String[] args) { Target target = new TargetImpl(); Proxy p = new Proxy(target); String result = p.execute(); System.out.println(result); } }運行結果:
perProcess TargetImpl execute! postProcess execute靜態代理程式需要針對被代理程式的方法提前寫好代理類,如果被代理的方法非常多則需要編寫很多程式碼,因此,對於上述缺點,透過動態代理的方式進行了彌補。
2.動態代理程式
動態代理程式主要透過反射機制,在執行時間動態產生所需代理程式的class.動態代理介面
package com.test.dynamic; public interface Target { public String execute(); }實作類別
package com.test.dynamic; public class TargetImpl implements Target { @Override public String execute() { System.out.println("TargetImpl execute!"); return "execute"; } }代理類別
package com.test.dynamic; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; public class DynamicProxyHandler implements InvocationHandler{ private Target target; public DynamicProxyHandler(Target target) { this.target = target; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("========before=========="); Object result = method.invoke(target,args); System.out.println("========after==========="); return result; } }測試類別
#
package com.test.dynamic; import java.lang.reflect.Proxy; public class DynamicProxyTest { public static void main(String[] args) { Target target = new TargetImpl(); DynamicProxyHandler handler = new DynamicProxyHandler(target); Target proxySubject = (Target) Proxy.newProxyInstance(TargetImpl.class.getClassLoader(),TargetImpl.class.getInterfaces(),handler); String result = proxySubject.execute(); System.out.println(result); } }執行結果:
========before========== TargetImpl execute! ========after=========== execute無論是動態代理還是靜態帶領,都需要定義接口,然後才能實現代理功能。這同樣有局限性,因此,為了解決這個問題,出現了第三種代理方式:cglib代理。
3.cglib代理
CGLib採用了非常底層的字節碼技術,其原理是透過字節碼技術為一個類別創建子類,並在子類別中採用方法攔截的技術攔截所有父類別方法的調用,順勢織入橫切邏輯。 JDK動態代理與CGLib動態代理程式皆是實現Spring AOP的基礎。 cglib動態代理package com.test.cglib; public class Target { public String execute() { String message = "-----------test------------"; System.out.println(message); return message; } }通用代理程式類別:
package com.test.cglib; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; import java.lang.reflect.Method; public class MyMethodInterceptor implements MethodInterceptor{ @Override public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { System.out.println(">>>>MethodInterceptor start..."); Object result = proxy.invokeSuper(obj,args); System.out.println(">>>>MethodInterceptor ending..."); return "result"; } }測試類別
package com.test.cglib; import net.sf.cglib.proxy.Enhancer; public class CglibTest { public static void main(String ... args) { System.out.println("***************"); Target target = new Target(); CglibTest test = new CglibTest(); Target proxyTarget = (Target) test.createProxy(Target.class); String res = proxyTarget.execute(); System.out.println(res); } public Object createProxy(Class targetClass) { Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(targetClass); enhancer.setCallback(new MyMethodInterceptor()); return enhancer.create(); } }執行結果:
*************** >>>>MethodInterceptor start... -----------test------------ >>>>MethodInterceptor ending... result代理物件的產生過程由Enhancer類別實現,大概步驟如下:
以上是Java中關於靜、動態代理以及CGLIB動態代理程式的詳解(圖)的詳細內容。更多資訊請關注PHP中文網其他相關文章!