Proxy代理設計模式是一種控制對象訪問的方式,類似於網絡代理,網絡代理圖如下:
Proxy代理模式如下:
代理模式UML圖如下:
客戶端程序通過代理程序來訪問真正的目標程序,代理程序對外隱藏了目標程序。普通代理設計模式例子代碼如下:
interface ProxyBase{
public void f();
public void g();
public void h();
}
//代理程序
class Proxy implement ProxyBase{
private ProxyBase implementation;
public Proxy(){
//目標程序
implementation = new ProxyImplementation();
}
public void f(){
implementation.f();
}
public void g(){
implementation.g();
}
public void h(){
implementation.h();
}
}
//目標程序
class ProxyImplementation implements ProxyBase{
public void f(){
System.out.println(“ProxyImplementation.f()”);
}
public void g(){
System.out.println(“ProxyImplementation.g()”);
}
public void h(){
System.out.println(“ProxyImplementation.h()”);
}
}
//客戶端程序調用代理
public class ProxyDemo{
public static void main(String[] args){
//客戶端調用代理程序
Proxy p = new Proxy();
p.f();
p.g();
p.h();
}
}
interface ProxyBase{
public void f();
public void g();
public void h();
}
//代理程序
class Proxy implement ProxyBase{
private ProxyBase implementation;
public Proxy(){
//目標程序
implementation = new ProxyImplementation();
}
public void f(){
implementation.f();
}
public void g(){
implementation.g();
}
public void h(){
implementation.h();
}
}
//目標程序
class ProxyImplementation implements ProxyBase{
public void f(){
System.out.println(“ProxyImplementation.f()”);
}
public void g(){
System.out.println(“ProxyImplementation.g()”);
}
public void h(){
System.out.println(“ProxyImplementation.h()”);
}
}
//客戶端程序調用代理
public class ProxyDemo{
public static void main(String[] args){
//客戶端調用代理程序
Proxy p = new Proxy();
p.f();
p.g();
p.h();
}
}
從JDK1.3以後,java引入動態代理機制,java的動態代理只能針對接口進行動態代理,即要實現動態代理的類必須實現接口,CGLIB提供了針對類的動態代理功能。JDK動態代理的例子如下:
//代理接口
interface Foo{
public void f(String s);
public void g(int i);
public void h(int i, String s);
}
//接口實現類,即被代理類
class FooImpl implements Foo{
public void f(String s){
System.out.println(“FooImpl.f(), s=” + s);
}
public void g(int i) {
System.out.println(“FooImpl.g(), i=” + i);
}
public void h(int i, String s) {
System.out.println(“FooImpl.h(), i=” + i + “, s=” + s);
}
}
//動態代理處理類
class ProxyHandler implements InvocationHandler{
//代理實現類
private Object delegate;
public ProxyHandler (Object obj) {
delegate = obj;
}
public Object invoke(Object proxy, Method method, Object[] args){
System.out.println(“Before mothod:” + method);
method.invoke(this.delegate, args);
System.out.println(“After mothod:” + method);
return null;
}
}
public class DynamicProxyDemo{
public static void main(String[] args){
Foo foo = new FooImpl();
ProxyHandler handler = new ProxyHandler(foo);
//產生動態代理
Foo proxy = (Foo)Proxy.newProxyInstance(Foo.class.getClassLoader(), new Class[]{Foo.class}, handler);
proxy.f(“f”);
proxy.g(1);
proxy.h(“h”, 2);
}
}
動態代理和普通的代理模式的區別:
動態代理中代理類是有Proxy類在運行時期根據接口定義,採用Java反射功能動態生成的。和InvocationHandler結合,可以加強現有類的方法實現。
代理模式應用的場合:
1 遠程代理,爲一個對象提供在不同的地址空間的局部代表,隱藏一個對象存在於不同的地址空間的事實。
2 虛擬代理,根據需要來創建開銷很大的對象。
3 安全代理,控制對真實對象的訪問權限
4 智能代理,調用真實對象的時候,會執行一些其他的行爲。