代理模式

定义

为其他对象提供一种代理以控制对这个对象的访问

作用

为真实类提供角色预处理消息、过滤消息、消息转发、时候消息处理;
比如 : 虚代理 , 远程代理 , 写时复制 , Cache代理 , 防火墙代理 , 同步代理 , 智能指引 ,保护代理 。

常用结构

  • Subject :目标接口。
  • RealSubject : 具体的目标对象
  • Proxy : 代理对象

实现方式

java中代理分为 静态代理 和 动态代理 , 这里重点讲动态代理 。
java中的动态代理,通过java的反射机制 和动态生成class的技术实现。代码如下 :

//动态代理类
public class DynamicProxy implements InvocationHandler{
    //主题的接口
    private Subject subject = null;

    //日志记录
    private final static Logger logger = LoggerFactory.getLogger(DynamicProxy.class);
    /*
    *绑定具体目标和接口
    *@param  RealSubject  具体目标,即实现类
    *@return  Subject      目标接口
    */
    public Subject getProxyInterface(RealSubject real){
      //将具体目标绑定到接口上
      this.subject = real ; 
      //将动态代理和具体目标绑定
      Subject subjectProxy = (Subject) Proxy.newProxyInstance(
          real.getClass().getClassLoader(),
          real.getClass().getInterface(),
          this
        );
        return  subjectProxy;
    }   

    public  Object invoke(Object proxy,Method method,Object[] args) throws Throwable{

        if(method.getName().equals(".."))
        {
            ...//相关处理
            subject.***
            //动态调用目标的方法
            return method.invoke(subject,args);
        }else{
            ***//相关处理return null;
    } 
}


客户端调用:
public class Clientpublic static void main(String[] args){

        RealSubject real = ***** //实例化
        DynamicProxy proxy = new DynamicProxy();
        //realSubject现在是动态代理类了
        Subject realSubject = proxy.getProxyInterface(real); 
        realSubject.***  //调用相关方法 

    }
}

通过代理类 ,彻底将接口的变化隔离了出去,当接口Subject发生变化的时候,动态代理类不需要关心,避免了静态代理的缺陷,但是,java自带的动态代理还必须知道接口的存在,接口Subject必须存在,在实际项目中,应当避免这种约束,可以使用cglib的代码生成库。


//动态代理类
public class ProxyCglib implements MethodInterceptor{
    //主题的接口
    private Subject subject = null;

    //日志记录
    private final static Logger logger = LoggerFactory.getLogger(ProxyCglib.class);
    /*
    *绑定具体目标和接口
    *@param  RealSubject  具体目标,即实现类
    *@return  Subject      目标接口
    */
    public Subject getProxyInstance(RealSubject real){
      //将具体目标绑定到接口上
      this.subject = real ; 
      //将动态代理和具体目标绑定
      Enhancer enhancer = new Enhancer();
      enhancer.setSuperclass(this.subject.getClass());
      enhancer.setCallback(this); 
      return  (RealSubject)enhancer.create();
    }   

    public  Object intercept(Object obj,Method method,Object[] args,MethodProxy proxy) throws Throwable{

        if(method.getName().equals(".."))
        {
            ...//相关处理

            //动态调用目标的方法
            return proxy.invokeSuper(obj,args);
            //或者
            proxy.invokeSuper(obj,args);
            return ;
        }else{
            ***//相关处理return null;
    } 
}


客户端调用:
public class Clientpublic static void main(String[] args){

        RealSubject real = ***** //实例化
        ProxyCglib proxy = new ProxyCglib();
        //realSubject现在是动态代理类了
        Subject realSubject = (realSubject)proxy.getInstance(real); 
        realSubject.***  //调用相关方法 

    }
}

通过cglib,就可以避免接口的一定存在的问题。
更对cglib的介绍
百度文库
博文stone2083
SourceForge下载

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值