我对代理模式的理解就是,对于类中的方法进行拦截的一种方式,Spring的AOP就是靠这个模式玩的。
下面纪录一个例子,对ArrayList代理,要求是对于ArrayList的add方法进行处理,在add执行前,打印一个信息,add执行后,打印add的元素的内容,最后打印add完成的信息.
定义一个ArrayListProxy的代理类, 引用一个ArrayList的实例, 然后利用这个实例去复写ArrayList所有的方法,对其中的add方法做一些处理.
这样以后直接用ArrayListProxy这个类,他的add方法就可以自动获得新的处理,而其他方法不变,通过这样的方式,把原来的ArrayList给代理了.
package com.design.study.proxy.list; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; public class ArrayListProxry<E> implements Collection<E> { private ArrayList<E> al = new ArrayList<E>(); public boolean add(E e) { System.out.println("Before Proxy arrayList!"); try{ System.out.println("add element:" + e); return al.add(e); }finally{ System.out.println("After Proxy arrayList!"); } } @Override public boolean addAll(Collection<? extends E> c) { return al.addAll(c); } @Override public void clear() { al.clear(); } @Override public boolean contains(Object o) { return al.contains(o); } @Override public boolean containsAll(Collection<?> c) { return al.containsAll(c); } @Override public boolean isEmpty() { return al.isEmpty(); } @Override public Iterator<E> iterator() { return al.iterator(); } @Override public boolean remove(Object o) { return al.remove(o); } @Override public boolean removeAll(Collection<?> c) { return al.remove(c); } @Override public boolean retainAll(Collection<?> c) { return al.retainAll(c); } @Override public int size() { return al.size(); } @Override public Object[] toArray() { return al.toArray(); } @Override public <T> T[] toArray(T[] a) { return al.toArray(a); } }
执行代码:
package com.design.study.proxy.list; import java.awt.Label; import java.util.Collection; public class Client { @SuppressWarnings("unchecked") public static void main(String[] args){ Collection l = new ArrayListProxry(); l.add("a"); l.add(new Label()); } }
执行结果:
Before Proxy arrayList! add element:a After Proxy arrayList! Before Proxy arrayList! add element:java.awt.Label[label0,0,0,0x0,invalid,align=left,text=] After Proxy arrayList!
不过,java的反射库里提供了一些类直接支持代理,我们可以直接利用, 下面我把上面的例子改成这样的方式,
package com.design.study.proxy.list; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.util.List; public class ArrayListProxy2<E> implements InvocationHandler{ private Object al; private ArrayListProxy2 (Object l){ this.al = l; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object o = null; if("add".equals(method.getName())){ System.out.println("Before Proxy arrayList!"); o = method.invoke(al, args); System.out.println("add element:" + ((List)proxy).get(((List)proxy).size()-1)); System.out.println("After Proxy arrayList!"); }else{ o = method.invoke(al, args); } return o; } public static Object factory(Object obj){ return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), new ArrayListProxy2(obj)); } }
通过这种方式要代理一个类,必须继承InvocationHandler接口.并实现invoke方法,通过该方法的3个参数,可以对这个类里的任何方法进行拦截处理.
Object proxy -- 被代理的对象的实例, Method method -- 被代理的对象的方法, Object[] args -- 被代理的对象的方法的参数列表
执行代码:
package com.design.study.proxy.list; import java.awt.Label; import java.util.ArrayList; import java.util.List; public class Client { @SuppressWarnings("unchecked") public static void main(String[] args){ List l2 = (List<String>)ArrayListProxy2.factory(new ArrayList()); l2.add(new Label()); l2.add("b"); l2.add("c"); l2.add("d"); l2.add("e"); l2.add(new Label()); l2.remove(0); l2.add(new Label()); } }
执行结果:
Before Proxy arrayList! add element:java.awt.Label[label0,0,0,0x0,invalid,align=left,text=] After Proxy arrayList! Before Proxy arrayList! add element:b After Proxy arrayList! Before Proxy arrayList! add element:c After Proxy arrayList! Before Proxy arrayList! add element:d After Proxy arrayList! Before Proxy arrayList! add element:e After Proxy arrayList! Before Proxy arrayList! add element:java.awt.Label[label1,0,0,0x0,invalid,align=left,text=] After Proxy arrayList! Before Proxy arrayList! add element:java.awt.Label[label2,0,0,0x0,invalid,align=left,text=] After Proxy arrayList!