一个简单的RPC框架实现
package com.rpc; public interface EchoService { String echo(String ping); }
package com.rpc; public class EchoServiceImpl implements EchoService{ @Override public String echo(String ping) { // TODO Auto-generated method stub return ping != null ? ping + "--> I am ok.":"I am ok."; } }
package com.rpc; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.lang.reflect.Method; import java.net.InetSocketAddress; import java.net.ServerSocket; import java.net.Socket; import java.util.concurrent.Executor; import java.util.concurrent.Executors; /** * 服务生产者 * @author Administrator * */ public class RpcExporter { static Executor executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()); public static void exporter(String hostname,int port) throws Exception{ ServerSocket server = new ServerSocket(); server.bind(new InetSocketAddress(hostname, port)); try { while(true){ executor.execute(new ExporterTask(server.accept())); } } finally { server.close(); } } private static class ExporterTask implements Runnable{ Socket client = null; public ExporterTask(Socket client) { this.client = client; } @Override public void run() { ObjectInputStream input = null; ObjectOutputStream output = null; try { input = new ObjectInputStream(client.getInputStream()); String interfaceName = input.readUTF(); Class<?> service = Class.forName(interfaceName); String methodName = input.readUTF(); Class<?>[] parameterTypes = (Class<?>[]) input.readObject(); Object[] arguments = (Object[]) input.readObject(); Method method = service.getMethod(methodName, parameterTypes); Object result = method.invoke(service.newInstance(), arguments); output = new ObjectOutputStream(client.getOutputStream()); output.writeObject(result); } catch (Exception e) { e.printStackTrace(); }finally{ if(output != null ) try{ output.close(); }catch(IOException e){ e.printStackTrace(); } if(input != null) try { input.close(); } catch (IOException e) { e.printStackTrace(); } if(client != null) try{ client.close(); }catch(IOException e){ e.printStackTrace(); } } } } }
package com.rpc; 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.InetSocketAddress; import java.net.Socket; /** * 服务消费者 * @author Administrator * * @param <S> */ public class RpcImporter<S> { // serviceClass 即传入的具体实现类 @SuppressWarnings("unchecked") public S importer(final Class<?> serviceClass, final InetSocketAddress addr) { return (S) Proxy.newProxyInstance(serviceClass.getClassLoader(), serviceClass.getInterfaces(), new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Socket socket = null; ObjectOutputStream output = null; ObjectInputStream input = null; try { socket = new Socket(); socket.connect(addr); output = new ObjectOutputStream(socket.getOutputStream()); output.writeUTF(serviceClass.getName()); output.writeUTF(method.getName()); output.writeObject(method.getParameterTypes()); output.writeObject(args); input = new ObjectInputStream(socket.getInputStream()); return input.readObject(); } finally { if (socket != null) socket.close(); if (output != null) output.close(); if (input != null) input.close(); } } }); } }
package com.rpc; import java.net.InetSocketAddress; public class RpcTest { public static void main(String[] args) throws InterruptedException { new Thread(new Runnable() { @Override public void run() { try { RpcExporter.exporter("localhost", 8080); } catch (Exception e) { e.printStackTrace(); } } }).start(); RpcImporter<EchoService> importer = new RpcImporter<EchoService>(); EchoService echo = importer.importer(EchoServiceImpl.class, new InetSocketAddress("localhost", 8080)); System.out.println(echo.echo("Are you ok ?")); } }