跳到正文
伩仁的博客
返回

jdk动态代理和Cglib代理笔记

动态代理

https://www.imooc.com/video/4704 这个视频的笔记

java动态代理类位于java.lang.reflect包下, 一般主要是设计到一下两个类:

接口

//定义接口
public interface Moveable {
    void movie() throws InterruptedException;
}

被代理的类

public class Car implements Moveable {
    @Override
    public void movie() throws InterruptedException {
        TimeUnit.SECONDS.sleep(new Random().nextInt(5));

    }
}

动态代理

//实现InvocationHandler接口, 复写invoke, 在被代理对象方法前后增加新的功能, 返回被代理对象的返回值
public class TimeHandler implements InvocationHandler{
    private Object target;

    public TimeHandler(Object target) {
        this.target = target;
    }

    /**
     *
     * @param proxy 被代理的对象
     * @param method 被代理对象的方法
     * @param args 被代理对象方法的参数
     * @return 被代理Object对象 方法的返回值
     * @throws Throwable
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

        long start = System.currentTimeMillis();
        System.out.println("汽车开始行驶");
        method.invoke(target);
        long end = System.currentTimeMillis();
        System.out.println("汽车终止行驶!");
        System.out.println((end - start)/ 1000.0);
        return null;
    }
}

代理类的测试

public class Test {
    /**
     * jdk动态代理测试类
     */
    public static void main(String[] args) throws InterruptedException {
        Car car = new Car();
        InvocationHandler handler = new TimeHandler(car);
        Class<?> carClass = car.getClass();

        /**
         * loader: 类加载器
         * interfaces 类实现的接口
         * h InvocationHandler
         */
        Moveable moveable = (Moveable) Proxy.newProxyInstance(
                carClass.getClassLoader(),
                carClass.getInterfaces(),
                handler);
        moveable.movie();

    }
}

Cglib代理

也叫做子类代理. 用被代理类的子类对象增加功能来实现的.

被代理类

public class Train {
    public void move(){
        System.out.println("火车行驶中...");
    }
}

创建cglib代理类

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

public class CglibProxy implements MethodInterceptor {
    private Enhancer enhancer = new Enhancer();

    public Object getProxy(Class cls) {
        // 设置创建子类(代理类)的类(被代理的类)
        enhancer.setSuperclass(cls);
        enhancer.setCallback(this);
        return enhancer.create();
    }

    /**
     * cglib通过继承父类方法来实现代理
     * 拦截所有目标类方法的调用
     *
     * @param o           目标类的实例
     * @param method      目标方法的反射对象
     * @param objects     目标方法的参数
     * @param methodProxy 代理类的实例
     * @return 目标类方法的返回值
     */
    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy)
            throws Throwable {
        System.out.println("日志开始记录");
        // 代理类调用父类的方法
        methodProxy.invokeSuper(o, objects);
        System.out.println("日志结束...");
        return null;
    }
}

测试cglib代理

public class Client {
    public static void main(String[] args) {
        CglibProxy proxy = new CglibProxy();
        Train train = (Train) proxy.getProxy(Train.class);
        train.move();
    }
}

输入结果, 在被代理类功能前后都增加了新功能.

日志开始记录
火车行驶中...
日志结束...


上一篇
java注解笔记
下一篇
python和java的类当做map的键