1. 程式人生 > 實用技巧 >【動態代理】增強代理方法、代理多種方法

【動態代理】增強代理方法、代理多種方法


/**
 * @Author: chenfuxian
 * @Date: 2020/7/27 22:22
 * 對Collection介面進行代理,以前的remove(Object obj)方法是刪除集合中第一次出現的元素
 * (比如集合中有多個“abc”,呼叫remove(“abc”)後只會刪除一個元素)。代理後,要求在呼叫remove(Object obj)方法後,
 * 能夠刪除集合中所有匹配的元素。Collectionde 的toString方法。【動態代理】
 */
public class Test04 {
public static void
main(String[] args) { Collection<String> collection = new ArrayList<>(); collection.add("abc"); collection.add("bac"); collection.add("abc"); collection.add("cba"); collection.add("abc"); collection.add("abc"); System.out.println(collection); Class
<? extends Collection> collectionClass = collection.getClass(); Collection proxy = (Collection)Proxy.newProxyInstance(collectionClass.getClassLoader(), collectionClass.getInterfaces(), new InvocationHandler() { /*引數1:ClassLoader loader 被代理物件的類載入器 引數2:Class<?>[] interfaces 被代理物件的要實現的介面 引數3:InvocationHandler h (介面)執行處理類。Proxy的介面,用於new代理物件。 返回值: 代理物件。proxy
*/ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { /* 呼叫代理類的任何方法,此方法都會執行 - 引數1:代理物件(慎用)。invoke方法內用會進入死迴圈。 - 引數2:當前執行的方法。指代理proxy呼叫的方法。 - 引數3:當前執行的方法執行時傳遞過來的引數。實參。 - 返回值:當前方法執行的返回值*/ //public Object invoke(Object obj, Object... args),可變引數可以傳入陣列args。 //返回值為超類Object,避免代理proxy呼叫不同方法的返回值型別不一樣而報錯。 Object res = method.invoke(collection,args); //if中為增強方法,可用於某個方法的增強;判斷方法是否為remove,iterator刪除集合中所有"abc"元素 if (method.getName().equals("remove")) { Iterator<String> it = collection.iterator(); while (it.hasNext()) { String next = (String) it.next(); if (next.equals(args[0])){ it.remove(); } } } return res; } }); boolean b = proxy.remove("abc"); System.out.println(collection); String s = proxy.toString(); System.out.println(s); } }