动态代理3-手写dubbo-RPC

项目结构

MyDubboClient

MyDubboServer

/MyDoubboInterface/src/main/java/com/jt/service/CartService.java

package com.jt.service;

public interface CartService {
     String findCartById(Long id);
}

/MyDubboClient/src/main/java/com/jt/controller/CartController.java

package com.jt.controller;

import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.net.Socket;


import com.jt.service.CartService;

public class CartController {

    public static void main(String[] args) {
        //1.得到动态代理对象
        Object proxyObject=getProxyObject(CartService.class);
        //2.通过动态代理对象调用目标方法
        CartService cartService=(CartService) proxyObject;
        cartService.findCartById(11L);
        //3.调用了目标方法,java虚拟机会执行invoke()
    }
    static class MyInvocationHandler implements
    InvocationHandler{
        String interfaceName;
        public MyInvocationHandler(String interfaceName) {
            this.interfaceName = interfaceName;
        }
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            try {
                //建立和服务器连接
                Socket socket=new Socket("127.0.0.1", 9000);
                //发送接口名
                OutputStream outputStream=socket.getOutputStream();
                ObjectOutputStream objectOutputStream=new ObjectOutputStream(outputStream);
                //发送方法名
                objectOutputStream.writeUTF(interfaceName);
                //发送参数类型
                objectOutputStream.writeUTF(method.getName());
                objectOutputStream.writeObject(method.getParameterTypes());
                objectOutputStream.writeObject(args);
                //发送参数
                InputStream inputStream=socket.getInputStream();
                ObjectInputStream objectInputStream=new ObjectInputStream(inputStream);
                //接收服务器结果
                Object serverReturnResult = objectInputStream.readObject();
                System.out.println("通过网络收到"+serverReturnResult);
                socket.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }
    }
    static Object getProxyObject(Class<?> intefraceInfo){
        //创建动态类需要类加载器和方法信息
        ClassLoader classLoader=intefraceInfo.getClassLoader();
        Class<?>[] methodInfo={intefraceInfo};
        //通过动态代理对象执行目标方法时,系统自动调用invoke
        MyInvocationHandler myinvocationHandler=new MyInvocationHandler(intefraceInfo.getName());
        return Proxy.newProxyInstance(classLoader, methodInfo, myinvocationHandler);
    }
}

/MyDubboServer/src/main/java/com/jt/server/MyDubboServer.java

package com.jt.server;

import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.lang.reflect.Method;
import java.net.ServerSocket;
import java.net.Socket;

public class MyDubboServer {

    public static void main(String[] args) {
        try {
            //监听9000端口号
            ServerSocket serverSocket=new ServerSocket(9000);
            System.out.println("启动服务器。。。");
            while(true)
            {
                //接收用户的请求
                Socket socket=serverSocket.accept();
                InputStream inputStream=socket.getInputStream();
                ObjectInputStream objectInputStream=new ObjectInputStream(inputStream);
                
                //读取接口名
                String interfaceName =objectInputStream.readUTF();
                //读取方法名
                String methodName = objectInputStream.readUTF();
                //读取参数类型                                                                                                                                                                                                                                                                                                                               
                Class<?>[] pType=(Class<?>[]) objectInputStream.readObject();
                //读取参数
                Object[] p=(Object[]) objectInputStream.readObject();
                //通过反射执行方法
                //根据接口名...找到实现类...
                //客户端发送不同的接口名,调用不同的实现类
                //map(interfacename,Impl)
                Class<?> imClassInfo=Class.forName(interfaceName+"Impl");
                //通过反射创建对象
                Object implObject=imClassInfo.newInstance();
                //通过反射执行方法
                
                Method method=imClassInfo.getMethod(methodName, pType);
                Object result = method.invoke(implObject, p);
                //执行的结果返回给客户端
                OutputStream outputStream=socket.getOutputStream();
                ObjectOutputStream objectOutputStream=new ObjectOutputStream(outputStream);
                objectOutputStream.writeObject(result);
                break;
            }
            serverSocket.close();
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
        }
    }

}

/MyDubboServer/src/main/java/com/jt/service/CartServiceImpl.java

package com.jt.service;

public class CartServiceImpl implements CartService {

    @Override
    public String findCartById(Long id) {
        System.out.println("CartServiceImpl.findCartById()");
        return "cart";
    }

}

输出结果

启动服务器。。。
通过网络收到cart
mydubbo总结

RPC:远程过程(进程)调用,跨进程调用
Servlet也实现了跨进程调用
普通用户浏览器访问servlet
通过httpClient,ajaxt访问

1服务端 new ServerSocket(9000)启动服务器
2客户端 通过proxy.newProxyInstance得到动态代理对象
3客户端 通过动态代理对象执行目标方法
4客户端 虚拟机自动调用InvocationHandler实现类的invoke()方法
5客户端 invoke()方法中联网
5.1new Socket("127.0.0.1",9000);
5.2objectOutputStream.writeUTF()得到对象输出流,写接口名,方法名
5.3objectOutputStream.writeObject()写参数类型,以及参数-参数类型和参数是对象
6服务端 accept接收请求
7服务端 objectInputStream.readUTF()读接口名,方法名
8服务端 objectInputStream.readObject()读参数类型和参数
9服务端 根据接口名找到实现类
10服务端 用反射执行方法
10.1得到类信息classInfo.newInstance()
10.2动态找方法classInfo.getMethod(方法名,参数类型)
10.3执行方法method.invoke(object,args)
11服务端 通过对象输出流objectOutputStream.writeObject()返回数据
12客户端 通过对象输入流objectInputStream.readObject()读结果


RPC
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容