*
代理模式(英语:Proxy Pattern)是程序设计中的一种设计模式。
所谓的代理者是指一个类可以作为其它东西的接口。代理者可以作任何东西的接口:网络连接、内存中的大对象、文件或其它昂贵或无法复制的资源。----WIKIPEDIA
个人理解
代理模式就是找另外的一个对象作为代理去为你实施请求,代理模式分为两种,一种是静态代理模式,另外一种是动态代理模式,静态代理模式是代理类为其创建一个对象,将需要代理的类的对象赋予代理类中的该对象,让代理类中该对象去代替需要代理的类的对象去执行一定的任务。动态代理模式采用JDK的动态代理,根据其类加载器以及其实现的接口生成代理对象,通过反射机制实现动态代理。
静态代理
假设这样的一个情景,文件都有打开的接口的,那么打开一个PDF文件的话,我这里可不可以使用代理模式去处理这样的一个情景呢,接下来设计了一个类图:
通过静态代理模式,PDFProxy对象作为PDFFile的代理对象,然后执行交给他的任务。
主要的代码(这里只贴出代理类的代码,全部代码:设计模式代码下载地址):
public class PDFProxy implements File{
private File file = null;
@Override
public void openFile() {
if(file == null){
file = new PDFFile();
}
file.openFile();
}
}
在测试类中进行调用的时候:
PDFProxy proxy = new PDFProxy();
proxy.openFile();
直接通过PDFProxy对象来调用需要被代理的对象的方法,当然,这两者需要实现同样的接口,这样在进行调用的时候可以保证代理类中的方法与被代理的对象中的方法保持一致。
动态代理
使用JDK的动态代理,这里需要几个参数,类加载器、接口和代理实例的调用处理类的实例。
代理类的代码如下:
public class PDFProxy {
public static Object getProxy(final Object obj){
return Proxy.newProxyInstance(obj.getClass().getClassLoader()
, obj.getClass().getInterfaces(), new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
method.invoke(obj, args);
return null;
}
});
}
}
在测试类中直接通过类名进行调用即可,上面的方法中之所以将obj声明为final是因为在内部匿名类中想访问外部的数据就需要将其设为final类型。采用JDK动态代理的前提是确定该类有实现接口,没有实现接口那就没办法产生代理对象了,代理模式还有CGLib方式去创建,他是采用继承,为目标类生成子类去覆盖目标方法实现增强。
同时代理模式再之前的博文中有所涉及,可以参考博文: Hibernate与代理模式