设计模式之代理模式

来源:互联网 发布:大屏数据可视化 编辑:程序博客网 时间:2024/05/22 17:26

代理对象

被代理对象

代理模式分为静态代理和动态代理

代理模式就是在一个方法前后加上一些自定义的业务处理

Spring的AOP就是利用了动态代理模式

实际应用比如:一张大图片一时半会加载不出来,这时候就可以用代理模式,先用一张图片代替它,登加载出来在替换

分布计算方式RMI和Corba等都是Proxy模式的应用


静态代理

代理类和被代理类都需要实现一个共同的抽象接口MoveAble

所谓静态代理就是在运行之前(编译期间)就存在代理类的字节码文件,代理类和被代理类的关系在运行之前就确定了

一、字节码文件:.java文件编译之后的.class文件,操作系统不能直接运行,必须在jvm上运行

二、这里的代理类就是日志代理,时间代理;被代理类就是汽车类(具体是move这个方法)

抽象接口也称之为抽象角色,代理类也称之为代理角色,被代理类也称之为真实角色


接口(Moveable )

public interface Moveable {    void move();}

被代理类

public class Car implements Moveable {    @Override    public void move() {            try {            Thread.sleep(new Random().nextInt(1000));        } catch (InterruptedException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }        System.out.println("汽车行驶中...");    }}

日志代理类(CarLogProxy )

public class CarLogProxy implements Moveable {    private Moveable m;    public CarLogProxy(Moveable m) {        super();        this.m = m;    }    @Override    public void move() {        System.out.println("静态代理,开始记录日志");        m.move();        System.out.println("静态代理,结束记录日志");    }}

计时代理类(CarTimeProxy )

public class CarTimeProxy implements Moveable {    private Moveable m;    public CarTimeProxy(Moveable m) {        super();        this.m = m;    }    @Override    public void move() {        System.out.println("静态代理,汽车开始记录时间");        long startTime = System.currentTimeMillis();        m.move();        long endTime = System.currentTimeMillis();        System.out.println("静态代理,汽车结束记录时间,用时:"+ (endTime - startTime));    }}

测试类

public class Test {    public static void  main(String args[]){        Car car = new Car();        CarLogProxy carLogProxy = new CarLogProxy(car);        CarTimeProxy carTimeProxy = new CarTimeProxy(carLogProxy);        carTimeProxy.move();    }}

控制台打印:

静态代理,汽车开始记录时间

静态代理,开始记录日志

汽车行驶中…

静态代理,结束记录日志

静态代理,汽车结束记录时间,用时:914

动态代理(jdk动态代理)

在动态代理中,代理类的源码是在运行期间由jvm根据反射机制自动生成的,所以不存在代理类的字节码文件,代理类与被代理类的联系在程序运行期间确定

这里写图片描述

timeHandler事务处理器

public class TimeHandler implements InvocationHandler {    private Object target;    public TimeHandler(Object target) {        super();        this.target = target;    }    @Override    public Object invoke(Object proxy, Method method, Object[] args)            throws Throwable {          //timeHandler事务处理器的业务代码如下,此处简单表示         System.out.println("动态代理,汽车开始记录时间");        long startTime = System.currentTimeMillis();        method.invoke(target);          long endTime = System.currentTimeMillis();        System.out.println("动态代理,汽车结束记录时间,用时:"+ (endTime - startTime));        return null;    }}

测试类

public class Test {    public static void main(String[] args) {        // TODO Auto-generated method stub        Car car = new Car();        Class<?> cls = car.getClass();        InvocationHandler timeHandler = new TimeHandler(car);        /**         * 动态生成代理类         * loader 被代理类的类加载器         * interface 被代理类实现的接口         * h 要绑定的事务处理器         */        Moveable m = (Moveable)Proxy.newProxyInstance(cls.getClassLoader(),                    cls.getInterfaces(), timeHandler);          m.move();    }}

控制台打印:

动态代理,汽车开始记录时间

汽车行驶中…

动态代理,汽车结束记录时间,用时:185