設計模式3——Proxy設計模式

Proxy代理設計模式是一種控制對象訪問的設計模式,相似於網絡代理,網絡代理機制以下圖: java

Proxy代理設計模式機制以下: 設計模式

代理模式UML圖以下: 安全

代理模式順序圖以下: 網絡


客戶端程序經過代理程序來訪問真正的目標程序,代理程序對外隱藏了目標程序。普通代理設計模式例子代碼以下: this

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動態代理的例子以下: spa

//代理接口
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);
	}
}

動態代理和普通的代理模式的區別:動態代理中的代理類是由java.lang.reflect.Proxy類在運行期時根據接口定義,採用Java反射功能動態生成的。和java.lang.reflect.InvocationHandler結合,能夠增強現有類的方法實現。動態帶來自定義Handler實現InvocationHandler接口,自定義Handler實例化時,將代理的實現類傳入自定義Handler對象中。自定義Handler須要實現invoke方法,該方法能夠使用Java反射調用實現類的實現的方法,同時固然能夠實現其餘功能,例如在調用實現類方法先後加入Log,實現安全認證等。而Proxy類根據Handler和須要代理的接口動態生成一個接口實現類的對象。當用戶調用這個動態生成的實現類時,其實是調用了自定義Handler的invoke方法。 設計


JDK中代理模式的應用: 代理

JDK動態代理; code

RMI。 對象

相關文章
相關標籤/搜索