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

    1:代理模式定义

      为其他对象提供一种代理以控制对这个对象的访问,代理对象起到了中介作用,可去掉功能服务或者增加额外的服务。

    2:静态代理 Static Proxy

      1)继承 extends

       子类继承父类,重写其相应方法,增加额外服务,实现代理功能 

      2)聚合 implements

       与被代理的类共同实现同一个接口,在代理类Proxy内部创建被代理类的对象,在被代理类对象调用相应方法的同时,增加额外的服务,实现代理功能。

        interface Moveable

        Class Car implements Moveable

        Class TimeProxy implements Moveable{

          Moveable moveable;

          创建含参moveable的构造方法,体现面向接口编程的思想

          在方法主体中添加代理功能和Moveable的主体方法

        }

      聚合比继承更适合代理模式,在代理类Proxy的内部使用面向接口编程,并没有指明具体的实现类,而且可以创建多个不同代理功能的代理类,例如日志代理,时间代理,在main方法中把他们联系起来便好,还可以在main方法中决定代理类的使用顺序。

    3:动态代理

      1)JDK动态代理

      1] 创建一个实现接口InvocationHandler的类,它必须实现Invoke方法

      2]创建被代理的类以及接口

      3]调用Proxy的静态方法,创建一个代理类

      newProxyInstance(ClassLoader loader,Class[] interfaces,InvocationHandler h)

      4]通过代理调用方法

      所谓代理,就是为了修改被代理对象的某些功能,日志代理,时间代理,就是添加了日志功能和时间功能,无谓继承还是聚合,静态代理同时对具体的被代理类进行功能上的修改。动态代理,顾名思义,是动态生成代理类的模式,重点在于把功能和代理区分开来。

      TimeHandler就是时间控制器,重写了InvocationHandler类实现了Invoke方法,它不再是某种具体代理类的功能,不再是CarTimeProxy,Time是功能,Proxy是代理。

      newProxyInstance()的参数invaocationHandler h 便是为代理类添加功能,至于前面的类加载器和接口,是为了生成具体的代理类,当代理和功能区分开来,便实现了解耦的目的。

      Dynamic Proxy是一种Class ,是运行时生成的class,需要实现一组interface。使用动态代理是,必须实现InvocationHandler接口。

      2)cglib动态代理

      cglib动态代理是针对类实现代理的,对指定目标类产生一个子类,通过方法拦截技术拦截所有父类方法的调用。

      JDK动态代理实现invocationHandler,cglib实现MethodIntercepter。

      JDK是向上找接口,用接口的抽象方法来替代未知的多种的具体被代理的方法,在此时添加功能。

      cglig是在父类方法调用的同时添加功能,运用了拦截器,是向下找子类。

      二者相同之处在于,具体的功能都与代理分离,功能都必须重写相应接口的抽象方法,JDK找接口很容易找到,但cglib必须指定给父类,也就是被代理的类。

      Enhancer负责设置创建子类的类,即代理类,建议写在MethodIntercepter接口的实现类中。

      综上:反射是Java中很重要的思想。

    JDK:

      //Handler这个就是时间功能

      

    package com.zhao.dynamic_proxy.jdk;

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

    public class TimeHandler implements InvocationHandler {
    private Object object;

    public TimeHandler(Object object) {
    super();
    this.object = object;
    }

    /*
    * 参数:
    * proxy:被代理的对象
    * method:被代理对象的方法
    * args:方法的参数
    *
    * 返回值:
    * Object:方法的返回值
    */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    // TODO Auto-generated method stub
    long startTime = System.currentTimeMillis();
    System.out.println("汽车开始行驶~~~");
    method.invoke(object);
    long endTime = System.currentTimeMillis();
    System.out.println("汽车结束行使~~~");
    System.out.println("汽车的行驶时间是:" + (endTime - startTime) + "毫秒");
    return null;
    }

    }

      //创建代理

    package com.zhao.dynamic_proxy;

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

    import org.junit.Test;

    import com.zhao.dynamic_proxy.jdk.TimeHandler;
    import com.zhao.static_proxy.service.Moveable;
    import com.zhao.static_proxy.service.impl.Car;

    /*
    * JDK动态代理测试类
    * */
    public class TestJDK {

    @Test
    public void test() {
    Car car=new Car();
    InvocationHandler h=new TimeHandler(car);
    Class<?> cls=car.getClass();
    /*
    * loader:类加载器
    * interfaces:实现接口
    * h:InvocationHandler
    * */
    Moveable moveable=(Moveable)Proxy.newProxyInstance(cls.getClassLoader(), cls.getInterfaces(), h);
    moveable.move();
    }

    }

    Cglib:

      

    package com.zhao.dynamic_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 CglibProxy implements MethodInterceptor{
    private Enhancer enhancer=new Enhancer();

    public Object getProxy(Class clazz){
    //设置创建子类的类
    enhancer.setSuperclass(clazz);
    enhancer.setCallback(this);

    return enhancer.create();
    }

    /*
    * 拦截所有目标类方法的调用
    * object:目标类的实例
    * method:目标方法的反射对象
    * args:方法的参数
    * proxy:代理类的实例
    * */
    @Override
    public Object intercept(Object object, Method method, Object[] args, MethodProxy proxy) throws Throwable {
    // 代理类调用父类的方法
    System.out.println("日志开始~~~~~~~~");
    proxy.invokeSuper(object, args);
    System.out.println("日志结束~~~~~~~~");
    return null;
    }

    }

    //获取代理类(代理类在上面的方法中创建)

    package com.zhao.dynamic_proxy;


    import org.junit.Test;
    import com.zhao.dynamic_proxy.cglib.CglibProxy;
    import com.zhao.dynamic_proxy.cglib.Train;

    public class TestCglib {

    @Test
    public void test() {
    CglibProxy cglibProxy=new CglibProxy();
    Train train=(Train) cglibProxy.getProxy(Train.class);
    train.move();
    }

    }

  • 相关阅读:
    AndroidAlarmManager(全局定时器/闹钟)
    Android dialog,activity 屏蔽Home键的教程详解
    实例教程一:电话拨号器
    Android的进程优先级与进程回收详解
    Android Bitmap内存限制
    【30篇突击 android】源码统计七
    在access中支持2个以上left join的方法,又是access的变态规则
    修改vs2005的键盘风格设置
    IE与Firefox的CSS兼容大全(转载)
    实现页面内多个表格在滚动时,表头浮动的效果(是同时多个表格哟)
  • 原文地址:https://www.cnblogs.com/zhao307/p/5339110.html
Copyright © 2011-2022 走看看