设计模式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。 对象