動態代理程式的特性:
當代理程式物件的時候,不需要實作介面
代理物件的產生,是利用JDK的API,動態的在記憶體中建構代理物件(需要我們指定創建代理物件/目標物件實現的介面的類型)
動態代理程式的別稱:JDK代理程式、介面代理
#類別圖:
Java動態代理程式類別位於java.lang.reflect套件下
一般主要涉及以下兩個類別:
1、Interface InvocationHandler : 該介面中僅定義了一個方法public object invoke(Object obj,Method method , Object[] args) 在實際使用時,第一個參數obj一般是指代理類,method是被代理的方法,args為該方法的參數數組。這個抽象方法在代理類別中動態實作。
2、Proxy:該類別即為動態代理類別
static Object newProxyInstance(ClassLoader loader, Class[] interfaces,InvocationHandler h):
傳回代理類別的一個實例,返回後的代理類別可以當作被代理類別使用(可使用被代理類別的在介面中宣告過的方法)
動態代的實作步驟:
#建立一個實作介面InvocationHandler的類,它必須實作invoke方法
#建立被代理程式的類別以及介面
呼叫Proxy的靜態方法,建立一個代理類別:newProxyInstance(ClassLoader loader,Class[]
透過代理呼叫方法
例如現在有一個汽車駕駛的方法:
public interface Moveable { void move(); }
現在有一輛車:
//实现Moveable 接口,并随机暂停一段时间 import java.util.Random; public class Car implements Moveable{ @Override public void move() { try{ Thread.sleep(new Random().nextInt(1000)); System.out.println("汽车行驶中"); } catch (InterruptedException e) { e.printStackTrace(); } } }
時間代理程式類別:
import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; public class TimeHandler implements InvocationHandler{ public TimeHandler(Object target){ super(); this.target = target; } private Object target; /** * * @param proxy :被代理的对象 * @param method:被代理对象的方法 * @param args:方法的参数 * @return * @throws Throwable * 返回值:Object 方法的返回值 */ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { long startTime = System.currentTimeMillis(); System.out.println("汽车开始行使"); method.invoke(target); long endTime = System.currentTimeMillis(); System.out.println("汽车行驶结束,行驶的时间为:"+(endTime-startTime)+"毫秒"); return null; } }
測試類別:
import java.lang.reflect.InvocationHandler; import java.lang.reflect.Proxy; public class Test { public static void main(String[] args) { Car car = new Car(); InvocationHandler h = new TimeHandler(car); Class<?> cls = car.getClass(); /** * newProxyInstanced的参数 * 分别是:类加载器、实现的接口、实现的处理器 */ Moveable m = (Moveable) Proxy.newProxyInstance(cls.getClassLoader(), cls.getInterfaces(),h); m.move(); } }
這樣的輸出結果是:
汽車開始行使
汽車行駛中
汽車行駛結束,行駛的時間為:137毫秒
//後面的時間是隨機產生的,每次都不一樣
注意:
JDK代理只能代理實作了介面的類,沒有實作介面的不能代理
cglib是針對類來實現代理的,cglib的原理是對指定的目標類生成一個子類,並覆蓋其中方法實現增強,但因為採用的是繼承,所以不能對final修飾的類進行代理,因為小應學長自己對這一塊也沒完全掌握,這裡就不多講解,大家可以參考其他部落客的技術文章。
以上是Java代理模式實例程式碼分析的詳細內容。更多資訊請關注PHP中文網其他相關文章!