代理类在程序运行时才被创建的代理方式被成为动态代理。在静态代理中,代理类是已经定义好的,在程序运行之前就已经编译完成。而动态代理是在运行时根据我们传入的方法动态生成的。动态代理相较于静态代理的优势在于可以很方便的对代理类的所有函数进行统一管理,假如我们想在每个代理方法中都加一些相同代码,如果代理方法很多,那么我们需要在每个代理方法中写重复代码。

在java的java.lang.reflect包下提供了一个Proxy类和一个InvocationHandler接口,通过这个类和这个接口可以生成JDK动态代理类和动态代理对象。

案例:

Rental接口(租房):

package Proxy2;

public interface Rental {
    public void lease();
    public void end();
}

RentalImpl类(租房接口实现类):

package Proxy2;

public class RentalImpl implements Rental{
    @Override
    public void lease() {
        System.out.println("租房");
    }

    @Override
    public void end() {
        System.out.println("租房完成");
    }
}

RentalProxy类(代理类):

package Proxy2;

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

public class RentalProxy {
    public static Rental getProxy(Rental obj){
 /**
 * public static Object newProxyInstance(ClassLoader loader,Class<?>[]  interfaces,InvocationHandler h)
 * 参数一: 类加载器,负责加载代理
 * 参数二: 获取被代理对象实现的全部接口。代理要为全部接口的全部方法进行的代理
 * 参数三: 代理的核心处理逻辑
 */
        return (Rental) Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(),
                new InvocationHandler() {
                    @Override
                    //参数一: 代理对象本身
                    //参数二: 正在被代理的方法
                    //参数三: 被代理方法,应该传入的参数
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        System.out.println("中介介入");
                        method.invoke(obj,args);
                        return null;
                    }
                });
    }
}

Test类

package Proxy2;

public class Test {
    public static void main(String[] args){
        Rental rental = new RentalImpl();
        Rental proxy = RentalProxy.getProxy(rental);
        proxy.lease();
        proxy.end();
    }
}

参考:
https://www.le1a.com/post/Java%E5%8A%A8%E6%80%81%E4%BB%A3%E7%90%86/