设计模式-代理模式

定义

通过代理对象访问目标对象

特点

代理对象可以在目标对象实现的基础上,扩展目标对象的功能

静态代理

代理对象和目标对象一起实现相同的接口或者是继承相同的父类

public class Car implements Moveable {
    @Override
    public void move() {
        try {
            Thread.sleep(new Random().nextInt(10000));//随机slepp[0-9),模拟汽车运动的时间
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {

      /* Car car= new Car();
       CarTimeProxy carTimeProxy = new CarTimeProxy(moveable);
       CarLogProxy carLogProxy = new CarLogProxy(carTimeProxy);
       carLogProxy.move();*/
      
      new CarLogProxy(
                new CarTimeProxy(
                        new Car()
                )
        ).move();
    }
}
//增加了记录Car运动时间的功能
class CarTimeProxy implements Moveable{
    //目标对象是Car,代理对象是CarTimeProxy
    //接收保存目标对象
    Moveable moveable;
    public CarTimeProxy(Moveable moveable){
        this.moveable = moveable;
    }
    @Override
    public void move() {
        System.out.println("Car moving 轰轰轰!");
        long start = System.currentTimeMillis();
        moveable.move();
        long end = System.currentTimeMillis();
        System.out.println("汽车运行了"+(end-start)/1000+"秒"+"真的好厉害啊!");
    }
}
//增加了记录Car开始和结束的日志动作
class CarLogProxy implements Moveable{
    //目标对象是CarTimeProxy,代理对象是CarLogProxy
    //接收保存目标对象
    Moveable moveable;
    public CarLogProxy(Moveable moveable){
        this.moveable = moveable;
    }
    @Override
    public void move() {
        System.out.println("Car开始运动了!");
        moveable.move();
        System.out.println("Car结束运动了!");
    }
}
interface Moveable {
    void move();//移动的动作
}
动态代理
  • jdk动态代理
    利用反射机制生成一个实现代理接口的匿名对象类,在调用具体方法前调用InvocationHandler类来处理
  • cglib动态代理
    利用ASM(开源的Java字节码编辑库,操作字节码)开源包,将代理对象类的class文件加载进来,通过修改其字节码生成子类来处理
JDK动态代理
public class Car implements Movable{
    @Override
    public void move() {
        try {
            Thread.sleep(new Random().nextInt(10000));//随机slepp[0-9),模拟汽车运动的时间
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        Car car = new Car();
        Movable movable = (Movable) Proxy.newProxyInstance(
                Car.class.getClassLoader(),//目标对象,需要用哪个loader把new出来的代理对象给load到内存中,一般写被代理对象的
                new Class[]{Movable.class},//接口,代理对象应该实现哪些接口
                new InvocationHandler() { //被代理对象方法被调用的时候我们如何做处理
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        /**
                         * proxy:生成的代理对象
                         * method:正在调用的方法
                         * args:往方法里面传入的参数
                         */
                        System.out.println("method:"+method.getName()+":start...");
                        /**
                         * 传入哪个应用就相当于调用哪个引用的方法
                         * 方法被调用的时候需要告诉方法由谁来调用它
                         */
                        Object o = method.invoke(car, args);
                        System.out.println("method:"+method.getName()+":end...");
                        return o;
                    }
                }
        );
        /**
         * 动态生成的代理类会生成代理方法,
         * 代理类会调用自己的move方法,move方法调用invoke方法,invoke方法调用car的move方法
         */
        movable.move();
    }
}
interface Movable{
    void move();
}
生成动态代理对象的关键代码
loader:用哪个类加载器去加载代理对象
interfaces:动态代理类需要实现的接口
h:动态方法在执行时,会调用h里面的invoke方法去执行
Proxy.newProxyInstance(ClassLoader loader,
                        Class<?>[] interfaces,
                     InvocationHandler h)
优化版本一
public class Car implements Movable{
    @Override
    public void move() {
        try {
            Thread.sleep(new Random().nextInt(10000));//随机slepp[0-9),模拟汽车运动的时间
        }catch (Exception e){
            e.printStackTrace();
        }
    }
    public static void main(String[] args) {
        Car car = new Car();
         Movable movable = (Movable) Proxy.newProxyInstance(
                 Car.class.getClassLoader(),
                 new Class[]{Movable.class},
                 new LogHander(car)
         );
         movable.move();
    }
}
class LogHander implements InvocationHandler{
    Car car;
    public LogHander(Car car){
        this.car = car;
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("method:"+method.getName()+":start...");
        Object o = method.invoke(car, args);
        System.out.println("method:"+method.getName()+":end...");
        return o;
    }
}
interface Movable{
    void move();
}
优化版本二
public class Car implements Moveable{
    @Override
    public void move() {
        try {
            Thread.sleep(new Random().nextInt(10000));
        }catch (Exception e){
            e.printStackTrace();
        }
    }
    public static void main(String[] args) {
        Car car = new Car();
        Moveable moveable = (Moveable) Proxy.newProxyInstance(
                Car.class.getClassLoader(),
                new Class[]{Moveable.class},
                new LogHandler(car)
        );
        moveable.move();
    }
}
class LogHandler implements InvocationHandler{
    Car car = new Car();
    public LogHandler(Car car){
        this.car=car;
    }
    public void before() {
        System.out.println("method:"+"start...");
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        before();
        Object o = method.invoke(car, args);
        after();
        return o;
    }
    public void after() {
        System.out.println("method:"+"stop...");
    }
}
interface Moveable{
    void move();//移动
}
cglib的动态代理
/**
* cglib的动态代理
*/
public class Main {
   public static void main(String[] args) {
       Enhancer enhancer = new Enhancer();//增强器
       enhancer.setSuperclass(Car.class);//设置Car为父类
       enhancer.setCallback(new TimeMethodInterceptor());//设置回调函数
       Car car = (Car) enhancer.create();//调用create方法
       car.move();
   }
}
class TimeMethodInterceptor implements MethodInterceptor{
   public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
       //System.out.println(o.getClass().getSuperclass());输出Object o的父类对象,o为Car的子类,若Car使用fina修饰,无法使用cglib代理
       System.out.println("Car start moving");
       Object result = null;
       result = methodProxy.invokeSuper(o, objects);
       System.out.println("Car stop moving");
       return result;
   }
}
class Car {
   public void move(){
       try {
           System.out.println("Car is moving");
           Thread.sleep(new Random().nextInt(1000));
       }catch (Exception e){
           e.printStackTrace();
       }
   }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值