本文转自Dubbo作者梁飞大神的CSDN(https://javatar.iteye.com/blog/1123915),代码简洁,五脏俱全.

1.首先实现RpcFramework,实现服务的暴露与引用功能.

 package com.zxd.dubbo.learning.rpc.framework;

 import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.net.ServerSocket;
import java.net.Socket; /**
* @Project DubboLearning
* @Package com.zxd.dubbo.learning.rpc.framework
* @Author:zouxiaodong
* @Description:
* @Date:Created in 14:32 2018/10/24.
*/
public class RpcFramework { /**
* @FileName RpcFramework.java
* @ClassName RpcFramework
* @MethodName export
* @Desc 暴露服务
* @author zouxiaodong
* @date 2018/10/24 15:06
* @Params [service 服务实现, port 服务端口]
* @return void
*/
public static void export(final Object service,int port) throws IOException {
if(service == null){
throw new IllegalArgumentException("service instance == null");
}
if(port < 0 || port > 65535){
throw new IllegalArgumentException("Invalid port " + port);
}
System.out.println("Export service :" + service.getClass().getName() + " on port " + port);
ServerSocket serverSocket = new ServerSocket(port);
while (true){
try {
final Socket socket = serverSocket.accept();
new Thread(new Runnable() {
@Override
public void run() {
ObjectInputStream input = null;
ObjectOutputStream output = null;
try {
input = new ObjectInputStream(socket.getInputStream());
String methodName = input.readUTF();
Class<?>[] parameterTypes = (Class<?>[]) input.readObject();
Object[] arguments = (Object[]) input.readObject();
output = new ObjectOutputStream(socket.getOutputStream());
Method method = service.getClass().getMethod(methodName,parameterTypes);
Object result = method.invoke(service,arguments);
output.writeObject(result);
} catch (Exception e) {
System.err.println("1."+e.getMessage());
}finally {
try {
if(output != null){
output.close();
}
if(input != null){
input.close();
}
if(socket != null){
socket.close();
}
} catch (IOException e) {
System.err.println("2."+e.getMessage());
}
}
}
}).start();
}catch (Exception e){ }
}
} /**
* @FileName RpcFramework.java
* @ClassName RpcFramework
* @MethodName refer
* @Desc 引用服务
* @author zouxiaodong
* @date 2018/10/24 15:32
* @Params [interfaceClass 接口类型, host 服务器主机名, port 服务器端口]
* @return T 远程服务
*/
public static <T> T refer(final Class<T> interfaceClass,final String host,final int port){
if(interfaceClass == null){
throw new IllegalArgumentException("Interface class == null");
}
if(!interfaceClass.isInterface()){
throw new IllegalArgumentException("The " + interfaceClass.getName() + " must be interface class!");
}
if (host == null || host.length() == 0) {
throw new IllegalArgumentException("Host == null!");
}
if (port <= 0 || port > 65535) {
throw new IllegalArgumentException("Invalid port " + port);
}
System.out.println("Get remote service " + interfaceClass.getName() + " from server " + host + ":" + port);
return (T)Proxy.newProxyInstance(interfaceClass.getClassLoader(), new Class<?>[]{interfaceClass}, new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Socket socket = new Socket(host,port);
ObjectOutputStream output = new ObjectOutputStream(socket.getOutputStream());
output.writeUTF(method.getName());
output.writeObject(method.getParameterTypes());
output.writeObject(args);
ObjectInputStream input = new ObjectInputStream(socket.getInputStream());
try {
Object result = input.readObject();
if(result instanceof Throwable){
throw (Throwable)result;
}
return result;
}finally {
input.close();
output.close();
socket.close();
}
}
});
}
}

2.编写接口HelloService.java与实现类HelloServiceImpl.java

 package com.zxd.dubbo.learning.rpc.framework;

 /**
* @Project DubboLearning
* @Package com.zxd.dubbo.learning.rpc.framework.api
* @Author:zouxiaodong
* @Description:
* @Date:Created in 15:50 2018/10/24.
*/
public interface HelloService {
String hello(String name);
}
 package com.zxd.dubbo.learning.rpc.framework;

 /**
* @Project DubboLearning
* @Package com.zxd.dubbo.learning.rpc.framework.impl
* @Author:zouxiaodong
* @Description:
* @Date:Created in 15:51 2018/10/24.
*/
public class HelloServiceImpl implements HelloService {
@Override
public String hello(String name) {
return "Hello "+name;
}
}

3.编写提供者(暴露服务)

 package com.zxd.dubbo.learning.rpc.framework;

 import java.io.IOException;

 /**
* @Project DubboLearning
* @Package com.zxd.dubbo.learning.rpc.framework
* @Author:zouxiaodong
* @Description:
* @Date:Created in 15:54 2018/10/24.
*/
public class RpcProvider {
public static void main(String[] args) throws IOException {
HelloService helloService = new HelloServiceImpl();
RpcFramework.export(helloService,12345);
}
}

4.编写消费者(引用服务)

 package com.zxd.dubbo.learning.rpc.framework;

 /**
* @Project DubboLearning
* @Package com.zxd.dubbo.learning.rpc.framework
* @Author:zouxiaodong
* @Description:
* @Date:Created in 15:55 2018/10/24.
*/
public class RpcConsumer {
public static void main(String[] args){
HelloService helloService = RpcFramework.refer(HelloService.class,"127.0.0.1",12345);
String result = helloService.hello("CoderZZ");
System.out.println(result);
}
}

Java通过Socket和动态代理实现简易RPC框架的更多相关文章

  1. Java Proxy和CGLIB动态代理原理

    动态代理在Java中有着广泛的应用,比如Spring AOP,Hibernate数据查询.测试框架的后端mock.RPC,Java注解对象获取等.静态代理的代理关系在编译时就确定了,而动态代理的代理关 ...

  2. java反射机制与动态代理

    在学习HadoopRPC时.用到了函数调用.函数调用都是採用的java的反射机制和动态代理来实现的,所以如今回想下java的反射和动态代理的相关知识. 一.反射 JAVA反射机制定义: JAVA反射机 ...

  3. Java反射机制以及动态代理

    Java反射机制以及动态代理 Java反射机制 含义与功能 Java的反射(reflection)机制是指在程序的运行状态中,可以构造任意一个类的对象,可以了解任意一个对象所属的类,可以了解任意一个类 ...

  4. 简易RPC框架-客户端限流配置

    *:first-child { margin-top: 0 !important; } body>*:last-child { margin-bottom: 0 !important; } /* ...

  5. 自行实现一个简易RPC框架

    10分钟写一个RPC框架 1.RpcFramework package com.alibaba.study.rpc.framework; import java.io.ObjectInputStrea ...

  6. 简易RPC框架-SPI

    *:first-child { margin-top: 0 !important; } body > *:last-child { margin-bottom: 0 !important; } ...

  7. 简易RPC框架-心跳与重连机制

    *:first-child { margin-top: 0 !important; } body > *:last-child { margin-bottom: 0 !important; } ...

  8. Java中的JDK动态代理

    所谓代理,其实就是相当于一个中间人,当客户端需要服务端的服务时,不是客户直接去找服务,而是客户先去找代理,告诉代理需要什么服务,然后代理再去服务端找服务,最后将结果返回给客户. 在日常生活中,就拿买火 ...

  9. Java核心技术点之动态代理

    本篇博文会从代理的概念出发,介绍Java中动态代理技术的使用,并进一步探索它的实现原理.由于个人水平有限,叙述中难免出现不清晰或是不准确的地方,希望大家可以指正,谢谢大家:) 一.概述 1. 什么是代 ...

随机推荐

  1. ORM SQLAlchemy 表于表的关系

    1表与表之间三种关系 1.1 一对一关系 举例: 一个丈夫对应一个妻子,一个妻子对应一个丈夫 1.2 一对多关系 举例:一个人可以拥有多辆汽车,要求查询某个人拥有的所有车辆 分析:这种情况其实也可以采 ...

  2. 利用csv文件批量编辑更新sql

    历史表(popularity_ranking)数据中只存了用户手机号,业务需求中需要新增用户昵称字段, 这里我们用户表和popularity_ranking表在不同数据库中,有两种方法:1.编写后台服 ...

  3. 无法访问com.alibaba.fastjson.parser.deserializer.PropertyProcessable

    某项目加入了某依赖A,IDEA里编译报了如下错误: 无法访问com.alibaba.fastjson.parser.deserializer.PropertyProcessable 错误代码行为某个使 ...

  4. Sublime 添加∕删除右键菜单.bat

    Sublime 添加∕删除右键菜单.bat @ECHO OFF & PUSHD %~DP0 & TITLE >NUL 2>&1 REG.exe query &quo ...

  5. SpringMVC之ajax与表单 Post 数据提交差异小结

    最近在写一个富文本框的后台数据服务的时候遇到一些关于 ajax 提交与 表单提交的比较特殊的案例,这里拿来跟大家分享,希望能让大家有所启发. 1. 首先是常见表单提交在SpringMVC的控制器中的代 ...

  6. 在CSS中定义【导航栏】超链接样式

    1.案例css代码 <style> .divcss5 a:link{ color:#F00}/* 链接默认为红色 */ .divcss5 a:hover{ color:#000}/* 鼠标 ...

  7. Oracle查询表和字段

    查看表字段.类型.注释 SELECT A.COLUMN_NAME,B.comments,A.DATA_TYPE FROM USER_TAB_COLUMNS A LEFT JOIN user_col_c ...

  8. Vue 2.x指令综合小练习

    实现效果如下: 代码实现如下: <!DOCTYPE html> <html lang="en"> <head> <meta charset ...

  9. utgard OPC 主要功能简介

    度娘还行,尽管不好用,但所有的开发人员不懈努力地写博客,能得到很多东西! 这里向所有未谋面的博主们致敬! 搜了一堆OPC资料,在这里整理一下,用一个封装类来说明utgard的主要接口.使用了java自 ...

  10. vue知识点积累

    vue中 列表组件写key,起作用是什么? <ul> <li v-for="item in items" :key="item.id"> ...