随着服务器的压力不断的上升,rmi的重要性日益突出
今天就简单的剖析以下RMI的底层实现原理
**************************************************************************
(1)rmi调用承载对象:call
import java.io.*; public class Call implements Serializable{ private String className; //表示类名 private String methodName; //表示方法名 private Class[] paramTypes; //表示方法参数类型 private Object[] params; //表示方法参数值 private Object result; //表示方法的返回值或者方法抛出的异常 public Call(){} public Call(String className,String methodName,Class[] paramTypes, Object[] params){ this.className=className; this.methodName=methodName; this.paramTypes=paramTypes; this.params=params; } public String getClassName(){return className;} public void setClassName(String className){this.className=className;} public String getMethodName(){return methodName;} public void setMethodName(String methodName){this.methodName=methodName;} public Class[] getParamTypes(){return paramTypes;} public void setParamTypes(Class[] paramTypes){this.paramTypes=paramTypes;} public Object[] getParams(){return params;} public void setParams(Object[] params){this.params=params;} public Object getResult(){return result;} public void setResult(Object result){this.result=result;} public String toString(){ return "className="+className+" methodName="+methodName; } }
(2)客户端执行rmi调用
import java.io.*; import java.net.*; import java.util.*; public class SimpleClient { public void invoke()throws Exception{ Socket socket = new Socket("localhost",8000); OutputStream out=socket.getOutputStream(); ObjectOutputStream oos=new ObjectOutputStream(out); InputStream in=socket.getInputStream(); ObjectInputStream ois=new ObjectInputStream(in); //Call call=new Call("remotecall.HelloService","getTime",new Class[]{},new Object[]{}); Call call=new Call("remotecall.HelloService","echo",new Class[]{String.class},new Object[]{"Hello"}); oos.writeObject(call); call=(Call)ois.readObject(); System.out.println(call.getResult()); ois.close(); oos.close(); socket.close(); } public static void main(String args[])throws Exception { new SimpleClient().invoke(); } }
(服务器端更具call对象的相关信息,通过反射调用方法,并将结果返回给客户端)
import java.io.*; import java.net.*; import java.util.*; import java.lang.reflect.*; public class SimpleServer { private Map remoteObjects=new HashMap(); public void register(String className,Object remoteObject){ remoteObjects.put( className,remoteObject); } public void service()throws Exception{ ServerSocket serverSocket = new ServerSocket(8000); System.out.println("服务器启动."); while(true){ Socket socket=serverSocket.accept(); InputStream in=socket.getInputStream(); ObjectInputStream ois=new ObjectInputStream(in); OutputStream out=socket.getOutputStream(); ObjectOutputStream oos=new ObjectOutputStream(out); Call call=(Call)ois.readObject(); System.out.println(call); call=invoke(call); oos.writeObject(call); ois.close(); oos.close(); socket.close(); } } public Call invoke(Call call){ Object result=null; try{ String className=call.getClassName(); String methodName=call.getMethodName(); Object[] params=call.getParams(); Class classType=Class.forName(className); Class[] paramTypes=call.getParamTypes(); Method method=classType.getMethod(methodName,paramTypes); Object remoteObject=remoteObjects.get(className);------>>>至于这边为什么不用class newInstance得到一个新对象————>>>必须式注册的组件才能被访问 if(remoteObject==null){ throw new Exception(className+"的远程对象不存在"); }else{ result=method.invoke(remoteObject,params); } }catch(Exception e){result=e;} call.setResult(result); return call; } public static void main(String args[])throws Exception { SimpleServer server=new SimpleServer(); server.register("remotecall.HelloService",new HelloServiceImpl()); server.service(); } }