/* * Copyright 2011 Alibaba.com All right reserved. This software is the * confidential and proprietary information of Alibaba.com ("Confidential * Information"). You shall not disclose such Confidential Information and shall * use it only in accordance with the terms of the license agreement you entered * into with Alibaba.com. */ package com.alibaba.study.rpc.framework; 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; /** * RpcFramework * * @author william.liangf */ publicclassRpcFramework { /** * 暴露服务 * * @param service 服务实现 * @param port 服务端口 * @throws Exception */ publicstaticvoidexport(final Object service, int port)throws Exception { if (service == null) thrownewIllegalArgumentException("service instance == null"); if (port <= 0 || port > 65535) thrownewIllegalArgumentException("Invalid port " + port); System.out.println("Export service " + service.getClass().getName() + " on port " + port); ServerSocketserver=newServerSocket(port); for(;;) { try { finalSocketsocket= server.accept(); newThread(newRunnable() { @Override publicvoidrun() { try { try { ObjectInputStreaminput=newObjectInputStream(socket.getInputStream()); try { StringmethodName= input.readUTF(); Class<?>[] parameterTypes = (Class<?>[])input.readObject(); Object[] arguments = (Object[])input.readObject(); ObjectOutputStreamoutput=newObjectOutputStream(socket.getOutputStream()); try { Methodmethod= service.getClass().getMethod(methodName, parameterTypes); Objectresult= method.invoke(service, arguments); output.writeObject(result); } catch (Throwable t) { output.writeObject(t); } finally { output.close(); } } finally { input.close(); } } finally { socket.close(); } } catch (Exception e) { e.printStackTrace(); } } }).start(); } catch (Exception e) { e.printStackTrace(); } } } /** * 引用服务 * * @param <T> 接口泛型 * @param interfaceClass 接口类型 * @param host 服务器主机名 * @param port 服务器端口 * @return 远程服务 * @throws Exception */ @SuppressWarnings("unchecked") publicstatic <T> T refer(final Class<T> interfaceClass, final String host, finalint port)throws Exception { if (interfaceClass == null) thrownewIllegalArgumentException("Interface class == null"); if (! interfaceClass.isInterface()) thrownewIllegalArgumentException("The " + interfaceClass.getName() + " must be interface class!"); if (host == null || host.length() == 0) thrownewIllegalArgumentException("Host == null!"); if (port <= 0 || port > 65535) thrownewIllegalArgumentException("Invalid port " + port); System.out.println("Get remote service " + interfaceClass.getName() + " from server " + host + ":" + port); return (T) Proxy.newProxyInstance(interfaceClass.getClassLoader(), newClass<?>[] {interfaceClass}, newInvocationHandler() { public Object invoke(Object proxy, Method method, Object[] arguments)throws Throwable { Socketsocket=newSocket(host, port); try { ObjectOutputStreamoutput=newObjectOutputStream(socket.getOutputStream()); try { output.writeUTF(method.getName()); output.writeObject(method.getParameterTypes()); output.writeObject(arguments); ObjectInputStreaminput=newObjectInputStream(socket.getInputStream()); try { Objectresult= input.readObject(); if (result instanceof Throwable) { throw (Throwable) result; } return result; } finally { input.close(); } } finally { output.close(); } } finally { socket.close(); } } }); } }
用起来也像模像样:
**(1) 定义服务接口 **
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
/* * Copyright 2011 Alibaba.com All right reserved. This software is the * confidential and proprietary information of Alibaba.com ("Confidential * Information"). You shall not disclose such Confidential Information and shall * use it only in accordance with the terms of the license agreement you entered * into with Alibaba.com. */ package com.alibaba.study.rpc.test; /** * HelloService * * @author william.liangf */ publicinterfaceHelloService { String hello(String name); }
/* * Copyright 2011 Alibaba.com All right reserved. This software is the * confidential and proprietary information of Alibaba.com ("Confidential * Information"). You shall not disclose such Confidential Information and shall * use it only in accordance with the terms of the license agreement you entered * into with Alibaba.com. */ package com.alibaba.study.rpc.test; /** * HelloServiceImpl * * @author william.liangf */ publicclassHelloServiceImplimplementsHelloService { public String hello(String name) { return"Hello " + name; } }
/* * Copyright 2011 Alibaba.com All right reserved. This software is the * confidential and proprietary information of Alibaba.com ("Confidential * Information"). You shall not disclose such Confidential Information and shall * use it only in accordance with the terms of the license agreement you entered * into with Alibaba.com. */ package com.alibaba.study.rpc.test; import com.alibaba.study.rpc.framework.RpcFramework; /** * RpcProvider * * @author william.liangf */ publicclassRpcProvider { publicstaticvoidmain(String[] args)throws Exception { HelloServiceservice=newHelloServiceImpl(); RpcFramework.export(service, 1234); } }
/* * Copyright 2011 Alibaba.com All right reserved. This software is the * confidential and proprietary information of Alibaba.com ("Confidential * Information"). You shall not disclose such Confidential Information and shall * use it only in accordance with the terms of the license agreement you entered * into with Alibaba.com. */ package com.alibaba.study.rpc.test; import com.alibaba.study.rpc.framework.RpcFramework; /** * RpcConsumer * * @author william.liangf */ publicclassRpcConsumer { publicstaticvoidmain(String[] args)throws Exception { HelloServiceservice= RpcFramework.refer(HelloService.class, "127.0.0.1", 1234); for (inti=0; i < Integer.MAX_VALUE; i ++) { Stringhello= service.hello("World" + i); System.out.println(hello); Thread.sleep(1000); } } }