当前位置:海洋目录网 » 站长资讯 » 教育考试 » 文章详细 订阅RssFeed

【java】说说有关jdk动态代理的那些事

来源:本站原创 浏览:51次 时间:2022-12-08
首先说下为什么要有动态代理呢?设计模式中,有一种模式叫代理模式,为什么要使用动态代理其实和为什么要使用设计模式一样,请读者自行思考。

代理通常有静态代理,动态代理,其中静态代理是通过持有目标对象引用,然后对目标对象的方法进行增强,可以说是一种硬编码。jdk动态代理也需要持有目标对象的引用,在目标对象的方法的调用处进行增强,但这部分被封在处理器InvocationHandler中,通过反射机制生成Proxy实例,并传入处理器。----先来看下使用jdk动态代理实现方式:

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

public class DynamicProxy implements InvocationHandler {
  private Object target;
  public DynamicProxy(Object object){
   this.target = object;
  }
  @Override
  public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    System.out.println("before......");
    Object result = method.invoke(target,args);
    System.out.println("after......");
    return result;
  }
  @SuppressWarnings("unchecked")
  public <T> T getProxy(){
    return (T)Proxy.newProxyInstance(
         target.getClass().getClassLoader(),
         target.getClass().getInterfaces(),
          this);
  }
}

动态是相对于静态代理而言,jvm执行java类,需要先将class文件加载到jvm中,java是不允许在运行时修改class文件的,所以要想使用动态代理,需要动态生成class文件,加载到jvm中。通过设置系统属性,可以在运行时看到jdk动态生成的class文件。

System.getProperties().setProperty("sun.misc.ProxyGenerator.saveGeneratedFiles", "true");
在生成的类文件中,可以看到代理类继承自Proxy并实现了业务自定义的接口,下面是动态生成的代理类部分代码:
public final class $Proxy0 extends Proxy implements IHello{
 public final String hello(String var1) throws  {
    return (String)super.h.invoke(this, m3, new Object[]{var1});
  }
  static {
    m0 = Class.forName("java.lang.Object").getMethod("hashCode");
   m1 = Class.forName("java.lang.Object").getMethod("equals", Class.forName("java.lang.Object"));
   m2 = Class.forName("java.lang.Object").getMethod("toString");
   m3 = Class.forName("com.proxy.IHello").getMethod("hello", Class.forName("java.lang.String"));
  }
}
可以看到jdk动态代理生成的代码,将目标对象接口的所有方法进行了代理,目标方法的执行就变成了处理器的invoke,在invoke中已经对目标对象中进行了增强。
其实思路是朴素的,就好比你不想出去吃饭点了外卖,外卖就相当于你的代理,帮你送饭,但是吃饭还是需要你自己来,外卖平台已经知道你需要的增强就是有人送饭,然后动态给你指定一个外卖骑手......----
下面看下jdk动态代理为了生成代理类是如何操作的,首先查找或生成设计好的代理class:

由ProxyClassFactory在给定类加载器和接口数组的条件下,生成、定义、并返回代理class。

最后将class字节码加载到jvm,在生成代理类的函数中可以看到是否生成class文件的布尔标记saveGeneratedFiles:

jdk动态代理无处不在,大名鼎鼎的spring AOP默认使用的就是jdk动态代理,对于没有接口实现的类才使用cglib代理。


  推荐站点

  • At-lib分类目录At-lib分类目录

    At-lib网站分类目录汇集全国所有高质量网站,是中国权威的中文网站分类目录,给站长提供免费网址目录提交收录和推荐最新最全的优秀网站大全是名站导航之家

    www.at-lib.cn
  • 中国链接目录中国链接目录

    中国链接目录简称链接目录,是收录优秀网站和淘宝网店的网站分类目录,为您提供优质的网址导航服务,也是网店进行收录推广,站长免费推广网站、加快百度收录、增加友情链接和网站外链的平台。

    www.cnlink.org
  • 35目录网35目录网

    35目录免费收录各类优秀网站,全力打造互动式网站目录,提供网站分类目录检索,关键字搜索功能。欢迎您向35目录推荐、提交优秀网站。

    www.35mulu.com
  • 就要爱网站目录就要爱网站目录

    就要爱网站目录,按主题和类别列出网站。所有提交的网站都经过人工审查,确保质量和无垃圾邮件的结果。

    www.912219.com
  • 伍佰目录伍佰目录

    伍佰网站目录免费收录各类优秀网站,全力打造互动式网站目录,提供网站分类目录检索,关键字搜索功能。欢迎您向伍佰目录推荐、提交优秀网站。

    www.wbwb.net