baidu / baidu/Jprotobuf-rpc-socket

不能支持Proxy对象的服务发布

Open
#52 3 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Java
Stars
535
Forks
216
PR merge metrics
No merged PRs in 30d

Description

不能支持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;  
}  

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start at com.baidu.jprotobuf.pbrpc.server.RpcServiceRegistry.registerService and trace how ReflectionUtils.doWithMethods inspects the target class and ProtobufRPCService annotations. Compare the proxy class shown in the report with the underlying PmpServiceImpl example, then verify that publishing a proxied service discovers the annotated helloWorld method without breaking direct service registration.

Written by the indexing model from the issue text.

Assessment

Tech stack
java, spring
Domain
backend-api-design
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.