Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

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

Open
yinhaomin opened this issue Mar 7, 2018 · 3 comments
Open

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

yinhaomin opened this issue Mar 7, 2018 · 3 comments

Comments

@yinhaomin
Copy link

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

@yinhaomin
Copy link
Author

@jhunters
Copy link
Collaborator

jhunters commented Mar 8, 2018

非常感谢反馈与整理,针对代理的对象的确是有这个问题,之所以没有那在一块API上进行, 是因为代理的方式有很多种, 除jdk的代理外,还有Spring的AOP, Cglib的,所以会加入很多行为判断逻辑。这一块后续怎么改进,会再单独考虑一下,后续发出同步

@yinhaomin
Copy link
Author

嗯嗯,赞,在其他公司用百度的开源推起来还是比较难的。讨论太少,社区资料有点少。可以考虑整个社区或者论坛啥的哈。

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants