RPC框架中一般都有3个角色:服务提供者、服务消费者和注册中心。服务提供者将服务注册到注册中心,服务消费者从注册中心拉取服务的地址,并根据服务地址向服务提供者发起RPC调用。动态代理在这个RPC调用的过程中有什么作用?对于服务消费者,一般只会依赖服务接口,而服务的具体实现是在服务提供者这一端的,服务消费者和服务提供者分别部署在不同的机器上,服务消费者调用接口中的方法时怎么能够得到结果呢?JDK的动态代理就派上用场了。服务消费者使用JDK的动态代理技术,可以创建接口的代理对象,并在回调函数中将自己要调用的接口名称、方法签名信息通过http或者tcp的方式发送给服务提供者,服务提供者再通过反射的方式调用本地的服务,最后将结果通过http或tcp的方式返回给消费者。

下面是一个简单的演示程序:

 import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.HashMap;
import java.util.Map; /**
* 动态代理在RPC中的使用
*
* @author syj
*/
public class JDKProxyTest { // --------------------------- 模拟RPC客户端 --------------------------- // 客户端依赖服务端的接口(实现类在服务端)
private static IUserService userService; public static void main(String[] args) {
// 根据接口创建代理对象
userService = (IUserService) Proxy.newProxyInstance(
JDKProxyTest.class.getClassLoader(),
new Class[]{IUserService.class},
new InvocationHandler() {
// 在回调方法模拟进行RPC调用(通过http或者tcp与服务端通信)
@Override
public Object invoke(Object proxy, Method method, Object[] params) throws Throwable {
return rpcInvoke(IUserService.class.getSimpleName(), method.getName(), method.getParameterTypes(), params);
}
}
);
// 本地调用
String result = userService.sayHello("hello");
System.out.println(">>>> result =" + result);
} // --------------------------- 模拟RPC服务端 --------------------------- /**
* 反射调用
*
* @param methodName 方法名称
* @param parameterTypes 方法参数类型
* @param parameters 方法参数
* @return
*/
private static Object rpcInvoke(String interfaceName, String methodName, Class<?>[] parameterTypes, Object[] parameters) {
Object result = null;
try {
// 根据接口名称从Bean容器中获取Bean实例
Object serviceBean = beanMap.get(interfaceName);
// 反射调用
Class<?> serviceClass = serviceBean.getClass();
Method method = serviceClass.getMethod(methodName, parameterTypes);
method.setAccessible(true);
// 得到调用结果
result = method.invoke(serviceBean, parameters);
} catch (Exception e) {
e.printStackTrace();
}
return result;
} // 模拟Bean容器, key为接口名称, value为bean实例
private static Map<String, Object> beanMap = new HashMap<String, Object>() {{
put("IUserService", new UserServiceImpl());
}};
}

接口(服务提供者和服务的消费者都会依赖该接口):

 public interface IUserService {
String sayHello(String content);
}

服务提供者实现类:

public class UserServiceImpl implements IUserService {
@Override
public String sayHello(String content) {
return content + "::" + System.currentTimeMillis();
}
}

其实,JDK的动态代理技术,不仅可以应用在RPC框架中,也可以应用在所有基于客户端和服务端通信的架构中,比如微服务架构中的注册中心、配置中心、消息中心等。

JDK动态代理在RPC框架中的应用的更多相关文章

  1. 017 Java中的静态代理、JDK动态代理、cglib动态代理

    一.静态代理 代理模式是常用设计模式的一种,我们在软件设计时常用的代理一般是指静态代理,也就是在代码中显式指定的代理. 静态代理由业务实现类.业务代理类两部分组成.业务实现类负责实现主要的业务方法,业 ...

  2. 代理模式(静态代理、JDK动态代理原理分析、CGLIB动态代理)

    代理模式 代理模式是设计模式之一,为一个对象提供一个替身或者占位符以控制对这个对象的访问,它给目标对象提供一个代理对象,由代理对象控制对目标对象的访问. 那么为什么要使用代理模式呢? 1.隔离,客户端 ...

  3. 转:JDK动态代理为什么必须用接口以及与CGLIB的对比

    参考链接: JDK动态代理为什么必须用接口以及与CGLIB的对比 文章中提到:试验了JDK动态代理与CGLIB动态代理.从Spring的AOP框架介绍中得知对于使用接口的类,Spring使用JDK动态 ...

  4. 从静态代理,jdk动态代理到cglib动态代理-一文搞懂代理模式

    从代理模式到动态代理 代理模式是一种理论上非常简单,但是各种地方的实现往往却非常复杂.本文将从代理模式的基本概念出发,探讨代理模式在java领域的应用与实现.读完本文你将get到以下几点: 为什么需要 ...

  5. JDK动态代理、CGLIB动态代理详解

    Spring的AOP其就是通过动态代理的机制实现的,所以理解动态代理尤其重要. 动态代理比静态代理的好处: 1.一个动态代理类可以实现多个业务接口.静态代理的一个代理类只能对一个业务接口的实现类进行包 ...

  6. 深度剖析java中JDK动态代理机制

    https://www.jb51.net/article/110342.htm 本篇文章主要介绍了深度剖析java中JDK动态代理机制 ,动态代理避免了开发人员编写各个繁锁的静态代理类,只需简单地指定 ...

  7. SpringBoot27 JDK动态代理详解、获取指定的类类型、动态注册Bean、接口调用框架

    1 JDK动态代理详解 静态代理.JDK动态代理.Cglib动态代理的简单实现方式和区别请参见我的另外一篇博文. 1.1 JDK代理的基本步骤 >通过实现InvocationHandler接口来 ...

  8. 浅谈Spring中JDK动态代理与CGLIB动态代理

    前言Spring是Java程序员基本不可能绕开的一个框架,它的核心思想是IOC(控制反转)和AOP(面向切面编程).在Spring中这两个核心思想都是基于设计模式实现的,IOC思想的实现基于工厂模式, ...

  9. 吴裕雄--天生自然JAVA SPRING框架开发学习笔记:Spring JDK动态代理

    JDK 动态代理是通过 JDK 中的 java.lang.reflect.Proxy 类实现的.下面通过具体的案例演示 JDK 动态代理的使用. 1. 创建项目 在 MyEclipse 中创建一个名称 ...

随机推荐

  1. koa2安装

    安装 1. npm install koa-generator -g 2. Koa2 test-koa2 3. npm install & npm run dev 看package.json里 ...

  2. PAT1125

    总体思路 这道题就是一道贪心题. 对我来说,这道题的关键在于他在说什么(黑人问号???),一开始读了几遍都不知道在讲什么,怎么一根绳子对折后就和另一根套上了? 描述上面确实让人比较迷糊,配图也不是很明 ...

  3. 手写Java的字符串简单匹配方法IndexOf()

    简单的字符串模式匹配算法,可使用KMP进行优化 /** * @param s1 母串 * @param s2 子串 * @return */ public static int myIndexOf(S ...

  4. pdfminer批量处理PDF文件

    from pdfminer.pdfparser import PDFParser, PDFDocument from pdfminer.pdfinterp import PDFResourceMana ...

  5. Python win32gui调用窗口到最前面

    Python win32gui调用窗口到最前面 0要写一个轮询几个重要页面的程序,不停的在大屏上进行刷新,通过pywin32模块下的SetForegroundWindow函数调用时,会出现error: ...

  6. Idea和eclipse安装activiti插件

    eclipse安装:help>install new software>add             有外网状态下 输入  :http://www.activiti.org/design ...

  7. matlab的diff()函数

    diff():求差分 一阶差分 X = [1 1 2 3 5 8 13 21]; Y = diff(X) 结果: Y = 0 1 1 2 3 5 8 X = [1 1 1; 5 5 5; 25 25 ...

  8. C++类分号(;)问题

    环境:vs2010 问题:今天编代码过程中发现好多很奇怪的错误,我以为昨天调了下编译器才出问题了.搞了好久,代码注释掉很多还是不行,并且错误还一直在变化.问题大概如下: (照片上传不了) .error ...

  9. 列举 Python2和Python3的区别?

    1.print 在python2中,print被视为一个语句而不是一个函数,python3中,print()被视为一个函数 2.整数的除法 在python2中,键入的任何不带小数的数字,将被视为整数的 ...

  10. SecureCRT工具如何连接本地虚拟机

    1,1.打开虚拟机,查看当前虚拟机的IP地址,如下图 2.运行本地计算机安装的SecureCRT连接工具 3.在工具打开界面的窗口中选择快速连接按钮 4.在弹出的连接窗口中输入刚才查看的虚拟机的IP地 ...