我对代理模式的理解就是,对于类中的方法进行拦截的一种方式,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!