两种:
提供者想省事或者消费者想省事
比如提供者想省事,虽然提供了10个方法,但是不想在接口里面写十个方法,也就不用给这十个方法做函数声明、参数声明了。直接通过:
ServiceConfig<GenericService> service = new ServiceConfig<GenericService>();
service.setApplication(new ApplicationConfig("generic-provider"));
service.setRegistry(new RegistryConfig("N/A"));
service.setProtocol(new ProtocolConfig("dubbo", 29581));
service.setInterface(DemoService.class.getName());
service.setRef(new GenericService() {
public Object $invoke(String method, String[] parameterTypes, Object[] args)
throws GenericException {
if ("sayName".equals(method)) {
return "Generic " + args[0];
}
if ("throwDemoException".equals(method)) {
throw new GenericException(DemoException.class.getName(), "Generic");
}
if ("getUsers".equals(method)) {
return args[0];
}
return null;
}
});
service.export();
也就是通过method不同,直接返回不同处理结果,隐藏了方法和参数声明。上面虽然 service.setInterface(DemoService.class.getName()),这里传入的是接口的str名称。也就是说通过generic,provider已经完全不依赖interface了,只是用到这个接口的名称字符串用做servericekey用的。
从provider的ref来看,如果消费者要消费generic的话,其实method-name肯定全部都是$invoke了。
之所以能这样操作,其实还是由于Hessian在做序列化的时候,不仅仅把这个对象的object内容塞入进去了,还要这个对象的class-name(字符串)也放入进去,这样对方在接受的时候,就知道按照什么class进行反序列化。
原文:https://www.cnblogs.com/notlate/p/10127942.html