记住这一时刻,世界赛中,我们夺冠了。
对于动态代理来说,先来一篇简单的小例子。
代码结构介绍:
RpcUserService:业务接口类
RpcUserServiceImpl:业务实现类。
RpcFramework:工具类,暴露Service实现。返回动态代理对象
MyInvocation:InvocationHandler实现类,动态代理真正调用的方法。
RpcConsumer:消费者端启动类
RpcProvider:提供者启动类
执行过程
Service接口与实现
public interface RpcUserService { String hello(String name); }
public class RpcUserServiceImpl implements RpcUserService { @Override public String miss(String name) { return name + "I miss you and you are getting better and better"; } }
工具类 工具类的监听,以及对象的序列化等都是阻塞式的,有兴趣的可以改为非阻塞的哦。
public class RpcFramework { @SuppressWarnings("all") public static void export(final Object service, int port) throws Exception { if (service == null) { throw new NullPointerException("service null"); } if (port <= 0 || port > 65535) { throw new IllegalArgumentException(" Invalid port " + port); } System.out.println(" Export service: " + service.getClass().getName() + " on port " + port); ServerSocket server = new ServerSocket(port); for (; ; ) { final Socket socket = server.accept(); System.out.println("建立起与客户端的链接"); new Thread(new Runnable() { @Override public void run() { try { ObjectInputStream objInput = new ObjectInputStream(socket.getInputStream()); try { String methodName = objInput.readUTF(); Class<?>[] parameterTypes = (Class<?>[]) objInput.readObject(); Object[] arguments = (Object[]) objInput.readObject(); ObjectOutputStream objOuput = new ObjectOutputStream(socket.getOutputStream()); try { Method method = service.getClass().getMethod(methodName, parameterTypes); System.out.println("服务端方法名" + method.getName()); System.out.println("服务端参数" + arguments); Object result = method.invoke(service, arguments); System.out.println(result); objOuput.writeObject(result); } catch (Throwable t) { objOuput.writeObject(t); } finally { objOuput.close(); } } finally { objInput.close(); } } catch (Exception ex) { ex.printStackTrace(); } finally { if (socket != null) { try { socket.close(); } catch (IOException e) { e.printStackTrace(); } } } } }).start(); } } public static <T> T refer(final Class<T> interfaceClass, final String host, final int port) throws Exception { if (interfaceClass == null) { throw new IllegalArgumentException(" interfaceClass is 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); MyInvocation invocation = new MyInvocation(host,port); T t = (T)Proxy.newProxyInstance(interfaceClass.getClassLoader(), new Class<?>[]{interfaceClass},invocation); return t; } }
InvocationHandler实现类
public class MyInvocation implements InvocationHandler { private String host; private int port; MyInvocation(String host, int port) { this.host = host; this.port = port; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Socket socket = new Socket(host, port); try { ObjectOutputStream objOuput = new ObjectOutputStream(socket.getOutputStream()); try { System.out.println("方法的名字:" + method.getName()); objOuput.writeUTF(method.getName()); objOuput.writeObject(method.getParameterTypes()); objOuput.writeObject(args); ObjectInputStream objInput = new ObjectInputStream(socket.getInputStream()); try { Object result = objInput.readObject(); System.out.println(result); if (result instanceof Throwable) { System.out.println("出错了"); throw (Throwable) result; } return result; } finally { objInput.close(); } } finally { objOuput.close(); } } catch (Exception e) { e.printStackTrace(); } finally { socket.close(); } return null; } }
提供者启动类
public class RpcProvider { public static void main(String[] args)throws Exception { RpcUserService service = new RpcUserServiceImpl(); RpcFramework.export(service,30000); } }
消费者启动类
public class RpcConsumer { public static void main(String[] args)throws Exception { RpcUserService service = RpcFramework.refer(RpcUserService.class,"127.0.0.1",30000); for(int i=0;i<365;i++){ String hello = service.miss("wxy" + i); System.out.println(hello); Thread.sleep(1000); } } }
好了一个Socket结合动态代理的Rpc调用完成了。最后呢,大声的告诉我们,谁是冠军!