【动态代理】增强代理方法、代理多种方法


/**
 * @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);

    }
}

 

posted @ 2020-07-28 18:09  炼金术士0z  阅读(421)  评论(0编辑  收藏  举报