zoukankan      html  css  js  c++  java
  • 设计模式之----代理模式

    代理模式

    1. 什么是代理模式?
      代理模式是GoF四人组提出的23种设计模式之一。
      若一个类T不能或不适合让另外一个类C直接访问,或者,类T在不修改自身源码的前提下,想增强业务逻辑功能,
      此时,就可以通过一个中间类P来完成这些需求。那么,这个中间类P就称为代理类,而类T则称为目标类。
      换个角度思考,那就是说,客户类C若想与目标类T打交道,那么都需要通过代理类P来完成。即客户类只能与代理
      类P发生直接的联系。代理类P的对象可以代表目标类T与客户类打交道。

      

    2. 代理模式中的角色
      目标类  代理类  客户类

    3. 代理模式的目的
      1)为了保护和隐藏某一个类,可以使用代理模式
      2)在不修改某个类的源码的前提下,为了增强某个类的功能,可以使用代理模式

    4. 代理模式的分类
      根据代理类创建的时间的不同,或者说,根据代理关系确立的时机的不同,可以将代理模式分为两类
      1)静态代理
      2)动态代理
      动态代理又根据实现技术的不同,可以分为若干类,例如:
      1)JDK的动态代理: 

        原理:  Proxy底层利用接口创建了代理类对象,  当内存中已经有时,会创建一个副本,,  自定义类为委托类....  

        使用要求:.有接口才能使用代理 
          ①自定义类实现(实现委托类), 需实现InvocationHandler 接口实现委托功能(对方法进行挑选过滤增强)

     1//创建委托类
     3 import java.lang.reflect.InvocationHandler;
     4 import java.lang.reflect.Method;
     5         //    jdk自带的proxy委托需实现InvocationHandler接口
     6 public class BookProxy implements InvocationHandler {
     7     private BookDao bookDao;//目标类对象
     8     public BookProxy(BookDao bookDao) {
     9         super();
    10         this.bookDao = bookDao;
    11     }
    12     //    proxy 代理类(一般不用,使用错误会导致死循环)
    13     // Method 方法(反射中的方法对象)
    14     // args  传参
    15     @Override
    16     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    17         // TODO Auto-generated method stub
    18         if (method.getName().equals("insert")) {
    19             //使用实现类对象用反射调用方法
    20             Object invoke = method.invoke(bookDao,args);
    21             return invoke;
    22         }
    23         return null;
    24     }
    25 }

        ②main方法中使用Proxy.newProxyInstance方法获取代理类

    public class Demo {
    public static void main(String[] args) {
        IbookDao instance = (IbookDao)Proxy.newProxyInstance(    //返回值为一个代理类对象  (强转为接口)
                                                Demo.class.getClassLoader(),    //目标类的类加载器
                                                BookDao.class.getInterfaces(), //目标类的实现接口
                                                new BookProxy(new BookDao()));//委托类对象
        instance.insert();                //调用接口中的方法,(实现类中的方法)
    }
    }

      ③目标类中实现接口

    public class BookDao implements IbookDao {
      .....//实现IbookDao中的方法  
    }

      2)CGLIB动态代理:  

        原理 :底层创建一个实现类的子类对象

       使用要求: 导入cglib包

          ①:自定义类(实现委托类).  实现MethodInterceptor接口(此接口实现了callback回调接口,标识作用)

    public class Cglib implements MethodInterceptor{
        private BookDao book;    //目标类对象
        public Cglib(BookDao book) {
            super();
            this.book = book;
        }
            //obj代理类对象
            // method    反射方法
            //    args 参数
            // proxy    实现方法的代理类对象
        @Override
        public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
            // TODO Auto-generated method stub
                     method.invoke(book, args);
                     return null;
        }
    }

        ②main调用    需自己创建调用类对象及方法

    public class Demo {
    public static void main(String[] args) {
        BookDao book= new BookDao();    //目标类
        Cglib cglib = new Cglib(book);    //委托类
                              //此类需要自己创建    
        BookDao bookDao = (BookDao)CreateProxy.newProxyInstance(  //返回值即为目标类的子类对象
                                                BookDao.class,     //实现类的字节码文件对象
                                                    cglib);    //委托类对象
        bookDao.delet();
        }
    }

        ③创建调用类,与方法..方法名与Proxy中的一样

    public class CreateProxy {
        public static Object newProxyInstance(Class class1, MethodInterceptor cglib) {
            //新建增强器对象
            Enhancer enhancer = new Enhancer();
            //设置父类,,,即目标类
            enhancer.setSuperclass(class1);
            //设置委托类
            enhancer.setCallback(cglib);
            //创建并返回
            return enhancer.create();
        }
    }

       


      3)Javassist动态代理

        ............

     

  • 相关阅读:
    尝试使用word发布博客
    设计模式学习系列7 建造者模式
    设计模式学习系列6 原型模式(prototype)
    最近比较闲
    提高程序运行效率的10个简单方法(转)
    设计模式学习系列5 工厂模式
    【LINUX/UNIX网络编程】之使用消息队列,信号量和命名管道实现的多进程服务器(多人群聊系统)
    三十分钟掌握STL
    在python包管理中使用easy_install软件的步骤
    【转】推荐给大家的7本游戏开发书
  • 原文地址:https://www.cnblogs.com/x-ph/p/7435123.html
Copyright © 2011-2022 走看看