动态代理

回顾

用来解决两个应用之间的通信,而网络则是两台l两台机器之间的“桥梁”,只有搭好桥梁才能把请求数据从一端传输到另一端,其中关键就是“可靠的传输”

背景

RPC的目标就是通过屏蔽调用细节,实现远程调用如同本地调用一样简单

在使用RPC时,一般的做法是先找服务提供方要接口,通过Maven或者其他工具把接口依赖到项目中,通过依赖注入的方式把接口注入项目中,然后在代码里面直接调用的方法

核心技术:动态代理

  • RPC会自动给接口生成一个代理类,在项目中注入接口的时候,运行过程中实际绑定的是这个接口生成的代理类,在接口方法被调用的时候,实际上是被生成代理类拦截到了,这样就可以在生成的代理类中加入远程调用逻辑

动态代理

实现原理

/**

  • 要代理的接口

    */

    public interface Hello {

      String say();

    }

/**

  • 真实调用对象

    */

    public class RealHello {

public String invoke(){

    return "i'm proxy";

  }

}

/**

  • JDK代理类生成

    */

    public class JDKProxy implements InvocationHandler {

      private Object target;

JDKProxy(Object target) {

    this.target = target;

  }

@Override

  public Object invoke(Object proxy, Method method, Object[] paramValues) {

    return ((RealHello)target).invoke();

  }

}

/**

  • 测试例子

    */

    public class TestProxy {

public static void main(String[] args){

    // 构建代理器

    JDKProxy proxy = new JDKProxy(new RealHello());

    ClassLoader classLoader = ClassLoaderUtils.getCurrentClassLoader();

    // 把生成的代理类保存到文件

System.setProperty("sun.misc.ProxyGenerator.saveGeneratedFiles","true");

    // 生成代理类

    Hello test = (Hello) Proxy.newProxyInstance(classLoader, new Class[]{Hello.class}, proxy);

    // 方法调用

    System.out.println(test.say());

  }

}

  • 给Hello接口生成一个动态代理类,并调用接口say()方法,但真实返回的值是来自RealHello里面的invoke()方法返回值

实现方法

  • 在java领域(而我对java不熟),除了JDK默认的nvocationHandler能完成代理,还有很多第三方框架,如javassist、BYTE Buddy这样的框架也行

动态代理是一种具体的技术框架,那就会涉及到选型的问题,可从以下考虑

  • 因为代理类是在运行中生成的,那么代理框架生成代理类的速度、生成代理类的字节码大小等等,都会影响到其性能——生成的字节码越小,运行所占资源就越小。
  • 还有就是我们生成的代理类,是用于接口方法请求拦截的,所以每次调用接口方法的时候,都会执行生成的代理类,这时生成的代理类的执行效率就需要很高效。
  • 最后一个是从我们的使用角度出发的,我们肯定希望选择一个使用起来很方便的代理类框架,比如我们可以考虑:API 设计是否好理解、社区活跃度、还有就是依赖复杂度等等。

RPC实战与核心原理之动态代理了的更多相关文章

  1. spring5——Aop的实现原理(动态代理)

    spring框架的核心之一AOP,面向切面编程是一种编程思想.我对于面向切面编程的理解是:可以让我们动态的控制程序的执行流程及执行结果.spring框架对AOP的实现是为了使业务逻辑之间实现分离,分离 ...

  2. mybatis源码分析(5)-----拦截器的实现原理(动态代理+责任链)

    写在前面 MyBatsi 的拦截器模式是基于代理的代理模式.并且myBatis 的插件开发也是以拦截器的形式集成到myBatis 当中. MyBatis 的拦截器已经插件是在org.apache.ib ...

  3. Hibernate学习--hibernate延迟加载原理(动态代理)

    在正式说hibernate延迟加载时,先说说一个比较奇怪的现象吧:hibernate中,在many-to-one时,如果我们设置了延迟加载,会发现我们在eclipse的调试框中查看one对应对象时,它 ...

  4. AOP底层实现原理,动态代理如何动态

    代理 指定另外一个主体代替原来的某个主体去执行某个事物 代理执行的人 需要代理的人 需要代理的事情是一定要做的 但是被代理的人没有时间或自己做的不专业 静态代理: 父母朋友帮忙物色找对象 代理人掌握需 ...

  5. 30个类手写Spring核心原理之动态数据源切换(8)

    本文节选自<Spring 5核心原理> 阅读本文之前,请先阅读以下内容: 30个类手写Spring核心原理之自定义ORM(上)(6) 30个类手写Spring核心原理之自定义ORM(下)( ...

  6. Redis核心原理-简单动态字符串SDS

    SDS简介 Redis是C语言编写的,但没有使用c语言的字符串结构,而是自己实现了一套简单动态字符串 simple dynamic string 简称SDS,SDS兼容C语言的字符串类型,原理类似Ja ...

  7. Java之美[从菜鸟到高手演练]之JDK动态代理的实现及原理

    Java之美[从菜鸟到高手演练]之JDK动态代理的实现及原理 JDK动态代理的实现及原理 作者:二青 邮箱:xtfggef@gmail.com     微博:http://weibo.com/xtfg ...

  8. JDK和CGLIB动态代理原理区别

    JDK和CGLIB动态代理原理区别 https://blog.csdn.net/yhl_jxy/article/details/80635012 2018年06月09日 18:34:17 阅读数:65 ...

  9. Mybatis mapper动态代理的原理详解

    在开始动态代理的原理讲解以前,我们先看一下集成mybatis以后dao层不使用动态代理以及使用动态代理的两种实现方式,通过对比我们自己实现dao层接口以及mybatis动态代理可以更加直观的展现出my ...

  10. Spring源码剖析5:JDK和cglib动态代理原理详解

    AOP的基础是Java动态代理,了解和使用两种动态代理能让我们更好地理解 AOP,在讲解AOP之前,让我们先来看看Java动态代理的使用方式以及底层实现原理. 转自https://www.jiansh ...

随机推荐

  1. D pid(16916) tid(19140) 14:05:45 EdgeSnapFeature::PostExitSizeMove: WM_TWINVIEW_SHOW_GRIDLINES -> off

    D pid(16916) tid(19140) 14:05:45 EdgeSnapFeature::PostExitSizeMove: WM_TWINVIEW_SHOW_GRIDLINES -> ...

  2. Typecho 博客文章评论添加显示 UserAgent(UA)的功能

    本篇文章实现了为 Typecho 博客文章评论添加显示 UserAgent(UA)的功能 本功能可替代 UserAgent 插件,更美观.简洁且好看 效果显示 大概就是这样了,实际效果请看我的评论! ...

  3. Java的数据类型详解

    java的为强类型语言,所以要求变量的使用要严格符合规定,所有的变量都必须先定义后在使用: 什么是变量? 变量顾名思义,就是可变的量:是程序中最基本的存储单元,其要素要包括:变量名.变量类型和作用域: ...

  4. Cannot find config.m4. phpize 安装扩展出错

    原因 编译扩展包下面的名字可能不是 config.m4,也有可能有类似 config0.m4 的文件:因此名字不一样也是找不到的,我们需要用 mv config0.m4 config.m4 :修改文件 ...

  5. go strings包

    //是否包含指定的字符串中任意一个字符 有一个出现过 就返回true fmt.Println(strings.ContainsAny(s1,"glass")) //返回指定字符出现 ...

  6. 在GNU Hurd中感受Mach微内核的进程通信(IPC)

    什么是GNU Hurd 具体的时间线已经在官方维基页面得到详细描述[0],笔者在此就简单叙述一下.在1983年Richard Stallman开启了GNU项目,目的是创建一个自由的操作系统[1].在接 ...

  7. Docker 运行命令

    停止所有的容器 docker stop $(docker ps -aq) 启动所有的容器 docker start $(docker ps -aq) 停止容器 docker stop <容器Na ...

  8. delphi获取DOS命令行输出函数 运行CMD命令并获取结果

    procedure TForm1.Button4Click(Sender: TObject); var hReadPipe,hWritePipe:THandle; si:STARTUPINFO; ls ...

  9. JavaScript将时间戳转化为时间

    const timestampToTime= (timestamp) => { const date = new Date(timestamp * 1000); const year = dat ...

  10. 探秘Transformer系列之(20)--- KV Cache

    探秘Transformer系列之(20)--- KV Cache 目录 探秘Transformer系列之(20)--- KV Cache 0x00 概述 0x01 自回归推理的问题 1.1 请求的生命 ...