代理模式主要是为其他对象提供一种代理,在代理中实现额外的处理和操作,而不需更改原型接口的方法。
实现过程:
委托类和代理类都实现共同的接口,然后将委托类传递给代理类,实现更多的处理。
1.静态代理:
代理和委托类是一一对应的,对于每个委托类都有响应的代理对应。
公共接口:
/**
* 公共接口
*/
public interface BookInterface {
public void addBook();
}
委托类:
/**
* 委托类
*/
public class BookImp implements BookInterface {
@Override
public void addBook() {
// TODO Auto-generated method stub
System.out.println("Imp");
}
}
代理类:
/**
* 代理类
*/
public class ProxyBook implements BookInterface {
private BookInterface inter;
/** 传递接口 **/
public ProxyBook(BookInterface inter) {
this.inter = inter;
}
// 扩展接口的方法,提供额外的操作
@Override
public void addBook() {
// TODO Auto-generated method stub
doBefore();
inter.addBook();
doAfter();
}
public void doBefore() {
System.out.println("do before");
}
public void doAfter() {
System.out.println("do after");
}
}
客户端调用:
public static void main(String[] args) {
BookImp imp = new BookImp();
//将对象传递给代理类
ProxyBook proxyBook = new ProxyBook(imp);
proxyBook.addBook();
}
2.动态代理:
代理类中属性是Object,因此可以代理Object类的子类。代理中传递的是接口列表,就当实现了这些接口,从而实现了一对多的代理。
InvocationHandler:
InvocationHandler接口在java.lang.reflec下,是代理实例的调用处理程序实现的接口。每个代理实例都具有一个关联的调用处理程序,将对方法调用进行编码并将其指派到它的调用处理程序的invoke方法。
Object invoke(Object proxy, Method method, Object[] args)
这个接口有三个参数,一个是代理的实例,一个是被拦截的方法,一个是该方法的参数列表。
Proxy:
动态代理类是一个实现在创建类时在运行时指定的接口列表的类。
Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)
三个参数分别为:加载类的对象(类加载器),要实现的接口数组,代理实例的接口。
代理类:
/**
* 代理类
*/
public class BookProxy implements InvocationHandler {
private Object object;
public BookProxy(Object object) {
this.object = object;
}
/**
* 额外的处理和操作
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
// TODO Auto-generated method stub
doBefore();
Object result = method.invoke(object, args);
doAfter();
return result;
}
private void doBefore() {
System.out.println("do before");
};
private void doAfter() {
System.out.println("do after");
};
}
客户端调用:
public static void main(String[] args) {
BookImp imp = new BookImp();
BookProxy pro = new BookProxy(imp);
// 动态代理,参数分别为:代理类的类加载器, 代理类要实现的接口列表, 指派方法的调用处理程序
BookInterface inter = (BookInterface) Proxy.newProxyInstance(imp
.getClass().getClassLoader(), imp.getClass().getInterfaces(),
pro);
inter.addBook();
}
运行结果: