基于Proxy模仿dubbo的RPC实现
用于生成Class对象
package com.liuzn.test.util;
public class ClassFactory {
@SuppressWarnings("unchecked")
public static <T> Class<T> getClass(String className) {
try {
return (Class<T>) Class.forName(className);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return null;
}
}
请求代理对象,封装Method对象以及请求参数
package com.liuzn.test.entity;
import java.io.Serializable;
public class ProxyRequest implements Serializable {
private static final long serialVersionUID = 2358035686978399918L;
private MethodEntity method;
private Object[] args;
/**
* @return the method
*/ public MethodEntity getMethod() {
return method;
}
/**
* @param method the method to set
*/ public void setMethod(MethodEntity method) {
this.method = method;
}
/**
* @return the args
*/ public Object[] getArgs() {
return args;
}
/**
* @param args the args to set
*/ public void setArgs(Object[] args) {
this.args = args;
}
}
用于封装请求数据的Method实体,封装了调用的接口信息,参数信息,后续应该继续加入version信息等
package com.liuzn.test.entity;
import java.io.Serializable;
public class MethodEntity implements Serializable {
private static final long serialVersionUID = 8247122061445501661L;
private String methodName;
private Class[] parameterTypes;
/**
* @return the methodName
*/ public String getMethodName() {
return methodName;
}
/**
* @param methodName the methodName to set
*/ public void setMethodName(String methodName) {
this.methodName = methodName;
}
/**
* @return the parameterTypes
*/ public Class[] getParameterTypes() {
return parameterTypes;
}
/**
* @param parameterTypes the parameterTypes to set
*/ public void setParameterTypes(Class[] parameterTypes) {
this.parameterTypes = parameterTypes;
}
}
基于Proxy实现Server端代理对象
package com.liuzn.test;
import com.liuzn.test.entity.MethodEntity;
import com.liuzn.test.entity.ProxyRequest;
import com.liuzn.test.util.ClassFactory;
import java.io.*;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.ServerSocket;
import java.net.Socket;
public class Service {
public static void main(String[] args) {
String infcName = "com.liuzn.test.Interface";
String implName = "com.liuzn.test.InterfaceImpl";
ServerSocket socket = null;
try {
Class bean = ClassFactory.getClass(implName);
Object o = bean.newInstance();
socket = new ServerSocket(2129);
while (true) {
Socket accept = socket.accept();
InputStream inputStream = accept.getInputStream();
OutputStream outputStream = accept.getOutputStream();
BufferedInputStream bis = null;
ObjectInputStream ois = null;
try {
while (true) {
bis = new BufferedInputStream(inputStream);
ois = new ObjectInputStream(bis);
ProxyRequest request = (ProxyRequest) ois.readObject();
MethodEntity method = request.getMethod();
Object[] args2 = request.getArgs();
String methodName = method.getMethodName();
Class interfaceName = ClassFactory.getClass(infcName);
Method declaredMethod = interfaceName.getDeclaredMethod(methodName, method.getParameterTypes());
Object result = declaredMethod.invoke(o, args2);
ByteArrayOutputStream bo = null;
ObjectOutputStream oo = null;
try {
bo = new ByteArrayOutputStream();
oo = new ObjectOutputStream(bo);
oo.writeObject(result);
byte[] byteArray = bo.toByteArray();
outputStream.write(byteArray);
outputStream.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (bo != null) {
bo.close();
}
if (oo != null) {
oo.close();
}
}
}
} catch (IOException | IllegalAccessException e) {
// TODO Auto-generated catch block
// e.printStackTrace();
} finally {
if (bis != null) {
bis.close();
}
if (ois != null) {
ois.close();
}
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} finally {
try {
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
基于Proxy实现client端代理远端API接口调用
package com.liuzn.test;
import com.liuzn.test.entity.MethodEntity;
import com.liuzn.test.entity.ProxyRequest;
import com.liuzn.test.util.ClassFactory;
import java.io.*;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.net.Socket;
class ProxyInvocationHandler implements InvocationHandler {
private Socket client = null;
private InputStream inputStream = null;
private OutputStream outputStream = null;
ProxyInvocationHandler() {
try {
if (client == null) {
client = new Socket("127.0.0.1", 2129);
}
if (inputStream == null) {
inputStream = client.getInputStream();
}
if (outputStream == null) {
outputStream = client.getOutputStream();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
ProxyRequest req = new ProxyRequest();
MethodEntity methodEntity = new MethodEntity();
methodEntity.setMethodName(method.getName());
Class[] parameterTypes = method.getParameterTypes();
methodEntity.setParameterTypes(parameterTypes);
req.setMethod(methodEntity);
req.setArgs(args);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(req);
oos.flush();
outputStream.write(bos.toByteArray());
outputStream.flush();
BufferedInputStream bis = new BufferedInputStream(inputStream);
ObjectInputStream ois = new ObjectInputStream(bis);
Object readObject = ois.readObject();
oos.flush();
bos.flush();
oos.close();
bos.close();
return readObject;
}
public void clear() {
try {
if (client != null) {
client.close();
}
if (outputStream != null) {
outputStream.close();
}
if (inputStream != null) {
inputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
class ProxyTest {
public void proxy() {
// 1.获取 interface 名称
String className = "com.liuzn.test.Interface";
// 2. 取得接口反射对象
Class clazz = ClassFactory.getClass(className);
if (clazz == null) {
System.out.println(className+"未找到");
return; }
ClassLoader classLoader = clazz.getClassLoader();
// 3.代理实现类
InvocationHandler h = new ProxyInvocationHandler();
Interface inter = (Interface) Proxy.newProxyInstance(classLoader, new Class[] { clazz }, h);
// while (true) {
Integer len = inter.test("test");
System.out.println("长度为" + len);
String str = inter.testString("test");
System.out.println(str);
Response res = inter.testResponse("test");
System.out.println(res.getName());
// try {
// Thread.sleep(5000);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
// }
}
}
public class Test {
public static void main(String[] args) {
ProxyTest pt = new ProxyTest();
pt.proxy();
}
}
测试接口
package com.liuzn.test;
public interface Interface{
Integer test(String testName);
String testString(String testString);
Response testResponse(String name);
}
测试接口实现
package com.liuzn.test;
public class InterfaceImpl implements Interface {
@Override
public Integer test(String testName) {
return testName.length();
}
@Override
public String testString(String testString) {
String result = "service: "+testString;
return result;
}
@Override
public Response testResponse(String name) {
Response response = new Response();
response.setName(name);
return response;
}
}