0
点赞
收藏
分享

微信扫一扫

反射与动态代理简直是影视圈的神马组合

反射与动态代理简直是影视圈的神马组合

Java可以在运行的时候知道对象的信息,这主要体现在Java的两个功能,RTTI和反射。

反射

上篇文章我们讲了RTTI的一些特性,它可以确定运行时的对象类型,这个类是在编译的时候是确定的,这样才能通过编译后的Class文件来加载类对象。当我们在编译时无法获取类信息的时候,就可以考虑使用反射,既然本地没有Class文件,可能就是通过网络获取Class文件,这时候我们就可以使用反射来获取类信息。

JDK中有个java.lang.reflect反射包,里面定义了反射用到的一些类,

代理

反射往往与动态代理相结合使用,所谓代理就是自己由于各种各样的原因不好抛头露面,有一个代理类来帮它完成一件事情,代理类往往在真正方法执行的前后添加逻辑。 下面我们举个代理模式使用的例子来说明一些

静态代理

定义一个接口:

interface Interface {
  void doSomething();
}

定义真正的对象:

class RealObject implements Interface {
  public void doSomething() { 
    System.out.println("简单输出"); 
  }
}

定义代理类:

class SimpleProxy implements Interface {
  private Interface proxied;
  public SimpleProxy(Interface proxied) {
    this.proxied = proxied;
  }
  public void doSomething() {
    System.out.println("使用代理类");
    proxied.doSomething();
  }
}  

使用:

new SimpleProxy(new RealObject()).doSomething();

这样我们看一下代码,,输出结果如下会先输出使用代理类 ,然后是简单输出

这是静态代理的实现,代理类需要我们定义,而动态代理就不一样了。

动态代理

动态代理可以动态创建代理并动态调用需要代理的方法。

定义动态代理类,这里我们使用实现InvocationHandler接口来,并重写他的invoke()方法

动态代理类:

class DynamicProxyHandler implements InvocationHandler {
  private Object proxied;
  public DynamicProxyHandler(Object proxied) {
    this.proxied = proxied;
  }
  public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    System.out.println("代理类: " + proxy.getClass() + ", 方法: " + method + ", 参数: " + args);
    if(args != null)
      for(Object arg : args)
        System.out.println("  " + arg);
    return method.invoke(proxied, args);
  }
}  

动态代理类的这一个invoke()方法的重写就够用了,当接口定义其他方法的时候,静态代理类需要同时实现接口的其他方法,而动态代理类就不需要了,这就是它的优势所在。

使用:

Interface proxy = (Interface)Proxy.newProxyInstance(
      Interface.class.getClassLoader(),
      new Class[]{ Interface.class },
      new DynamicProxyHandler(new RealObject()));
      
 proxy.doSomething();

运行结果:代理类:class $Proxy0, 方法:public abstract void Interface.doSomething(),参数: null

这里定义的动态代理类和静态代理类差不多,但比静态代理类稍微复杂一点。

我们使用Proxy.newProxyInstance()方法来创建动态代理对象,Method的invoke()方法调用被代理的对象的相应的方法,参数也可以携带。

总结

这篇文章我们讲了反射和代理的内容,往往他们两个结合起来使用,代理又分为静态代理和动态代理,动态代理相比静态代理更加灵活,减少代理类方法的编写,这也是我们生产中或者源码中经常用到的代理模式。动态代理的实现我们这里是使用了实现InvocationHandler接口的JDK代理方式,除此之外还可以使用CGlib代理。

❤️ 感谢大家

如果你觉得这篇内容对你挺有有帮助的话:

  1. 欢迎关注我❤️,点赞👍🏻,评论🤤,转发🙏
  2. 关注周结论本人,定期为你推送好文,还有群聊不定期抽奖活动,可以畅所欲言,与大神们一起交流,一起学习。
  3. 有不当之处欢迎批评指正。
举报

相关推荐

0 条评论