RPC远程过程调用,可以采用TCP方式支持,也可采用HTTP方式进行支持(WebService也支持)。传值可选用JSON、XML或者二进制进行传递,此示例为了提高效率采用二进制流进行传递(为追求序列化效率,选用开源Hessian对对象进行序列化,java自身携带了序列化反序列化方法,此处选用自身提供的)
1.添加接口
package test01.producer;
public interface Pro01 {
String produce(String proName);
}
2.添加实现类
package test01.producer;
public class Pro01Impl implements Pro01 {
@Override
public String produce(String proName) {
System.out.println(proName);
return "server say hi";
}
}
3.添加调用时对象,包含要访问类类型、方法名以及方法中参数
package test01.common;
import java.io.Serializable;
import java.util.List;
public class RemoteObj implements Serializable {
private static final long serialVersionUID = 5803202976390284233L;
private String className;
private String methodName;
private List<ArgsObj> argsList;
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 List<ArgsObj> getArgsList() {
return argsList;
}
public void setArgsList(List<ArgsObj> argsList) {
this.argsList = argsList;
}
}
4.添加参数对象,此处也可以不添加,根据内部通过反射获得类型
package test01.common;
import java.io.Serializable;
public class ArgsObj implements Serializable {
private static final long serialVersionUID = 6879837066786687313L;
private String argsType;
private Object argsValue;
public String getArgsType() {
return argsType;
}
public void setArgsType(String argsType) {
this.argsType = argsType;
}
public Object getArgsValue() {
return argsValue;
}
public void setArgsValue(Object argsValue) {
this.argsValue = argsValue;
}
}
5.以TCP方式发布服务
package test01.producer;
import java.net.ServerSocket;
import java.net.Socket;
import test.thread.ServerRecive;
/**
* 此示例只是简单实现,可将服务地址注册到zookeeper,访问时通过zookeeper获取服务地址
* @author zsx
*
*/
public class ProService {
public static void main(String[] args) throws Exception {
ServerSocket serverSocket = new ServerSocket(9999);
while(true) {
Socket socket = serverSocket.accept();
new Thread(new ServerRecive(socket)).start();
}
}
}
package test.thread;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.lang.reflect.Method;
import java.net.Socket;
import java.util.List;
import test01.common.ArgsObj;
import test01.common.RemoteObj;
import test01.producer.Pro01;
import test01.producer.Pro01Impl;
public class ServerRecive implements Runnable {
private Socket socket;
public ServerRecive(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
try {
InputStream inputStream = socket.getInputStream();
//序列化对象
ObjectInputStream objectInputStream = new ObjectInputStream(inputStream);
RemoteObj remoteObj = (RemoteObj)objectInputStream.readObject();
//类-方法-参数
String className = remoteObj.getClassName();
String methodName = remoteObj.getMethodName();
List<ArgsObj> argsList = remoteObj.getArgsList();
//获取参数类型
Class<?>[] clazzs = null;
Object[] objs = null;
if(argsList != null && argsList.size() > 0) {
clazzs = new Class[argsList.size()];
objs = new Object[argsList.size()];
for(int i = 0; i < argsList.size(); i++) {
clazzs[i] = Class.forName(argsList.get(i).getArgsType());
objs[i] = argsList.get(i).getArgsValue();
}
}
//此处如果实现IoC框架应该从IoC获取对象,暂不加入IoC框架
if(className.equals(Pro01.class.getName())) {
Pro01 pro01 = new Pro01Impl();
Method method = pro01.getClass().getMethod(methodName, clazzs);
//响应对象,包含类型,包含响应值
Object obj = method.invoke(pro01, objs);
OutputStream outputStream = socket.getOutputStream();
ObjectOutputStream objectOutputStream = new ObjectOutputStream(outputStream);
objectOutputStream.writeObject(obj);
}
} catch (Exception e) {
}
}
}
6.编写客户端测试访问
package test01.consumer;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
import test01.common.ArgsObj;
import test01.common.RemoteObj;
import test01.producer.Pro01;
public class Con01 {
public static void main(String[] args) throws Exception {
Socket socket = new Socket("127.0.0.1", 9999);
OutputStream outputStream = socket.getOutputStream();
ObjectOutputStream objectOutputStream = new ObjectOutputStream(outputStream);
RemoteObj remoteObj = new RemoteObj();
remoteObj.setClassName(Pro01.class.getName());
remoteObj.setMethodName("produce");
List<ArgsObj> argsList = new ArrayList<>();
ArgsObj argsObj = new ArgsObj();
argsObj.setArgsType("java.lang.String");
argsObj.setArgsValue("hello,Pro01");
argsList.add(argsObj);
remoteObj.setArgsList(argsList);
objectOutputStream.writeObject(remoteObj);
objectOutputStream.flush();
InputStream inputStream = socket.getInputStream();
ObjectInputStream objectInputStream = new ObjectInputStream(inputStream);
Object object = (Object)objectInputStream.readObject();
if(object == null) {
} else {
System.out.println(object);
}
socket.close();
}
}
注意:使用时需注意对象实现Serializable接口,接口间以流通信,需支持对象序列化和反序列化