zoukankan      html  css  js  c++  java
  • 代理模式

    1.代理模式的基本介绍:

      1.代理模式:为一个对象提供一个替身来控制对这个对象(被代理的对象)的访问。也就是通过代理对象来访问目标对象(间接访问目标对象),这样的好处就是可以在目标对象实现的基础上,增强额外的功能操作,即扩展目标对象的功能

      2.被代理的对象可以是远程对象创建开销大的对象或者需要安全控制的对象。

      3.形式:静态代理动态代理(JDK代理、接口代理)Cglib代理(可在内存中动态创建对象,而不需要实现接口,它是属于动态代理的范畴)。

      4.代理模式的示意图

      Client调用TargetObject是通过ProxyObject来实现的,这就是代理

    =========================================================================================================================================

    2.代理模式的分类

      1.静态代理

        1.基本介绍:

          静态代理在使用时,需要定义接口或者父类,被代理对象(目标对象)与代理对象一起实现相同的接口或者继承相同的父类。

        2.应用实例

          1.具体要求:

            1.定义一个接口:ITeacherDao

            2.目标对象TeacherDao实现ITeacherDao接口

            3.使用静态代理方式,那么代理对象TeacherProxy也需要实现ITeacherDao接口

            4.调用的时候通过调用代理对象的方法来调用目标对象

            5.代理对象与目标对象要实现相同的接口,然后通过调用相同的方法来调用目标对象的方法

          2.类图:

            

           3.代码:

    1.ITeacherDao接口                                       2.目标对象代码                                             3.代理对象代码

     

     4.客户端调用

           4.代理对象的优缺点

             

    =========================================================================================================================================

      2.动态代理

        1.基本介绍

        

         2.JDK中生成动态代理的API

        

         3.动态代理应用实例

          1.类图:

              

             getProxyInstance():

              1.根据传入的目标对象(TeacherDao)

              2.利用反射机制,返回一个代理对象

              3.然后通过代理对象,调用目标对象的方法

                2.代码:          

    package com.atguigu.proxy.dynamic
    
    //接口
    public interface ITeacherDao{
        void teach();    //授课的方法
    }
    package com.atguigu.proxy.dynamic
    //目标对象
    public class TeacherDao implements ITeacherDao{
        public void teache(){
            System.out.print("老师授课。。。。");
        }
    }
    package com.atguigu.proxy.dynamic;
    
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    
    public class ProxyFactory {
    
        //维护一个目标对象,Object
        private Object target;
        
        //初始化target
        public ProxyFactory(Object target){
            this.target = target;
        }
        
        //给目标对象生成一个代理对象
        public Object getProxyInstance(){
            
            //说明:
            
            /* public static Object newProxyInstance(ClassLoader loader,
                     Class<?>[] interfaces,
                   InvocationHandler h)*/
            /*
             * 1.ClassLoader loader:指定当前目标对象使用的类加载器,获取类加载器的方法固定
             * 2.Class<?>[] interfaces: 目标对象实现的接口类型,使用泛型确定类型
             * 3.InvocationHandler h: 事件处理,执行目标对象的方法时,会触发事件处理方法,会
             * 把当前执行的目标对象方法作为参数传入
             */
            return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), new InvocationHandler() {
                
                @Override
                public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                    System.out.print("JDK代理开始。。。");
                    //反射机制调用目标对象的方法
                    Object returnVal = method.invoke(target, args);
                    return returnVal;
                }
            });
        }
        
    }
    package com.atguigu.proxy.dynamic;
    
    public class Client {
    
        public static void main(String[] args) {
            //创建目标对象
            ITeacherDao target = new TeacherDao();
            
            //给目标对象创建代理对象,可以转成ITeacherDao
            ITeacherDao  proxyInstance =(ITeacherDao)new ProxyFactory(target).getProxyInstance();
            
            //proxyInstance=class com.sun.proxy.$Proxy0:内存中动态生成了代理对象
            System.out.println("proxyInstance" + proxyInstance);
            
            //通过代理对象,调用目标对象的方法
            proxyInstance.teach();
        }
    }

    =========================================================================================================================================

    3.Cglib代理

      1.基本介绍

      

      2.实现步骤

       

      3.类图

       4.代码

    1.TeacherDao.java

    package com.atguigu.proxy.cglib;
    
    public class TeacherDao {
    
        public void teach(){
            System.out.println("老师授课中。。。我是cglib代理,不需要实现接口");
        }
    }

    2.ProxyFactory.java

    package com.atguigu.proxy.cglib;
    
    import java.lang.reflect.Method;
    
    import net.sf.cglib.proxy.Enhancer;
    import net.sf.cglib.proxy.MethodInterceptor;
    import net.sf.cglib.proxy.MethodProxy;
    
    public class ProxyFactory implements MethodInterceptor {
    
        // 维护一个目标对象
        private Object target;
    
        // 传入一个被代理的对象
        public ProxyFactory(Object target) {
            this.target = target;
        }
    
        // 返回一个代理对象,是target对象的代理对象
        public Object getProxyInstance() {
    
            // 1. 创建一个工具类
            Enhancer enhancer = new Enhancer();
            // 2. 设置父类
            enhancer.setSuperclass(target.getClass());
            // 3. 设置回调函数
            enhancer.setCallback(this);
            // 4. 创建子类对象,即代理对象
            return enhancer.create();
    
        }
    
        // 重写 intercept 方法,调用目标对象的方法时会触发该方法的调用,从而调用目标对象的方法
        @Override
        public Object intercept(Object arg0, Method method, Object[] args, MethodProxy arg3) throws Throwable {
            // TODO Auto-generated method stub
            System.out.println("Cglib代理模式 ~~ 开始");
            Object returnVal = method.invoke(target, args);
            System.out.println("Cglib代理模式 ~~ 提交");
            return returnVal;
        }
    
    }

    3.Client.java

    package com.atguigu.proxy.cglib;
    
    public class Client {
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            // 创建目标对象
            TeacherDao target = new TeacherDao();
            // 获取到代理对象,并且将目标对象传递给代理对象
            TeacherDao proxyInstance = (TeacherDao) new ProxyFactory(target).getProxyInstance();
    
            // 执行代理对象的方法,触发intecept 方法,从而实现 对目标对象的调用
            proxyInstance.teach();
        }
    }

    =========================================================================================================================================

    4.代理模式的变体

    //目标对象
    你还有很多未完成的梦,你有什么理由停下脚步
  • 相关阅读:
    APP Https双向认证抓包
    剖析XSS
    php连接mysql
    linux去掉某一字符开头的行
    memcached+php客户端
    memcached-repcached
    memcached+memadmin
    Linux GPT分区
    Linux查看文件夹大小
    linux挂载windwos共享文件
  • 原文地址:https://www.cnblogs.com/quanziheng/p/13306714.html
Copyright © 2011-2022 走看看