一篇文章让你搞懂Java中的静态代理和动态代理(一篇文章让你搞懂java中的静态代理和动态代理)

  本篇文章为你整理了一篇文章让你搞懂Java中的静态代理和动态代理(一篇文章让你搞懂java中的静态代理和动态代理)的详细内容,包含有一篇文章让你搞懂java中的静态代理和动态代理是什么 一篇文章让你搞懂java中的静态代理和动态代理 java静态代理和动态代理的区别 java静态代理和动态代理的优缺点 一篇文章让你搞懂Java中的静态代理和动态代理,希望能帮助你了解 一篇文章让你搞懂Java中的静态代理和动态代理。

  代理模式是常用的java设计模式,在Java中我们通常会通过new一个对象再调用其对应的方法来访问我们需要的服务。代理模式则是通过创建代理类(proxy)的方式间接地来访问我们需要的服务。

  举一个生活中的例子:像我们在网上通过中介租到其背后房东的房子,因为房东也嫌麻烦想省事,此时中介就相当于代理而房东则是被代理,两者是分开的,这样我们就不会直接访问到房东,大部分情况下在中介手中租到的房子都会比原价要贵一些,这好比代理的作用,即不需要通过房东中介也可以在原有房价基础上进行增减或者添加其他的推广方式等操作来进行出租。

  在Java中也是如此,我们需要遵循类的单一性原则,只有功能单一这个类被改动的可能性才会最小或者说在尽量不修改源码的前提下进行方法扩展,这样也可以避免在不清楚别人代码的情况下进行修改所导致的各种问题等等。

  代理的优缺点

  优点:

  
由于在客户端和真实对象之间增加了代理对象,因此有些类型的代理模式可能会造成请求的处理速度变慢;

  
由程序员创建或工具生成代理类的源码,再编译代理类,即代理类和委托类的关系再程序运行前就已经存在

  实现步骤:

  
将目标对象注入代理类中然后在代理类方法中调用目标类中的对应方法,这样我们就可以通过代理类在不修改原有方法的基础上进行扩展

  
Hobby hobby = new MyHobby();

   Hobbystaticproxy hobbystaticproxy = new Hobbystaticproxy(hobby);

   hobbystaticproxy.sing();

   hobbystaticproxy.dance();

  

 

 

  输出结果:

  可以看到我们在没有修改目标类的情况下通过代理类来实现按目标接口并且分别在目标类的 唱、跳方法前后都扩展了一个rap方法,这就是静态代理

  缺点:接口类变化会影响实现类和代理类;比如方法修改返回值、参数类型、增加方法,实现类和代理类都需要修改,不灵活而且很麻烦。

  使用反射和字节码的技术,在运行期创建指定接口或类的子类,以及其实例对象,控制被代理对象的访问,使用的工具有 jdkproxy、cglibproxy 等。

  上述静态代理在程序运行前就需要把对应的类和方法写好,这样就被写死了,这只是一个简单的接口里面也只有两个方法,那如果接口中有几十个方法都需要扩展呢,总不能一个个地手动去添加吧,所以有了我们的动态代理

  实现步骤:

  
@Override

   public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

   rap();

   Object result = method.invoke(obj, args);

   rap();

   return result;

   public void rap() {

   System.out.println("Dynamic-rap...");

  
public static void main(String[] args) {

   InvocationHandler renterHandler = new HobbyDynamicProxy(new MyHobby());

   Hobby hobbyProxy = (Hobby)Proxy.newProxyInstance(Hobby.class.getClassLoader(), new Class[]{Hobby.class},renterHandler);

   hobbyProxy.sing();

   hobbyProxy.dance();

  

 

 

  输出结果:

  InvocationHandler 接口 和 invoke 方法介绍

  InvokationHandler是Java 反射包里面的一个接口通过用户类来实现,来激发一个动态代理类的方法。

  它只有一个方法:

  

 

 

  public Object invoke(Object proxy, Method method, Object[] args)

  throws Throwable;

  

 

  
静态代理:

  在jvm运行之前就已经获取到代理类的class信息。代理类需要开发者自己写好,即开发者需要自己实现代理类的.java文件,也就是说在项目编译之前就需要存在代理类的.java文件,然后在编译阶段就可以将代理类的.java文件编译成.class文件,从而得到代理类的class信息;

  动态代理:

  不需要开发人员自己实现代理类的,也就是项目代码中是不存在代理类的.java文件的,既然代理类未由开发者实现,那么程序经过编译之后肯定也不会有代理类的.class文件。也就是说经过编译之后程序未启动运行之前,关于代理类的信息我们一无所知,它是在程序运行过程中需要用到的时候才会由jvm动态生成的,而且生成之后也只存在于内存中,不会写到磁盘保存成.class文件,更加不会保存为.java文件;

  总之一句话就是静态代理是需要开发人员自己实现代理类的逻辑的,且代理类的class信息是在程序运行之前就已经可以获取到的了,而动态代理是不需要开发人员自己实现代理类的

  以上就是一篇文章让你搞懂Java中的静态代理和动态代理(一篇文章让你搞懂java中的静态代理和动态代理)的详细内容,想要了解更多 一篇文章让你搞懂Java中的静态代理和动态代理的内容,请持续关注盛行IT软件开发工作室。

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: