Java设计模式之代理模式

来源:互联网 发布:linux文件权限 编辑:程序博客网 时间:2024/05/18 01:21

静态代理

直接上代码。
汽车移动的接口

package com.ysk.proxy;public interface Moveable {    void move();}

汽车类实现移动接口

package com.ysk.proxy;import java.util.Random;public class Car implements Moveable{    @Override    public void move() {        try {            System.out.println("汽车行驶中");            Thread.sleep(new Random().nextInt(1000));        } catch (InterruptedException e) {            e.printStackTrace();        }    }}

代理类实现移动接口

package com.ysk.proxy;public class CarProxy implements Moveable{    private Car car;    public CarProxy(Car car){        this.car=car;    }    @Override    public void move() {        System.out.println("汽车开始行驶");        car.move();        System.out.println("汽车开始行驶");    }}

测试类

package com.ysk.proxy;public class CarProxy implements Moveable{    private Car car;    public CarProxy(Car car){        this.car=car;    }    @Override    public void move() {        System.out.println("汽车开始行驶");        car.move();        System.out.println("汽车开始行驶");    }}

JDK动态代理

代理类实现InvocationHandler接口,在类层面代理

package com.dl.jdkproxy;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;public class LogHandler implements InvocationHandler{    //Object 为需要代理的类对象    private Object o;    public LogHandler(Object o){        this.o=o;    }    @Override    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {        System.out.println("开始记录日志");        method.invoke(o);        System.out.println("结束记录日志");        return null;    }}

测试类

package com.dl.jdkproxy;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Proxy;import com.ysk.proxy.Car;import com.ysk.proxy.Moveable;public class App {    public static void main(String[] args) {       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.dl.cglibproxy;public class Train {    public void move() {        System.out.println("火车行驶中...");    }}

实现cglib的MethodInterceptor接口

package com.dl.cglibproxy;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();    }    /**     * obj 目标类的实例 m 目标方法的反射对象 args 方法的参数 proxy 代理类的实例     */    @Override    public Object intercept(Object obj, Method m, Object[] args, MethodProxy proxy) throws Throwable {        System.out.println("日志开始...");        proxy.invokeSuper(obj,args);        System.out.println("日志结束...");        return null;    }}

测试类,只需要将我们需要代理的类传进去即可,比JDK代理使用更加方便

package com.dl.cglibproxy;public class App {    public static void main(String[] args) {    CglibProxy proxy=new CglibProxy();    Train train=(Train) proxy.getProxy(Train.class);    train.move();    }}

总结

静态代理太过死板,不能从类的层面去代理我们的类,如果多加几个类(比如火车,自行车等等),仍需要去写很多代码去实现。
动态代理,从类的层面去加载,使我们可以同时适用于多个类。
 JDK的动态代理机制只能代理实现了接口的类,而不能实现接口的类就不能实现JDK的动态代理,cglib是针对类来实现代理的,他的原理是对指定的目标类生成一个子类,并覆盖其中方法实现增强,但因为采用的是继承,所以不能对final修饰的类进行代理.