动态代理

上篇随笔讲到的静态代理(https://www.cnblogs.com/great-r/p/17758310.html),这篇随笔就讲一讲动态代理吧。
一、动态代理
首先动态代理用来做什么?比如说项目中的其他人开发了某一块功能,你也想要使用此功能,但是可能需求不满足,需要增加点代码对功能做一些增强,这时候就可以使用代理,做到不修改其他人的代码。
动态代理分为了两个主要的实现方式,一个是JDK动态代理,一个是cglib动态代理。那么这两种实现方式有什么区别呢?
1、JDK动态代理
JDK动态代理是基于反射机制实现的,JDK动态代理主要有两个核心类分别是InvocationHandler和Proxy,通过实现InvocationHandler接口,然后重写invoke方法,invoke方法中的主要参数就是(被代理对象、被代理方法名、具体的参数),在invoke方法中去做一个增强方法的过程。然后通过Proxy使用newProxyInstance()方法去创建一个代理类,然后执行代理方法完成动态代理的这么一个过程。
代码示例:
1)创建一个接口

public interface Calculate {
    int add(int num1, int num2);
}

2)创建一个委托类(被代理的类),实现接口

public class Calculator implements Calculate {
    @Override
    public int add(int num1, int num2) {
        System.out.println(num1 + "+" + num2 + "=" + num1 + num2);
        return num1 + num2;
    }
}

3)创建InvocationHandler接口的实现类

public class MyInvocationHandler implements InvocationHandler {

    private Object target;

    //动态代理,目标对象是活动的,不是固定的,需要传入进来
    public MyInvocationHandler(Object target) {
        this.target = target;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("代理对象前进行真强活动");
        Object invoke = method.invoke(target, args);
        System.out.println("代理对象后进行真强活动");
        return invoke;
    }
}

4)使用newProxyInstance()方法创建代理对象

public class TestProxy {
    public static void main(String[] args) {
        //创建被代理对象
        Calculator calculator = new Calculator();
        //创建invocationHandler对象,传入被代理对象
        InvocationHandler invocationHandler = new MyInvocationHandler(calculator);
        //通过newProxyInstance()方法创建代理对象
        Calculate calculate = (Calculate) Proxy.newProxyInstance(calculator.getClass().getClassLoader(), calculator.getClass().getInterfaces(), invocationHandler);
        //代理对象执行add方法
        calculate.add(2, 3);
    }
}

5)运行结果

可以看到JDK动态代理比较关键的一点就是需要实现接口。那我们有些类没有实现接口,然而方法也需要使用到代理这时候怎么办呢?于是就有了cglib动态代理
2、cglib动态代理
cglib动态代理主要的原理就是通过继承目标类,创建它的子类,在子类中重写父类的方法,实现增强活动的这么一个过程。首先类似于JDK动态代理,cglib动态代理也有两个核心类,一个是MethodInterceptor,一个是enhancer类。MethodInterceptor类似于InvocationHandler,它是通过重写intercept方法,在intercept方法内做一个增强活动的过程,enhancer就类似于Proxy类,作用就是创建代理类,它是通过设置父类对象以及回调对象,然后通过enhancer.create()的方法创建代理对象的。
代码示例:
1)创建委托类,实现具体方法

public class SumNumber {
    public int add(int num1, int num2) {
        System.out.println(num1 + "+" + num2 + "=" + num1 + num2);
        return num1 + num2;
    }
}

2)创建MethodInterceptor接口的实现类

public class MyMethodInterceptor implements MethodInterceptor {

    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        System.out.println("代理对象前进行真强活动");
        Object o1 = methodProxy.invokeSuper(o, objects);
        System.out.println("代理对象后进行真强活动");
        return o1;
    }
}

3)创建代理类

public static void main(String[] args) {
        //创建代理对象
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(SumNumber.class);//设置父类对象
        enhancer.setCallback(new MyMethodInterceptor());//设置回调对象,增强类
        //通过enhancer.create()方法创建代理对象
        SumNumber sumNumber = (SumNumber)enhancer.create();
        sumNumber.add(2, 3);
    }

4)执行结果

posted @ 2023-10-14 15:31  Great-R  阅读(272)  评论(0)    收藏  举报