2025年Java动态代理之JDK动态代理Proxy类

Java动态代理之JDK动态代理Proxy类注 示例代码如下 public interface ProxyInterfa String targetMethod String param public class JDKProxy public Object getInstanceP Class c

大家好,我是讯享网,很高兴认识大家。

注:示例代码如下

public interface ProxyInterface { 
    String targetMethod(String param); } 

讯享网
讯享网public class JDKProxy { 
    public Object getInstanceProxy(Class c) { 
    Object instance = Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), new Class[]{ 
   c}, (proxy, method, args) -> { 
    System.out.println("代理被执行。。。。"); System.out.println("执行完毕"); if (args != null) { 
    System.out.println("参数:" + args[0]); } return "您好"; }); return instance; } } 
public class ProxyInterfaceMain { 
    public static void main(String[] args) { 
    JDKProxy jdkProxy = new JDKProxy(); ProxyInterface instanceProxy = (ProxyInterface) jdkProxy.getInstanceProxy(ProxyInterface.class); System.out.println(instanceProxy.targetMethod("你好")); // System.out.println(instanceProxy); } } 

JDK的动态代理可以通过Proxy类型newProxyInstance()方法实现,方法有三个参数

讯享网 public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) 

JDK的动态代理生成,只能为接口提供,也就是说,有以下两种情况

1、接口没有实现类
如果接口没有实现类,那么生成的代理对象,在invoke方法中,则不能调用method.invoke方法,因为接口没有实现,调用这个方法传入proxy则会死循环,传入接口的类型,将会报错,则,接口所有的方法,都只能走InvocationHandler的invoke方法逻辑
而且,如果没有实现类,在调用Proxy.newProxyInstance时,要注意传入的interfaces参数,没有实现类,则需要用new Class[]{ProxyInterface.class}的方法传入,这样就可以生成代理了,如果传的是new Class[0],那么默认只会给toString方法代理,具体在下面有说明
2、
如果接口有实现类,那么在调用Proxy.newProxyInstance时,就需要用实现的Class对象,调用getInterface()方法,得到这个类实现的接口数组,然后这样代理对象才能对实现类的所有接口进行代理。
在这里插入图片描述
讯享网

  1. ClassLoader loader
    类加载器,一般都是直接获取当前线程的类加载器,也可以传入自定义的
    获取当前线程类加载器:
Thread.currentThread().getContextClassLoader() 

为什么要传入ClassLoader(类加载器、CL)

JVM通过类加载器来将.class文件加载到Meta space(元空间)中,也就是会通过类加载器,创建一个类的Class对象
JDK的动态代理,是一种动态字节码技术,通过在JVM中直接写入字节码的方式,为原始类创建一个代理类
再结合前面说的,如果要为这个代理类创建一个代理对象,则需要通过类加载器将代理类加载(创建一个代理类的Class对象)
而由于代理类是动态生成的,所以没有对应的类加载器,则只能通过方法参数传递进来(借用一个类加载器)。

  1. Class<?>[] interfaces
    需要代理的接口,这个参数有点特殊,它可以传入需要代理的接口的class,也可以传入接口中的方法的class
    1、传入接口的class
    在这里插入图片描述
    那么代理则会生成这个接口的实现类,在调用接口中的方法时,会执行InvocationHandler的invoke()方法,返回值也是方法的返回值,就是走的正常的动态代理流程
    2、传入数组大小问0的Class数组
    在这里插入图片描述
    如果是这样传值的话,那么,代理的接口就是toString()方法,且不能将返回的对象强转为接口类型,因为返回值对象已经变成了,invoke方法返回的,也只有在使用返回值对象时,才会触发invoke方法
    例如:
    在这里插入图片描述
    在这里插入图片描述
  2. InvocationHandler
    代理对象,通过动态代理生成出的对象,调用对象方法,实际调用的就是InvocationHandler对象的invoke方法,可以自定义一个类,实现InvocationHandler接口,也可以在Proxy.newProxyInstance的时候通过lambda表达式实现invoke方法。
小讯
上一篇 2025-02-26 18:21
下一篇 2025-03-25 17:03

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/53790.html