Java經過Socket和動態代理實現簡易RPC框架

本文轉自Dubbo做者梁飛大神的CSDN(https://javatar.iteye.com/blog/1123915),代碼簡潔,五臟俱全.java

 1.首先實現RpcFramework,實現服務的暴露與引用功能.

 1 package com.zxd.dubbo.learning.rpc.framework;  2 
 3 import java.io.IOException;  4 import java.io.ObjectInputStream;  5 import java.io.ObjectOutputStream;  6 import java.lang.reflect.InvocationHandler;  7 import java.lang.reflect.Method;  8 import java.lang.reflect.Proxy;  9 import java.net.ServerSocket;  10 import java.net.Socket;  11 
 12 /**
 13  * @Project DubboLearning  14  * @Package com.zxd.dubbo.learning.rpc.framework  15  * @Author:zouxiaodong  16  * @Description:  17  * @Date:Created in 14:32 2018/10/24.  18  */
 19 public class RpcFramework {  20 
 21     /**
 22  * @FileName RpcFramework.java  23  * @ClassName RpcFramework  24  * @MethodName export  25  * @Desc 暴露服務  26  * @author zouxiaodong  27  * @date 2018/10/24 15:06  28  * @Params [service 服務實現, port 服務端口]  29  * @return void  30      */
 31     public static void export(final Object service,int port) throws IOException {  32         if(service == null){  33             throw new IllegalArgumentException("service instance == null");  34  }  35         if(port < 0 || port > 65535){  36             throw new IllegalArgumentException("Invalid port " + port);  37  }  38         System.out.println("Export service :" + service.getClass().getName() + " on port " + port);  39         ServerSocket serverSocket = new ServerSocket(port);  40         while (true){  41             try {  42                 final Socket socket = serverSocket.accept();  43                 new Thread(new Runnable() {  44  @Override  45                     public void run() {  46                         ObjectInputStream input = null;  47                         ObjectOutputStream output = null;  48                         try {  49                             input = new ObjectInputStream(socket.getInputStream());  50                             String methodName = input.readUTF();  51                             Class<?>[] parameterTypes = (Class<?>[]) input.readObject();  52                             Object[] arguments = (Object[]) input.readObject();  53                             output = new ObjectOutputStream(socket.getOutputStream());  54                             Method method = service.getClass().getMethod(methodName,parameterTypes);  55                             Object result = method.invoke(service,arguments);  56  output.writeObject(result);  57                         } catch (Exception e) {  58                             System.err.println("1."+e.getMessage());  59                         }finally {  60                             try {  61                                 if(output != null){  62  output.close();  63  }  64                                 if(input != null){  65  input.close();  66  }  67                                 if(socket != null){  68  socket.close();  69  }  70                             } catch (IOException e) {  71                                 System.err.println("2."+e.getMessage());  72  }  73  }  74  }  75  }).start();  76             }catch (Exception e){  77 
 78  }  79  }  80  }  81 
 82     /**
 83  * @FileName RpcFramework.java  84  * @ClassName RpcFramework  85  * @MethodName refer  86  * @Desc 引用服務  87  * @author zouxiaodong  88  * @date 2018/10/24 15:32  89  * @Params [interfaceClass 接口類型, host 服務器主機名, port 服務器端口]  90  * @return T 遠程服務  91      */
 92     public static <T> T refer(final Class<T> interfaceClass,final String host,final int port){  93         if(interfaceClass == null){  94             throw new IllegalArgumentException("Interface class == null");  95  }  96         if(!interfaceClass.isInterface()){  97             throw new IllegalArgumentException("The " + interfaceClass.getName() + " must be interface class!");  98  }  99         if (host == null || host.length() == 0) { 100             throw new IllegalArgumentException("Host == null!"); 101  } 102         if (port <= 0 || port > 65535) { 103             throw new IllegalArgumentException("Invalid port " + port); 104  } 105         System.out.println("Get remote service " + interfaceClass.getName() + " from server " + host + ":" + port); 106         return (T)Proxy.newProxyInstance(interfaceClass.getClassLoader(), new Class<?>[]{interfaceClass}, new InvocationHandler() { 107  @Override 108             public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { 109                 Socket socket = new Socket(host,port); 110                 ObjectOutputStream output = new ObjectOutputStream(socket.getOutputStream()); 111  output.writeUTF(method.getName()); 112  output.writeObject(method.getParameterTypes()); 113  output.writeObject(args); 114                 ObjectInputStream input = new ObjectInputStream(socket.getInputStream()); 115                 try { 116                     Object result = input.readObject(); 117                     if(result instanceof Throwable){ 118                         throw (Throwable)result; 119  } 120                     return result; 121                 }finally { 122  input.close(); 123  output.close(); 124  socket.close(); 125  } 126  } 127  }); 128  } 129 }

2.編寫接口HelloService.java與實現類HelloServiceImpl.java

 1 package com.zxd.dubbo.learning.rpc.framework;  2 
 3 /**
 4  * @Project DubboLearning  5  * @Package com.zxd.dubbo.learning.rpc.framework.api  6  * @Author:zouxiaodong  7  * @Description:  8  * @Date:Created in 15:50 2018/10/24.  9  */
10 public interface HelloService { 11  String hello(String name); 12 }
 1 package com.zxd.dubbo.learning.rpc.framework;  2 
 3 
 4 /**
 5  * @Project DubboLearning  6  * @Package com.zxd.dubbo.learning.rpc.framework.impl  7  * @Author:zouxiaodong  8  * @Description:  9  * @Date:Created in 15:51 2018/10/24. 10  */
11 public class HelloServiceImpl implements HelloService { 12  @Override 13     public String hello(String name) { 14         return "Hello "+name; 15  } 16 }

3.編寫提供者(暴露服務)

 1 package com.zxd.dubbo.learning.rpc.framework;  2 
 3 import java.io.IOException;  4 
 5 /**
 6  * @Project DubboLearning  7  * @Package com.zxd.dubbo.learning.rpc.framework  8  * @Author:zouxiaodong  9  * @Description: 10  * @Date:Created in 15:54 2018/10/24. 11  */
12 public class RpcProvider { 13     public static void main(String[] args) throws IOException { 14         HelloService helloService = new HelloServiceImpl(); 15         RpcFramework.export(helloService,12345); 16  } 17 }

4.編寫消費者(引用服務)

 1 package com.zxd.dubbo.learning.rpc.framework;  2 
 3 /**
 4  * @Project DubboLearning  5  * @Package com.zxd.dubbo.learning.rpc.framework  6  * @Author:zouxiaodong  7  * @Description:  8  * @Date:Created in 15:55 2018/10/24.  9  */
10 public class RpcConsumer { 11     public static void main(String[] args){ 12         HelloService helloService = RpcFramework.refer(HelloService.class,"127.0.0.1",12345); 13         String result = helloService.hello("CoderZZ"); 14  System.out.println(result); 15  } 16 }
相關文章
相關標籤/搜索