关于Jprotobuf-rpc-socket的讨论

Posted by Yin Haomin on March 7, 2018

开个Post一起讨论百度的Jprotobuf-rpc-socket

背景说明

考虑多内部系统交互的稳定性,我们一般使用RPC框架进行交互,我在百度开发使用过Baidu Jprotobuf-rpc-socket,这里是User guide
百度的框架虽然开源了,但是市面上用的太少了,导致资料经验贴和教程等等都太少了,期望自此开始积累Jprotobuf-rpc-socket的使用经验和教程资料。这是我整理的Jprotobuf-rpc-demo,里面有使用的详细的说明。

问题1:不能支持Proxy对象的服务发布

当我们发布一个代理类的时候,在下面代码中会出现问题。

com.baidu.jprotobuf.pbrpc.server.RpcServiceRegistry

    /**
     * Register service.
     *
     * @param target the target
     */
    public void registerService(final Object target) {
        if (target == null) {
            throw new IllegalArgumentException("Param 'target' is null.");
        }
        Class<? extends Object> cls = target.getClass();
        ReflectionUtils.doWithMethods(cls, new ReflectionUtils.MethodCallback() {
            public void doWith(Method method) throws IllegalArgumentException, IllegalAccessException {
                ProtobufRPCService protobufPRCService = method.getAnnotation(ProtobufRPCService.class);
                if (protobufPRCService != null) {
                    doRegiterService(method, target, protobufPRCService);
                }
            }
        });
    }

在运行的时候,下面的代码,拿到的类为”class com.sun.proxy.$Proxy81”。

Class<? extends Object> cls = target.getClass();

这就导致在下面的语句中,我们拿不到需要注册的方法.

ProtobufRPCService protobufPRCService = method.getAnnotation(ProtobufRPCService.class);

我们的实现代码是这样的。

@Slf4j
@RpcExporter(port = "1033", rpcServerOptionsBeanName = "rpcServerOptions")
@Service(DemoConstants.PMP_SERVICE)
public class PmpServiceImpl implements PmpService {

    @Autowired
    private HelloWorldRunService helloWorldRunService;

    @ProtobufRPCService(serviceName = DemoConstants.PMP_SERVICE, methodName = "helloWorld")
    @Override
    public HelloWorldResponse helloWorld(HelloWorldRequest request) {
        log.info("Called by request:" + request);
        HelloWorldResponse response = helloWorldRunService.helloWorld(request);
        return response;
    }

}

实际上我们可以通过下面的代码,拿到被代理类,不知道开发者不做这件事情是否有其他考虑?

public static Object getJdkDynamicProxyTargetObject(Object proxy) throws Exception {  
    InvocationHandler invocationHandler = Proxy.getInvocationHandler(proxy);  
    Object target = ((AdvisedSupport) ReflectionUtils.getFieldValue(invocationHandler,"advised")).getTargetSource().getTarget();  
    return target;  
}