代理设计模式

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();
	}
}
从JDK1.3以后,java引入动态代理机制,java的动态代理只能针对接口进行动态代理,即要实现动态代理的类必须实现接口,CGLIB提供了针对类的动态代理功能。JDK动态代理的例子如下:

demo1:

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * 代理接口
 * @author jacky
 *
 */
interface Foo{
	public void f(String s);
	public void g(int i);
	public void h(int i, String s);
}

/**
 * 接口实现类,即被代理类
 * @author jacky
 *
 */
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);
	}
} 


/**
 * 动态代理处理类
 * @author jacky
 *
 */
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);
	  		try {
				method.invoke(this.delegate, args);
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} 
	  		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(2, "h");
	}
}

demo2:

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.*;

/**
 * 接口
 * @author jacky
 *
 */
interface Person {     
         
    String getName();     
         
    String getGender();     
         
    void setName(String name);     
         
    void setGender(String gender);     
         
    void setRate(int rate);     
         
    int getRate();     
}   

/**
 * 接口实现类,被代理类
 * @author jacky
 *
 */
class PersonImpl implements Person {     
String name;     
    
String gender;     
    
String interests;     
    
int rate;     
    
public String getName() {     
    return name;     
}     
    
public void setName(String name) {     
    this.name = name;     
}     
    
public String getGender() {     
    return gender;     
}     
    
public void setGender(String gender) {     
    this.gender = gender;     
}     
    
public String getInterests() {     
    return interests;     
}     
    
public void setInterests(String interests) {     
    this.interests = interests;     
}     
    
public int getRate() {     
    return rate;     
}     
    
public void setRate(int rate) {     
    this.rate = rate;     
}   
}

/**
 * 动态代理处理类
 * @author jacky
 *
 */
class OwnerInvocationHandler implements InvocationHandler{     
    
    private Person personBean;     
         
    public OwnerInvocationHandler(Person personBean){     
        this.personBean = personBean;     
    }     
         
    public Object invoke(Object proxy, Method method, Object[] args)     
            throws IllegalAccessException {     
             
        try {     
            if(method.getName().startsWith("get")){//如果方法名为get,就调用person类内的get相应方法     
    
                return method.invoke(personBean, args);     
            }else if(method.getName().equals("setRate")){ // 如果方法是setRate,则抛出异常     
                throw new IllegalAccessException("access deny");     
            }else if(method.getName().startsWith("set")){  //如果为set,就调用person类内的set相应方法     
                return method.invoke(personBean, args);     
            }else {     
                System.out.println("non method invoke");     
            }     
        } catch (InvocationTargetException e) {     
            e.printStackTrace();     
        }     
        return null;      
             
    }     
         
}    

/**
 * 动态代理处理类
 * @author jacky
 *
 */
class NonInvocationHandler implements InvocationHandler{     
    //     
    private Person person;     
         
    public NonInvocationHandler(Person person){     
        this.person = person;     
    }     
    
    public Object invoke(Object proxy, Method method, Object[] args)     
            throws Throwable {     
        if(method.getName().startsWith("setRate")){     
            return method.invoke(person, args);     
        }else if (method.getName().startsWith("get")){     
            return method.invoke(person, args);     
        } else {     
            System.out.println("non method invoke");     
            return null;     
        }     
    }     
         
}   

/**
 * 主类
 * @author jacky
 *
 */
public class MyDynamicProxy {     
    
public Person getOwnerPersonBeanProxy(Person person){     
    return (Person)Proxy.newProxyInstance(person.getClass().getClassLoader(),      
            person.getClass().getInterfaces(), new OwnerInvocationHandler(person));     
}     
    
public Person getNonPersonBeanProxy(Person person){     
    return (Person)Proxy.newProxyInstance(person.getClass().getClassLoader(),      
            person.getClass().getInterfaces(), new NonInvocationHandler(person));     
}     
    
public static void main(String[] args) {     
    MyDynamicProxy mdp = new MyDynamicProxy();     
    mdp.test();     
         
}     
    
public void test(){     
    Person person = getPersonBeanFromDB1();     
    Person personProxy = getOwnerPersonBeanProxy(person);     
    System.out.println(personProxy.getName());      
    try {     
        personProxy.setRate(2);     
    } catch (Exception e) {     
        System.out.println("can not setRate");     
    }     
    Person person1 = getPersonBeanFromDB1();     
    Person personProxy2 = getNonPersonBeanProxy(person1);     
    System.out.println(personProxy2.getName());     
    personProxy2.setRate(2);     
    System.out.println(personProxy2.getRate());     
}     
    
/**
 * 返回接口实现类
 * @return
 */
private Person getPersonBeanFromDB1(){     
    Person pb = new PersonImpl();     
    pb.setName("remy");     
    pb.setGender("girl");     
    pb.setRate(1);     
    return pb;     
}  
}

动态代理和普通的代理模式的区别:动态代理中的代理类是由java.lang.reflect.Proxy类在运行期时根据接口定义,采用Java反射功能动态生成的。和java.lang.reflect.InvocationHandler结合,可以加强现有类的方法实现。动态带来自定义Handler实现InvocationHandler接口,自定义Handler实例化时,将代理的实现类传入自定义Handler对象中。自定义Handler需要实现invoke方法,该方法可以使用Java反射调用实现类的实现的方法,同时当然可以实现其他功能,例如在调用实现类方法前后加入Log,实现安全认证等。而Proxy类根据Handler和需要代理的接口动态生成一个接口实现类的对象。当用户调用这个动态生成的实现类时,实际上是调用了自定义Handler的invoke方法。

JDK中代理模式的应用:

JDK动态代理.

RMI.

参考:http://developer.51cto.com/art/201104/253625.htm


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值