`
squll369
  • 浏览: 106789 次
  • 性别: Icon_minigender_1
  • 来自: 苏州
社区版块
存档分类
最新评论

代理模式(Proxy)笔记

阅读更多

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

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics