【无标题】

在RPC中使用JDK动态代理

1.什么是动态代理

动态代理简单来说,就是在你需要用到某个类的时候,由Proxy给你动态构建这个类,同时你可以根据自己的需求定制具体方法的实现。

它可以在运行时动态实现接口,不仅可以有效解耦,还能实现很多操作,比如混淆编译,即编译的时候在代码中混淆一些东西,防止别人反编译,;另一个就是方法拦截器,这个可操作性也很大,比如AOP、日志记录等。

2.简单的JDK动态代理实现

由于本次主要记录一下在RPC中使用jdk动态代理,所以这里简单介绍一下。

2.1 创建代理接口ProxyService:

java 复制代码
public interface ProxyService {	
    void proxyMethod();	
}

2.2 创建接口实现类ProxyServiceImpl

java 复制代码
public class ProxyServiceImpl implements ProxyService {
    @Override
    public void proxyMethod() {
        System.out.println("ProxyService.proxyMethod() running");
    }

2.3 创建InvocationHandler接口的实现类

java 复制代码
public class MyInvocationHandler implements InvocationHandler {

    private Object target;

    public MyInvocationHandler(Object target){
        this.target = target;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args)
    throws Throwable {
        System.out.println("MyInvocationHandler.invoke 方法开始");
        method.invoke(target, args);
        System.out.println("MyInvocationHandler.invoke 方法结束");
        return null;
    }

}

2.4 测试动态代理

java 复制代码
public class JavaProxyTest {

    public static void main(String[] args) {
        MyInvocationHandler handler = new MyInvocationHandler(new ProxyServiceImpl()); //被代理的对象
        ProxyService proxyService = (ProxyService) Proxy.newProxyInstance(JavaProxyTest.class.getClassLoader(), new Class[] { ProxyService.class }, handler);//代理对象
        proxyService.proxyMethod();  
    }

}

2.5 结果

3. RPC中使用动态代理

在RPC中,由于消费者和服务者在不同的服务器中,所以方法的执行是中服务端中进行的,在发送端的代理方法中,我们发送方法名、接口名、参数类型、具体的参数,在服务端中收到这些参数再执行具体的方法。

3.1 发送端代码

  • 被代理的接口(实现中服务端)
java 复制代码
public interface HelloService {
    String hello(Hello hello);
}
  • 执行发送
java 复制代码
HelloService helloServiceProxy = rpcClientProxy.getProxy(HelloService.class);//代理对象
String sendData = helloServiceProxy.hello(new Hello("111", "send data"));
System.out.println(sendData);
  • 代理逻辑
java 复制代码
public Object invoke(Object o, Method method, Object[] args) throws Throwable {
        log.info("invoked method {}",method.getName());
        RpcRequest rpcRequest = RpcRequest.builder().methodName(method.getName())
                .parameters(args)
                .interfaceName(method.getDeclaringClass().getName())
                .paramTypes(method.getParameterTypes())
                .requestId(UUID.randomUUID().toString())
                .build();

        //send
		sendRpcRequest(rpcRequest);
        return "send successful";
    }

3.2 服务端代码

  • 提供服务
java 复制代码
@Slf4j
public class HelloServiceImpl2 implements HelloService {

    static {
        System.out.println("HelloServiceImpl2被创建");
    }

    @Override
    public String hello(Hello hello) {
        log.info("HelloServiceImpl2收到: {}.", hello.getMessage());
        String result = "Hello description is " + hello.getDescription();
        log.info("HelloServiceImpl2返回: {}.", result);
        return result;
    }
}
  • 发布服务
java 复制代码
HelloService helloServiceImpl2 = new HelloServiceImpl2();
RpcServiceConfig rpcServiceConfig = RpcServiceConfig.builder().group("test").version("version2").service(helloServiceImpl2).build();
nettyServer.registerService(rpcServiceConfig);
  • 服务端解析受到的参数,并通过反射执行具体的方法
java 复制代码
public Object invokeTargetMethod(RpcRequest rpcRequest) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
    String rpcServiceName = rpcRequest.getRpcServiceName();
    Object service = serviceProvider.getService(rpcServiceName);//获得实际对象
    Method method = service.getClass().getMethod(rpcRequest.getMethodName(), rpcRequest.getParamTypes());
    Object invoke = method.invoke(service, rpcRequest.getParameters());
    return invoke;
}
相关推荐
梅羽落4 天前
ideal jdk报错如何解决
java·经验分享·jdk·intellij-idea
G_whang4 天前
macOS 安装JDK17
macos·jdk
十二测试录8 天前
【自动化测试】—— Appium安装配置保姆教程(图文详解)
经验分享·python·pycharm·jdk·node.js·appium·自动化
八月五9 天前
JDK8新特性详解
jdk
THE WHY12 天前
IDEA Maven构建时报错:无效的目标发行版17
java·后端·jdk·maven·intellij-idea
_Shirley12 天前
Unknown Kotlin JVM target: 21
android·java·jvm·jdk·kotlin·android studio
程序员大阳1 个月前
闲谭Scala(2)--安装与环境配置
jdk·scala·安装·配置·环境变量
新手小袁_J1 个月前
JDK11下载安装和配置超详细过程
java·spring cloud·jdk·maven·mybatis·jdk11
waicsdn_haha1 个月前
Java/JDK下载、安装及环境配置超详细教程【Windows10、macOS和Linux图文详解】
java·运维·服务器·开发语言·windows·后端·jdk
ZHOUPUYU1 个月前
最新 neo4j 5.26版本下载安装配置步骤【附安装包】
java·后端·jdk·nosql·数据库开发·neo4j·图形数据库