RPC-准备阶段

他是一种通过网络从远程计算机程序上请求服务,不需要了解底层网络的技术

完整的RPC网络调用流程

  1. 服务消费方:以本地调用方式调用客户端存根;
  2. 什么叫客户端存根?就是远程方法在本地的模拟对象,一样的也有方法名,也有方法参数,client stub 接收到调用后负责将方法名方法的参数等包装,并将包装后的信息通过网络发送到服务端。
  3. 服务端收到消息后,交给代理存根在服务器的部分后尽心解码为实际的方法名和参数
  4. server stub 根据解码结果调用服务器上本地的实际服务。
  5. 本地服务执行,将结果返回给server stub
  6. server stub将返回的结果打包成消息并发送给消费方
  7. client stub接受到消息进行解码
  8. 消费方得到最后的结果。

写一个类似框架,需要解决几个不常用的问题

  1. 代理模式
  2. 序列化问题 利用java的相关机制,也就是Serializable
  3. 通信问题 BIO
  4. 登记的服务实力化问题 使用反射机制
    • 在运行时候,判断任意一个对象所属的类
    • 运行时候构造人意一个类的对象
    • 运行时候,判断任意一个类所就有的方法和成员变量
    • 运行时候,调用任意一个对象的方法
    • 生成动态代理
      下边的代码简单的解释一下上述的问题

1、 代理模式

//静态代理方法的实现
/**
 * 接口类
 */
public interface IGetServer {
    void choice(String desc);
}

 /**
 * 接口的实现类
 */
public class Receptionist implements IGetServer {
    public void choice(String desc) {
        System.out.println(desc);
    }
}
/**
*代理类
*/
public class ProxyServer  implements InvocationHandler {
    private  Object receptionist;//实现类的实例
    public ProxyServer(Object receptionist) {
        this.receptionist = receptionist;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("执行对应的方法之前执行的方法");
        //实际的方法
        Object result = method.invoke(receptionist,args);
        System.out.println("执行之后执行的方法");
        return result;
    }
}


//-----------------------------------
/**
*调用类
*/

public class Proxyclient {
    //调用代理方法
    public static void main(String[] args) {
        IGetServer ig = (IGetServer) Proxy.newProxyInstance(IGetServer.class.getClassLoader(),new Class[]{IGetServer.class},new ProxyServer(new Receptionist()));
        ig.choice("这里是我要传入的参数");
    }

}

2、 序列化

bean同时实现了Se rierizable就好了


public class SerialBean implements Serializable {
    private final String name;
    private  final  String age;

    public SerialBean(String name, String age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public String getAge() {
        return age;
    }
}

主要用到的是如何调用序列化和反序列化


public class TestSerial {
    public static void main(String[] args) {
        setSer();//序列化
        getSer();
    }


    //序列化
    private static void setSer()  {
        SerialBean bean = new SerialBean("Mark","123");
        List<String> list= new ArrayList<String>();
        list.add("my name");
        list.add( "is " );
        list.add("mark");

        ObjectOutputStream os = null;
        try {
            os = new ObjectOutputStream(new FileOutputStream("/Users/weblogic/study/Serial.txt"));
            os.writeObject(bean);
            os.writeObject(list);
            os.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
    public static void getSer(){
        try {
            ObjectInputStream is = new ObjectInputStream(
                    new FileInputStream("/Users/weblogic/study/Serial.txt"));
            SerialBean bean = (SerialBean) is.readObject();
            System.out.println(bean.getAge());
            System.out.println(bean.getName());
            List tempList  = (List) is.readObject();
            for(Iterator iterable = tempList.iterator();iterable.hasNext();){
                System.out.println(iterable.next());
            }
            is.close();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

3、 反射


public class RefleDemo  {
    public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
        //实例化对象的标准用法
        Servant servant = new Servant();
        servant.service("hello|");
      //  全限定名拿到勒的class对象
        Class servantClazz = Class.forName("cn.baip.netty.rpc.refle.Servant");
        //通过class对象拿到类的实例
        Servant servant1 = (Servant) servantClass.newInstance();

        //拿到所有的方法名
        Method[] methods = servantClazz.getMethods();
        for (Method method :methods){
            System.out.println(method.getName());//方法的名称
            if(method.getName().equals("toString")){
                try {
                    System.out.println(method.invoke(servant1,null));
                    System.out.println("执行,"+method.invoke(servantClazz.newInstance(),null));
                } catch (InvocationTargetException e) {
                    e.printStackTrace();
                }
            }
        }

    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值