RPC简易版(一)

在本系列文章中,我将利用netty实现一个简单的RPC。
首先,在本节中,主要介绍的是使用spring的FactoryBean和Proxy,进行客户端Bean的创建。

在RPC中,我们需要远程调用一些方法,但是具体能调用哪些方法,以及参数是什么,这个最方便的,就是我们能够和调用本地方法一下去调用远程方法。

我们尝试一下我们日常调用本地方法的方式,通过接口的方式,和实际的实现进行解耦,这个是我们在调用本地方法所熟悉的方法,那么我们是不是可以也使用这种方式来实现RPC呢?当然也是可以的。

通过上面这种方式,客户端只需要拿到对应的方法签名,这里我们先通过依赖二方库中接口,后面我们将介绍通过泛化的方式进行调用。所以客户端能通过接口的定义,可以感知对应远程调用的方法签名,说白了,就是在本地可以有一个接口类,里面定义了调用的方法。

如下,我们先定义了一个接口

/**
 * @author admin
 */
public interface InterfaceC {

    void process(int a , int b);
}

在客户端,将通过二房库的形式依赖了这个接口。我们的目标方式应该是下面这种

/**
 * @author admin
 */
public class RpcTest {

    private InterfaceC interfaceC;

    public  void test(int a , int b) {
        interfaceC.process(a , b);
    }

    public InterfaceC getInterfaceC() {
        return interfaceC;
    }

    public void setInterfaceC(InterfaceC interfaceC) {
        this.interfaceC = interfaceC;
    }
}

直接定义一个field是InterfaceC类型的,然后直接调用这个接口对应的方法就可以了,这个就非常类似我们本地的调用方式。那为了实现这个目标,spring的FactoryBean和Java的Proxy就可以为我们提供帮助。

首先,我们先实现一个FactoryBean,如下

import org.springframework.beans.factory.FactoryBean;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * @author admin
 */
public class RpcConsumerBean implements FactoryBean {
    private String interfaceName;

    private Object target;

    private Object proxyObj;

    public void init() throws ClassNotFoundException {
        proxyObj = Proxy.newProxyInstance(this.getClass().getClassLoader(), new Class[] {Class.forName(interfaceName)},
            new InvocationHandler() {
                @Override
                public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                    System.out.println("call rpc before");
                    System.out.println("method : " + method.getName() + " , args : " + args);
                    System.out.println("rpc call");
                    System.out.println("call rpc after");
                    return null;
                }
            });
    }

    @Override
    public Object getObject() throws Exception {
        return proxyObj;
    }

    @Override
    public Class getObjectType() {
        return proxyObj == null ? Object.class : proxyObj.getClass();
    }

    public void setInterfaceName(String interfaceName) {
        this.interfaceName = interfaceName;
    }

    public void setTarget(Object target) {
        this.target = target;
    }
}

在这个FactoryBean中,我们可以在bean的初始化过程中,通过代理的方式,代理掉全部的方法,进行远程的调用,具体的远程调用实现,我们会在后面继续介绍。

另外,下面是我们具体的xml配置





    
        
    

    
        
    

通过上面的这种方式,我们就实现了类似本地调用的方式,进行远程的rpc调用。后面将继续介绍更多的内容,慢慢实现一个简易的rpc。

你可能感兴趣的:(RPC简易版(一))