本篇文章為大家帶來了關於java的相關知識,動態代理指的是,代理類別和目標類別的關係在程式運行的時候確定的,客戶透過代理類別來調用目標物件的方法,是在程式運行時根據需要動態的創建目標類別的代理物件。以下將透過案例詳細解說Java動態代理的原理及實現,希望對大家有幫助。
推薦學習:《java影片教學》
"代理"這個字相信大家並不陌生,簡單來說就是代替廠商來販賣商品,代理替代廠商販售商品,顧客找代理商購買商品。也就是說:1)顧客和廠商之間是看不見的,顧客不知道背後的廠商是誰。 2)代理可以對顧客進行“定位”,更精確的售賣給需要的客戶群。
代理模式:為其他物件提供一種代理程式以控制對這個物件的訪問,也就是創建一個代理物件作為客戶端和目標物件之間的中介,主要目的是保護目標物件或增強目標物件
透過使用代理模式,通常有以下兩個優點:
\1) 可以隱藏被代理類別的實作
\ 2) 可以實作客戶與被代理類別間的解耦,在不修改被代理類別程式碼的情況下能夠做一些額外的處理
所謂的動態代理,就是透過聲明一個明確的代理類別來存取來源對象,一個代理只能服務一種產品,當有n種產品時,就需要n個代理,這樣就不利於業務的發展。
範例:我們有兩個接口,Mouse和Keyboard,每個接口都有一個實作類別
實作類別中的程式碼如下:
public class LogitechMouse implements Mouse{ @Override public void sell() { System.out.println("出售罗技鼠标"); } } public class HHKBKeyboard implements Keyboard{ @Override public void sell() { System.out.println("出售HHKB键盘"); } }
現在我們要做的就是讓代理程式在呼叫sell()
前輸出一句售前了解,呼叫後輸出一句售後服務
那我們只需寫兩個代理類別MouseProxy
和KeyboardProxy
public class MouseProxy implements Mouse { private Mouse mouse; public MouseProxy(Mouse mouse) { this.mouse = mouse; } @Override public void sell() { System.out.println("售前了解"); mouse.sell(); System.out.println("售后服务"); } } public class KeyboardProxy implements Keyboard{ private Keyboard keyboard; public KeyboardProxy(Keyboard keyboard) { this.keyboard = keyboard; } @Override public void sell() { System.out.println("售前了解"); keyboard.sell(); System.out.println("售后服务"); } }
最終執行為:
public class Test { public static void main(String[] args) { Mouse logitechMouse = new LogitechMouse(); MouseProxy mouseProxy = new MouseProxy(logitechMouse); mouseProxy.sell(); Keyboard hhkbKeyboard = new HHKBKeyboard(); KeyboardProxy keyboardProxy = new KeyboardProxy(hhkbKeyboard); keyboardProxy.sell(); } }
##靜態代理程式的程式碼非常簡單易懂,這種模式雖好,但是也有明顯的缺點:輸出:
售前了解
出售羅技滑鼠
售後服務
售前了解
出售HHKB鍵盤
售後服務
java.lang.reflect.Proxy和
java.lang.reflect.InvocationHandler
public class JDKProxy implements InvocationHandler { private Object object; public JDKProxy(Object object) { this.object = object; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("售前了解"); Object invoke = method.invoke(object, args); System.out.println("售后服务"); return invoke; } }
public class Test { public static void main(String[] args) { Mouse logitechMouse = new LogitechMouse(); JDKProxy jdkProxy = new JDKProxy(logitechMouse); Mouse mouse= (Mouse)Proxy.newProxyInstance(jdkProxy.getClass().getClassLoader(), new Class[]{Mouse.class}, jdkProxy); mouse.sell(); HHKBKeyboard hhkbKeyboard = new HHKBKeyboard(); JDKProxy jdkProxy1 = new JDKProxy(hhkbKeyboard); Keyboard keyboard = (Keyboard)Proxy.newProxyInstance(jdkProxy1.getClass().getClassLoader(), new Class[]{Keyboard.class}, jdkProxy1); keyboard.sell(); } }
public class CGLIBProcy implements MethodInterceptor { private Enhancer enhancer = new Enhancer(); private Object object; public CGLIBProcy(Object object) { this.object = object; } public Object getProxy(){ //设置需要创建子类的类 enhancer.setSuperclass(object.getClass()); enhancer.setCallback(this); //创建代理对象 return enhancer.create(); } // o: cglib 动态生成的代理类的实例 // method:实体类所调用的都被代理的方法的引用 // objects 参数列表 // methodProxy:生成的代理类对方法的代理引用 @Override public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { System.out.println("售前了解"); Object invoke = method.invoke(object, objects); System.out.println("售后处理"); return invoke; } }
public class Test { public static void main(String[] args) { Mouse logitechMouse = new LogitechMouse(); CGLIBProcy cglibProcy = new CGLIBProcy(logitechMouse); Mouse proxy = (Mouse)cglibProcy.getProxy(); proxy.sell(); cglibProcy = new CGLIBProcy(new HHKBKeyboard()); Keyboard keyboard = (Keyboard)cglibProcy.getProxy(); keyboard.sell(); } }
java影片教學》
以上是完全掌握Java動態代理的詳細內容。更多資訊請關注PHP中文網其他相關文章!