使用socket实现RPC通信的核心:暴露服务、建立连接,序列化与反序列化,动态代理
服务端:
/**
* API 接口
**/
public instance IOrderService {
String queryOrderList();
String queryOrderById(String id);
}
/**
*API RpcRequest
**/
public class Rpcquest implements Serializable{
private String className;
private String methodName;
private Object[] types;
private Object[] args;
}
/**
* provide 接口实现类
**/
public class OrderService implements IOrderService {
@Override
public String queryOrderList() {
return "QUERT ORDER LIST";
}
@Override
public String queryOrderById(String id) {
return "QUERY ORDER BY ID";
}
}
/**
* provide 启动类
**/
public static void BootStart{
// 实例化接口
IOrderService orderService = new IOrderService();
//实例化代理
RpcProxyService rpcProxyService = new RpcProxyService();
rpcProxyService.publisher(orderService, 8080);
}
/**
* provide 动态代理类
**/
public class RpcProxyService {
private ExecutorService executorService = Executors.newCachedThread(20);
public void publisher(Object service, int port) {
//建立连接
SocketService socketService = new SocketService(port);
while (true) {
Socket socket = socketServce.accept();
executorService.execute(new ProcessorHandler(socket, service));
}
}
}
/**
* provide 线程类
* 在线程中处理监听
**/
public class ProcesserHandler implements Runnable {
private Socket socket;
private Object service;
public ProcesserHandler (Socket socket, Object service) {
this.socket = socket;
this.service = service;
}
@Override
public Object run(){
//接收信息
ObjectInputStream inputStream = new ObjectInputStream(socket.getInputStream());
RpcRequest request = (RpcRequest) inputStream.readObject();
Object obj = invoke(request);
ObjectOutputStream outputStream = new ObjectOutputStream(socket.getOutputStream());
outputStream .writeObject(obj);
outputStream.flush();
}
public Object invoke(RpcRequest request) {
Class clazz = Class.forName(request.getClassName());
Method method = clazz.getMethod(request.getMethodName(), request.getTypes());
return mehtod.invoke(service, requeset.getArgs());
}
}
客户端:
/**
* 启动类
**/
public class app {
public static void main (String[] args) {
//远程调用IOrdeService接口,
IOrderService orderService = null;
//通过代理类加载
RpcProxyClient rpcProxyClient = new RpcProxyClient();
orderService = rpcProxyClient.clientProxy(IOrderService.class, "localhost", 8080);
//调用接口
sout(orderService.queryOrderList());
}
}
/**
* 代理类
**/
public class RpcProxyClient {
public T clientProxy(final Class> instanceCls, final String host, final int port) {
return Proxy.newProxyInstance(instanceCls.getClassLoader(), new Class> {instanceCls}, new RemoteInvocationHandler(host, port));
}
}
/**
* InvocationHandler
**/
public class RemoteInvocationHandler implements InvocationHandler{
private String host;
private int port;
public RemoteInvocationHandler (String host, int port) {
this.host = host;
this.port = port;
}
@Override
public Object invoke (Object proxy, Method method, Object[] args) {
//封装成通信协议
RpcNetTransport rpcNetTransport = new RpcNetTransport(host, port);
RpcRequest request = new RpcRequest();
request .setClassName(method.getDeclaringClass.getName());
request.setMethodName(method.getName());
request.setTypes(method.getParamTypes());
requeust.setArgs(args);
return rpcNetTransport.send(request);
}
}
/**
* 通信协议
**/
public class RpcNetTransport {
private String host;
private int port;
public RpcNetTransport (String host, int port) {
this.host = host;
this.port = port;
}
public Object send (RpcRequest request) {
Socket socket = new Socket(host, port);
ObjectOutputStream outputStream = new ObjectOutputStream(socket.getOutputStream());
outputStream.writerObject(request);
outputStream.flush();
ObjectInputStream inputStream = new ObjectInputStream(socket.getInputStream());
return inputStream.readObject();
}
}
注解版RPC中需要注意两个spring的类:
其中涉及到一个模式:Mediator(中介者模式)
BeanPostProcessor也称为Bean后置处理器,它是Spring中定义的接口,在Spring容器的创建过程中(具体为Bean初始化前后)会回调BeanPostProcessor中定义的两个方法。BeanPostProcessor的源码如下:
public interface BeanPostProcessor {
Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;
Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;
}
其中postProcessBeforeInitialization方法会在每一个bean对象的初始化方法调用之前回调;postProcessAfterInitialization方法会在每个bean对象的初始化方法调用之后被回调。
BeanPostProcessor的执行是定义在容器的刷新过程中,容器刷新对象具体的方法为:AbstractApplicationContext.refresh()。在refresh方法执行的调用栈中会去调用AbstractAutowireCapableBeanFactory.doCreateBean()方法。
服务端
/**
* 注解类,所有有该注解的自动进行加载
**/
@Target(ElementType.TYPT)
@Retention(RetentionPolicy.RUNTIME)
@Component
public @instance GpRemoteService {
}
/**
* 实现类
**/
@GpRemoteService
public class OrderService implements IOrderService {
@Override
public String queryOrderList() {
return "QUERT ORDER LIST";
}
@Override
public String queryOrderById(String id) {
return "QUERY ORDER BY ID";
}
}
/**
* 启动类,Spring的启动
**/
@Configuration
@ComponentScan("com.**.**")
public class BootStart{
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(BootStart.class);
}
/**
* spring 容器加载完成后,执行BeanPostProcessor的实现类,将带有注解的类加载到容器中
**/
@Component
public class InitialMerdiator implements BeanPostProcessor {
@Overrride
public Object postProcessorAfterInitialization(Object bean, String beanName) throws BeansException {
if(bean.getClass().isAnnotationPresent(GpRemoteService.class)) {
Method[] methods = bean.getClass().getDeclaredMethods();
for(Method method: methods) {
String key = bean.getClass().getInterfaces()[0].getName() + "." + method.getName();
BeanMethodd beanMethod = new BeanMethod();
beanMethod.setBean(bean);
beanMethod.setMethod(method);
Merdiator.map.put(key, method);
}
}
return bean;
}
}
/**
* beanMethod
**/
public class BeanMethod {
private Object bean;
private Method method;
……
}
/**
* Merdiator
**/
public class Merdiator{
public static Map map=new ConcurrentHashMap<>();
private Merdiator instance;
private Merdiator(){}
public static Merdiator getInstance(){
if (instance == null) {
synchronized(Merdiator.class) {
if (instance == null) {
instance = new Merdiator();
}
}
}
}
//根据request查询出需要的接口
public Object processor(RpcRequest request) {
String key = request.getClassName() + "." + request.getMethodName();
BeanMethod beanMethod = map.get(key);
if (beanMethod == null) {
return null;
}
Object bean = beanMethod.getBean();
Method method = beanMethod.getMethod();
return method.invoke(bean, request.getArgs());
}
}
/**
* spring 容器启动完成之后,会发布一个ContextRefreshedEvent。因此socket服务端监听发生在该事件中
**/
@Component
public class SocketServiceInitial implements ApplicationListener {
private finish ExecutorService executorService = Executors.newCachedThread();
@Override
public void onApplicationEvent(ContextRefreshedEvent contextRefreshendEvent) {
SocketService socketService = null;
try{
socketService = new SocketService(8080);
while(true) {
Socket socket = socketService.accpect();
executorService.execute(new ProcessorHandler(socket));
}
}
}
}
public class ProcessorHandler implements Runnable {
private Socket socket;
public ProcessorHandler(Socket socket) {
this.socket = socket;
}
@Override
private void run(){
ObjectInputStream inputStream = null;
ObjectOutputStream outputStream = null;
try {
inputStream = new ObjectInputStream(socket.getInputStream());
RpcRequest request = (RpcRequest)inputStream.readObject();
//路由
Mediator mediator = Mediator.getInstance();
Object rs = mediator.processor(request);
//将查询到的接口传到消费端
outputStream = new ObjectOutputStream(socket.getOutpustStream());
outputStream.writeObject(rs);
outputStream.flush();
}
}
}
消费端
@Target(ElementType.FILED)
@Retention(RetentionPolicy.RUNTIME)
@Comonent
publci @interface GpReference{
}
@SpringbootApplication
public class UserServiceMain (
public static void main (String[] args) {
SpringApplication.run(UserServiceMain.class);
}
)
/**
* 加载时机:初始化之前
* 在初始化之前,需要将动态代理类加载到IOC容器中
**/
@Component
public class ReferenceInvokeProxy implements BeanPostProcessor {
@Autowried
private RemoteInvocationHandler invocationHandler;
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
Filed[] fileds = bean.getClass().getDeclaredFileds();
for(Filed filed: fileds) {
if(filed.isAnnotationPresent(GpReference.class)) {
filed.setAccessible(true);
//针对GpReference注解进行代理
Object proxy = Proxy.newProxyInstance(filed.getType().getClassLoad(), new Class>[]{filed.getType()}, invocationHandler);
//相当于针对加了GpReference的注解,设置了一个代理,这个代理的实现是inovcationHandler
field.set(bean,proxy);
}
}
return bean;
}
}
@Component
public class RemoteInvocationHandler implements InvocationHandler {
@Value("${Gp.host}")
private String host;
@Value("${GP.port}")
private int port;
@Override
public Object invoke(Object proxy, Method method, Object[] args) {
//建立连接
RpcNetTransport rpcNetTransport=new RpcNetTransport(host,port);
//传递数据
RpcRequest request = new RpcRequest();
request.setClassName(method.getDeclaringClass().getName());
request.setMethodName(method.getName());
request.setTypes(method.getParamterTypes());
request.setArgs(args);
return rpcNetTransport.send(request)
}
}
@RestController
public class TestController{
@GpReference
private IOrderService orderService;
@GetMapping("/test")
public String queryOrderList(){
return orderService.queryOrderList();
}
}