代理模式是在不改变源码的情况下增加已有方法的功能。要使用代理模式的前提是:被代理的类实现了一个接口。代理模式分为静态代理模式与动态代理模式。
静态代理模式:
只是在实现与被代理类相同的接口,在代理对象力穿一个被代理类的对象。具体实现如下代码:
class ProxyList implements List<String>{
List<String> target;
public ProxyList(List<String> target) {
this.target = target;
}
@Override
public boolean add(String e) {
Thread t = Thread.currentThread();
System.out.println("线程"+t.getName()+"调用add");
return target.add(e);
}
@Override
public void add(int index, String element) {
// TODO Auto-generated method stub
}
@Override
public boolean addAll(Collection<? extends String> c) {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean addAll(int index, Collection<? extends String> c) {
// TODO Auto-generated method stub
return false;
}
@Override
public void clear() {
// TODO Auto-generated method stub
}
@Override
public boolean contains(Object o) {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean containsAll(Collection<?> c) {
// TODO Auto-generated method stub
return false;
}
@Override
public String get(int index) {
// TODO Auto-generated method stub
return null;
}
@Override
public int indexOf(Object o) {
// TODO Auto-generated method stub
return 0;
}
@Override
public boolean isEmpty() {
// TODO Auto-generated method stub
return false;
}
@Override
public Iterator<String> iterator() {
// TODO Auto-generated method stub
return null;
}
@Override
public int lastIndexOf(Object o) {
// TODO Auto-generated method stub
return 0;
}
@Override
public ListIterator<String> listIterator() {
// TODO Auto-generated method stub
return null;
}
@Override
public ListIterator<String> listIterator(int index) {
// TODO Auto-generated method stub
return null;
}
@Override
public boolean remove(Object o) {
// TODO Auto-generated method stub
return false;
}
@Override
public String remove(int index) {
// TODO Auto-generated method stub
return null;
}
@Override
public boolean removeAll(Collection<?> c) {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean retainAll(Collection<?> c) {
// TODO Auto-generated method stub
return false;
}
@Override
public String set(int index, String element) {
// TODO Auto-generated method stub
return null;
}
@Override
public int size() {
// TODO Auto-generated method stub
return 0;
}
@Override
public List<String> subList(int fromIndex, int toIndex) {
// TODO Auto-generated method stub
return null;
}
@Override
public Object[] toArray() {
// TODO Auto-generated method stub
return null;
}
@Override
public <T> T[] toArray(T[] a) {
// TODO Auto-generated method stub
return null;
}
}
上面的代码是list集合的一个静态代理类,在这个类力只是实现了一个add方法,其他方法只要增加一定的功能和调用target对象相应的方法就可以。
动态代理:
java 提供了动态代理API:
1 底层是利用反射实现的功能
2 java 提供了API Proxy,动态的继承接口(被代理类所实现的接口),实现接口中所有的方法,当方法被调用时候,将调用请求转给调用处理器处理
3 调用处理器,就可以处理所有的方法执行过程
下面代码是list集合的动态代理的实现以及与之的实现:
public List proxy(final List list){
//调用处理器
InvocationHandler handler = new InvocationHandler() {
//invoke 调用
//当有方法被调用时候执行invoke 方法,
// 参数proxy是代理对象, method正在执行的方法, args是调用方法传递的参数
// 返回值是方法执行的结果
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
Thread t = Thread.currentThread();
System.out.println("线程"+t.getName()+"调用"+method.getName());
//根据业务规则决定是否执行 被代理方法 method.invoke(list, args);
//在这里可以添加业务逻辑
//if(没有授权) throw 权限不够异常
//if(没有登陆) throw 需要登陆异常
//方法调用之前的 可以添加逻辑
Object val = method.invoke(list, args);
//方法调用之后的 可以添加逻辑
// 返回值太大 超过范围,抛出权限不够 。。。
return val;
}
};
/*
* 创建代理类对象
* Proxy.newProxyInstance 根据接口 getClass.getClassLoader:获取一个类加载器(任何一个类加载器都可以),
* new Class[]{List.class}:必须是接口 , handler :将一个处理器传给代理类,以便在代理类中调用handler中的invoke方法。
* List.class 创建对象,也就是实现了接口的全部方法
* 当调用了这些方法时候,就会执行 调用处理器中的 invoke方法,并且当前方法作为参数 method
* 传递给 invoke 方法,在invoke方法可以利用 method.invoke()执行方法。
*/
List proxy = (List) Proxy.newProxyInstance(getClass().getClassLoader(),
new Class[]{List.class}, handler);
return proxy;
}
}
测试代理类对象的方法:
public void testProxy3(){
List<String> list = new ArrayList<String>();
list = proxy(list);
list.add("Tom");
list.add("Jerry");
list.remove("Tom");
}
代理模式的图片分析: