Java的动态代理是指在程序运行的时候,通过代理对象去调用目标对象的方法,同时在调用目标方法的前后可以执行一些功能,也就是可以增强目标对象的功能。

以鸟为例,我们需要让鸟飞,那么首先需要打开鸟的笼子,然后执行鸟的飞行方法,而代理要做的事情就是委托一个第三方代理,让这个代理去执行打开笼子的操作。

静态代理

首先采用静态代理的方式来做这件事

创建一个接口Bird,这个接口定义了鸟的fly方法

package com.kezez.java;

/**
 * @author : kaygb
 * @date : 2022/7/23 19:44
 * @desc :
 * @website : https://www.170601.xyz/
 * @blog : https://www.kezez.com/
 * @github : https://github.com/kaygb
 */
public interface Bird {
    void fly();
}

然后我们实现一个鸟类BirdOne,调用fly方法时会输出fly:

package com.kezez.java;

/**
 * @author : kaygb
 * @date : 2022/7/23 20:28
 * @desc :
 * @website : https://www.170601.xyz/
 * @blog : https://www.kezez.com/
 * @github : https://github.com/kaygb
 */
public class BirdOne implements Bird{
    @Override
    public void fly() {
        System.out.println("fly");
    }
}

接着,我们委托一个第三方代理,让他去打开笼子,鸟才能自由的飞翔:

package com.kezez.java;

/**
 * @author : kaygb
 * @date : 2022/7/23 20:25
 * @desc :
 * @website : https://www.170601.xyz/
 * @blog : https://www.kezez.com/
 * @github : https://github.com/kaygb
 */
public class Birdcage implements Bird{
    private Bird birdOne;
    public Birdcage (Bird birdOne){
        this.birdOne = birdOne;
    }
    @Override
    public void fly() {
        System.out.println("打开鸟笼");
        birdOne.fly();
    }
}

在main方法中使用静态代理去执行这个方法:

package com.kezez.java;

import java.lang.reflect.Proxy;

public class Main {

    public static void main(String[] args) {

        Bird birdOne = new BirdOne();
        Birdcage birdcage = new Birdcage(birdOne);
        birdcage.fly();

    }
}

然后就会得到下面的输出结果,说明我们的代理确实帮我们打开了这个笼子:

打开鸟笼
fly

动态代理

动态代理可以在程序运行的过程中去动态创建目标对象所需要的代理对象,无需像静态代理一样在编译的期间就指定好了代理对象。

使用动态代理只需要实现InvocationHandler接口即可,并且只需要重写invoke方法即可

package com.kezez.java;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

/**
 * @author : kaygb
 * @date : 2022/7/23 19:41
 * @desc :
 * @website : https://www.170601.xyz/
 * @blog : https://www.kezez.com/
 * @github : https://github.com/kaygb
 */
public class DynamicProxy implements InvocationHandler {
    private Object target;

    public void setTarget(Object target) {
        this.target = target;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("动态代理:打开鸟笼的门");
        Object res = method.invoke(target, args);
        return res;
    }
}

然后在main方法中使用Proxy调用动态代理,传入目标代理对象的ClassLoader、目标代理对象的接口以及上方创建的动态代理对象DynamicProxy,会返回一个被动态代理增强后的一个Object对象。

package com.kezez.java;

import java.lang.reflect.Proxy;

public class Main {

    public static void main(String[] args) {
        Bird bird = new BirdOne();
        DynamicProxy dynamicProxy = new DynamicProxy();
        dynamicProxy.setTarget(bird);
        Object obj = Proxy.newProxyInstance(bird.getClass().getClassLoader(), bird.getClass().getInterfaces(), dynamicProxy);
        ((Bird) obj).fly();
    }
}

输出如下:

动态代理:打开鸟笼的门
fly
版权声明
本文作者 珂泽
本文链接 https://www.kezez.com/archives/195.html
共享协议 CC BY-NC-SA 4.0
引用规则 非商业转载及引用请注明出处(作者、原文链接),商业转载请联系作者获得授权。
QQ 群组 962303102