Java設計模式----------代理模式
阿新 • • 發佈:2018-12-19
什麼是代理呢,就好比經紀人和演員的關係,有些事情不用演員做,經紀人就直接動手了,也就是說在不訪問被代理類的情況下去呼叫其相關方法。
Java代理分為靜態代理和動態代理
靜態代理就是和被代理類實現統一介面,然後呼叫其方法,如果我們在編譯時就知道是代理哪個物件 就可以使用靜態代理
首先建立一個介面Animal
/** * @author chunying */ public interface Animal { void eat(); void run(); }
然後是實現類Cat
/** * @author chunying */ //被代理類 public class Cat implements Animal{ @Override public void eat() { System.out.println("貓吃魚"); } @Override public void run() { System.out.println("喵喵叫"); } } 靜態代理類
/** * @author chunying */ public class StaticProxy implements Animal{ private Animal animal; public StaticProxy(Animal animal) { this.animal = animal; } @Override public void eat() { animal.eat(); } @Override public void run() { animal.run(); } }
測試
@Test public void fun3() { Cat c = new Cat(); StaticProxy staticProxy = new StaticProxy(c); staticProxy.eat(); staticProxy.run(); }
最終輸出
貓吃魚 喵喵叫
接下來看動態代理
Animal 和 Cat不變
代理物件需要實現InvocationHandler介面 實現方法invoke
/** * @author chunying */ public class MyInvocationHandler implements InvocationHandler{ private Object target; public MyInvocationHandler(Object target) { this.target = target; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { method.invoke(target, args); return null; } }
我們在執行被代理類的方法時 最終都是呼叫了這個方法,所以可以在這個類中對方法進行一些擴充套件
測試
@Test public void fun2() { Cat cat = new Cat(); Class<?>[] interfaces = cat.getClass().getInterfaces(); MyInvocationHandler myInvocationHandler = new MyInvocationHandler(cat); ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); Animal proxy = (Animal)Proxy.newProxyInstance(classLoader, interfaces, myInvocationHandler); proxy.eat(); proxy.run(); }
最終輸出是一樣的 這裡我們建立了一個代理物件,呼叫了Proxy.newProxyInstance()
這個方法有三個引數,第一個是指定的類載入器,第二個是指明被代理類實現的介面,第三個這是一個方法委託類,我們通過代理呼叫被代理類的方法時,就可以將方法名和方法引數都委託給這個委託類。
所以有了類載入器,實現的方法,代理的物件,這樣執行一個被代理類的方法就很簡單了。