通过手撸RPC让你真正明白动态代理的强大之处

普通代理

  • 定义一个接口
public interface HelloInterface {
    void sayHello();
}
  • 定义一个被代理类
public class Hello implements HelloInterface{
    @Override
    public void sayHello() {
        System.out.println("Hello zhanghao!");
    }
}

如果我们单纯的使用普通代理,只需要将被代理类作为代理类的一个属性,然后代理类实现接口方法的时候调用被代理类的同名方法即可.

public class HelloProxy implements HelloInterface{
    private HelloInterface helloInterface = new Hello();
    @Override
    public void sayHello() {
        System.out.println("Before invoke sayHello" );
        helloInterface.sayHello();
        System.out.println("After invoke sayHello");
    }
}

动态代理代理对象—可以使用同一个代理类代理任意被代理类

public class ProxyHandler implements InvocationHandler{
    private Object object;
    public ProxyHandler(Object object){
        this.object = object;
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("Before invoke "  + method.getName());
        method.invoke(object, args);
        System.out.println("After invoke " + method.getName());
        return null;
    }
}

    public static void main(String[] args) {
        System.getProperties().setProperty("sun.misc.ProxyGenerator.saveGeneratedFiles", "true");

        HelloInterface hello = new Hello();
        
        InvocationHandler handler = new ProxyHandler(hello);

        HelloInterface proxyHello = (HelloInterface) Proxy.newProxyInstance(hello.getClass().getClassLoader(), hello.getClass().getInterfaces(), handler);

        proxyHello.sayHello();
    }
    输出:
    Before invoke sayHello
    Hello zhanghao!
    After invoke sayHello

动态代理代理接口—即便没有任何类的实例,也能使用动态代理(也能代理接口)

  • 定义一个接口
public interface Protocol {
    public int add(int a, int b);
}
  • 定义一个handle
class DyProxy implements InvocationHandler {
    Object object;

    DyProxy() {

    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws InvocationTargetException, IllegalAccessException {
        System.out.println(method.getName());
        System.out.println(args);
        return null;
    }
}
  • 使用接口方法
    public static void main(String[] args) throws IOException {

        Protocol proxyClass = (Protocol) Proxy.newProxyInstance(Protocol.class.getClassLoader(), new Class[]{Protocol.class}, new DyProxy());
        System.out.println(proxyClass.add(1, 2));
    }

自我实现RPC

只需要在动态代理代理接口的时候,在invoke函数里实现一个RPC通信即可

  • 协议
public interface Protocol {
    public int add(int a, int b);

    public int sub(int a, int b);
}
  • 服务器
package blm.myRPC;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * @ProjectName: hadoop_learn
 * @Package: blm.myRPC
 * @ClassName: Server
 * @Author: chenmengqi
 * @Description:
 * @Date: 2020/2/28 10:25 下午
 * @Version: 1.0
 */
public class Server implements Protocol {
    @Override
    public int add(int a, int b) {
        return a + b;
    }

    public int sub(int a, int b) {
        return a - b;
    }

    public static void main(String[] args) throws IOException, ClassNotFoundException {
        ServerSocket serverSocket = new ServerSocket(8006);
        Server server = new Server();

        while (true) {
            Socket accept = serverSocket.accept();

            ObjectInputStream objectInputStream = new ObjectInputStream(accept.getInputStream());

            Message message = (Message) objectInputStream.readObject();

            ObjectOutputStream objectOutputStream = new ObjectOutputStream(accept.getOutputStream());

            System.out.println(message.getMethod());

            if ("add".equals(message.getMethod())) {
                message.setRes(server.add(message.getArg1(), message.getArg2()));
            } else if ("sub".equals(message.getMethod())) {
                message.setRes(server.sub(message.getArg1(), message.getArg2()));
            }

            System.out.println(message);
            objectOutputStream.writeObject(message);
            
        }
    }
}

  • 客户端
public class Client {

    public static void main(String[] args) throws IOException {

        Protocol proxyClass = (Protocol) Proxy.newProxyInstance(Protocol.class.getClassLoader(), new Class[]{Protocol.class}, new DyProxy());
        System.out.println(proxyClass.add(2, 1));
        System.out.println(proxyClass.sub(2, 1));
    }
}


class DyProxy implements InvocationHandler {
    Socket socket;


    DyProxy() throws IOException {
        this.socket = new Socket("127.0.0.1", 8006);
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Message message = new Message();
        message.setMethod(method.getName());
        message.setArg1((int) args[0]);
        message.setArg2((int) args[1]);

        ObjectOutputStream objectOutputStream = new ObjectOutputStream(this.socket.getOutputStream());
        objectOutputStream.writeObject(message);
//        objectOutputStream.flush();
//        socket.shutdownOutput();

        ObjectInputStream objectInputStream = new ObjectInputStream(this.socket.getInputStream());
        message = (Message) objectInputStream.readObject();
//        socket.shutdownOutput();

        return message.getRes();
    }
}
发布了85 篇原创文章 · 获赞 21 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/weixin_37275456/article/details/104567119
今日推荐