赞
踩
分布式系统架构时代,RPC框架你一定不会陌生。目前主流的RPC框架有 dubbo、thrift、motan、grpc等。
消费端(RPC Consumer)通常只有服务接口定义,接口的业务逻辑实现部署在生产端(RPC Provider),服务调用一般是采用动态代理方式,通过Proxy创建一个代理类,借助增强方式完成网络的远程调用,获取执行结果。
这里有两个关键点:
1、如何实现一个通用的代理类?
2、如何在消费端动态注入接口的代理对象?
如何实现一个通用的代理类?
目前动态代理的实现方案有很多种,如JDK 动态代理、Cglib、Javassist、ASM、Byte Buddy等
JDK 动态代理的代理类是运行时通过字节码生成的,我们通过Proxy.newProxyInstance方法获取的接口实现类就是这个字节码生成的代理类
定义代理类RpcInvocationHandler
,继承InvocationHandler
接口,并重写invoke()方法。
- public class RpcInvocationHandler implements InvocationHandler {
-
- private final String serviceVersion;
- private final long timeout;
-
- public RpcInvocationHandler(String serviceVersion, long timeout) {
- this.serviceVersion = serviceVersion;
- this.timeout = timeout;
- }
-
- @Override
- public Object invoke(Object proxy, Method method, Object[] args) {
- // todo
- // 1、封装RpcProtocol对象
- // 2、对象编码
- // 3、发送请求到服务端
- // 4、获取返回结果
-
- // 模拟生成一个订单号
- Long orderId = Long.valueOf(new Random().nextInt(100));
-
- String s = String.format("【RpcInvocationHandler】 调用方法:%s , 参数:%s ,订单id:%d", method.getName(), JSON.toJSONString(args), orderId);
- System.out.println(s);
- return orderId;
- }
如何在消费端动态注入接口的代理对象?
构造一个自定义Bean,并对该Bean下执行的所有方法拦截,增加额外处理逻辑。
OrderService
是一个订单接口类,client端没有该接口的实现类。
定义注解@RpcReference
,用于描述代理类的参数信息。
- @Retention(RetentionPolicy.RUNTIME)
- @Target(ElementType.FIELD)
- @Autowired
- public @interface RpcReference {
- String serviceVersion() default "1.0";
- long timeout() default 5000;
- }
Spring 的 FactoryBean 接口可以帮助我们实现自定义的 Bean,FactoryBean 是一种特殊的工厂 Bean,通过 getObject() 方法返回对象,而并不是 FactoryBean 本身。
- public class RpcReferenceBean implements FactoryBean<Object> {
-
- private Class<?> interfaceClass;
-
- private String serviceVersion;
-
- private long timeout;
-
- private Object object;
-
- @Override
- public Object getObject() throws Exception {
- return object;
- }
-
-
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。