設計模式之動態代理模式
阿新 • • 發佈:2018-08-12
傳遞 api inter 服務 輸出 main 編程) 創建 實現
學習動態代理模式是為了以後學習AOP(面向切面編程)打下基礎,他比裝飾者模式還要靈活。
我們只學習他的一個方法:
Proxy.newProxyInstance(ClassLoader classLoader, Class[] interfaces, InvocationHandler invocationHandler);
作用:在運行時,動態創建一組指定的接口的實現類對象。
三個參數分別是:
1. ClassLoader classLoader:類加載器
2.Class[] interfaces:指定要實現的接口
3.InvocationHandler invocationHandler:調用處理器,這是個接口
查看API得知有一個方法:
public Object invoke(Object proxy, Method method, Object[] args);
interface A { void a(); Object aa(String x); } interface B { void b(); } public class Demo1 { public static void main(String[] args) { donttai(); } private static void donttai() {//通過目標對象得到類加載器
Demo1 d=new Demo1(); ClassLoader classLoader = d.getClass().getClassLoader(); InvocationHandler invocationHandler = new InvocationHandler() { public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("動態代理有點難"); return "aaa"; } }; //使用三大參數創建代理對象 Object o = Proxy.newProxyInstance(classLoader, new Class[]{A.class, B.class}, invocationHandler); A a = (A) o; B b = (B) o; a.a(); b.b(); 輸出:動態代理有點難 動態代理有點難 a被傳遞給了proxy這個參數,aa傳遞給了method參數,括號中的內容傳遞給了args1 Object aaa = a.aa("hello"); System.out.println(aaa); 輸出:動態代理有點難 由此可得:代理對象實現的所有接口中的方法,內容都是調用InvocationHandler的invoke()方法
例子
public interface Waiter { //這個waiter可以服務別人 void service(); } public class ManWaiter implements Waiter { public void service() { System.out.println("服務周到"); } } public class Demo1 { public static void main(String[] args) { getOne(); } private static void getOne() { //manWaiter就是一個目標對象(需要被增強的) Waiter manWaiter = new ManWaiter(); //通過目標對象得到類加載器 ClassLoader classLoader = manWaiter.getClass().getClassLoader();
//需要被實現的接口 Class[] interfaces = new Class[]{Waiter.class}; InvocationHandler invocationHandler = new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("你好"); manWaiter.service(); System.out.println("再見"); return null; } }; //得到一個代理對象,代理對象就是在目標對象的基礎上進行增強的對象 Waiter waiterProxy = (Waiter) Proxy.newProxyInstance(classLoader, interfaces, invocationHandler); //在調用代理對象的時候,在前面添加“你好”,後面添加“再見”, //因為需要一個目標對象,所以需要自己傳一個 waiterProxy.service(); } } 輸出: 你好 服務周到 再見
設計模式之動態代理模式