GWT 如何减少用于 RPC 调用的代码序列化程序的大小 [英] GWT how can I reduce the size of code serializers for RPC calls

查看:17
本文介绍了GWT 如何减少用于 RPC 调用的代码序列化程序的大小的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我发现 GWT 在我的应用程序上生成的 60% 以上的 javaScript 代码是用于 RPC 序列化程序的.此外,我发现序列化程序不在服务接口之间共享,我的意思是,如果我在 2 个 rpc 服务接口上引用了例如 AccountDTO 类型,我将获得 2 个序列化程序类,而不是同一类型的 1 个.为了减少编译代码的大小,我想也许我可以使用延迟绑定来替换一个大接口的所有服务接口.如果可能的话,那么 GWTCompiler 可能只生成一个 AccountDTO 序列化程序,而不是 2 个.

I found that the more than 60% of the javaScript code generated by GWT on my application is for RPC serializers. Also I found that serializers are not shared between service interfaces, I mean if I have for example AccountDTO type referenced on 2 rpc service interfaces, I will get 2 serializer classes instead of 1 for the same type. In Order to reduce the size of the compiled code I was thinking that maybe I could use Deferred Binding in order to do a replacement of all the services interfaces I have for one big interface. If that could be possible, maybe then GWTCompiler will produce only one AccountDTO serializer instead of 2.

我不确定这是个好主意,或者我的问题是否有更好的解决方案.

I'm not sure this is a good idea or if there is a better solution for my problem.

我试图实现的是这样的:

What I was trying to implement was something like this:

// Define new interface that extends all service interfaces
public interface GenericService extends RemoteService,
                    AccountingService,
                    FinancialService,..., { }

public interface GenericServiceAsync extends AccountingServiceAsync,
                         FinancialServiceAsync, ..., { }

// At Application.gwt.xml do:

<module>
...
...
    <replace-with class="com.arballon.gwt.core.client.GenericService">
        <when-this-is class="com.arballon.gwt.core.client.AccountingService>
    </replace-with>
    <replace-with class="com.arballon.gwt.core.client.GenericService">
        <when-this-is class="com.arballon.gwt.core.client.FinancialService>
    </replace-with>
    ...
    ...

但此刻我收到了错误:

[错误] 'file:/C:/Users/Daniel/EclipseWorkspace/ADK/src/com/arballon/gwt/core/client/FinancialService.java' 中的错误[错误] 第 31 行:找不到重新绑定结果com.arballon.gwt.core.client.GenericService"

[ERROR] Errors in 'file:/C:/Users/Daniel/EclipseWorkspace/ADK/src/com/arballon/gwt/core/client/FinancialService.java' [ERROR] Line 31: Rebind result 'com.arballon.gwt.core.client.GenericService' could not be found

对此问题的任何想法将不胜感激.问候

Any thoughts about the issue will be appreciated. Regards

丹尼尔

推荐答案

GWT 的 RPC 生成代码构建了几个类来完成它的工作,正如您所注意到的:每个类型都有一个 *_FieldSerializer线路,以及 RemoteService 异步类型的 *_Proxy 类.该代理类型需要一个 *_TypeSerializer,这是您问题的根源-出于某种原因,GWT 将所有序列化/反序列化方法连接到 string->js 函数映射中,可能是为了方便快速查找 - 但是这个设置代码是以需要在最终构建中的代码行为代价的.一种更优化的方法可以让每个 FieldSerializer 都有一个注册方法,它将其方法添加到代理拥有的静态映射中 - 然而,这是一个困扰,但 GWT 尝试不引用 的优化instantiate(), deserialize()serialize() 方法如果没有出现它们将被调用.

GWT's RPC generation code builds several classes to do its work as you've noted: a *_FieldSerializer for each type that goes over the wire, and a *_Proxy class for the RemoteService async type. That proxy type requires a *_TypeSerializer, which is the root of your problem - for some reason, GWT wires up all of the serialization/deserialization methods in a string->js function map, probably to facilitate fast lookups - but this setup code comes at the cost of lines of code that need to be in the final build. A more optimized approach could have each FieldSerializer have a registration method where it adds its methods to the static map owned by the Proxy - this is plagued, however, but GWT's optimization of attempting to not reference instantiate(), deserialize() and serialize() methods if it doesnt appear they will be called.

您的问题源于有许多可以序列化的类型,以及您试图构建 RemoteService 类型,每个类型描述特定的功能单元,但重用许多模型类型.令人钦佩的目标,尤其是因为它可能会使您的服务器端代码看起来更好,但显然 GWT 会因此而咬您.

Your issue stems from having many types that can be serialized, and from your having attempted to build out RemoteService types that each describe specific units of functionality, but re-use many model types. Admirable goal, especially as it will probably make your server-side code look nicer, but apparently GWT bites you for it.

我试图在 freenode(如 niloc132)上为您提供的解决方案是构建一个大型 RemoteService 类型,您将其命名为 GeneralService,以及一个匹配的 GeneralServiceAsync,每个都扩展了所有现有的 rpc 服务类型.我的第一个想法是使用 告诉生成器系统,当您希望每个 RemoteService 类型将其替换为 GeneralService 时,但正如 Tahir 指出的那样,这没有意义 - GWT 不会将重新绑定结果传递回自身以继续进行查找.相反,我建议当您需要服务异步类型时,请执行以下操作:

The solution I attempted to offer you on freenode (as niloc132) was to build a single large RemoteService type, which you named GeneralService, and a matching GeneralServiceAsync, each extending all of the existing rpc service types. My first thought was to use a <replace-with> to tell the generator system that when you want each RemoteService type to replace it with GeneralService, but as Tahir points out, this doesn't make sense - GWT doesn't pass rebind results back into itself to keep doing lookups. Instead, I would suggest that when you want a service async type, do the following:

AccountingServiceAsync service = (AccountingServiceAsync) GWT.create(GeneralService.class)

GeneralService 的重新绑定结果将实现 GeneralServiceAsync,它本身可分配给 AccountingServiceAsync.如果没记错的话,您说您有提供这些服务的静态方法/字段 - 更改这些站点以始终创建 GeneralServiceAsync 实例.只要您不在任何 RemoteService 子类型上调用 GWT.create,而是在 GeneralService 上调用,您就会限制 TypeSerializers到一.

The rebind result from GeneralService will implement GeneralServiceAsync, which is itself assignable to AccountingServiceAsync. If memory serves, you said that you have static methods/fields that provide these services - change those sites to always create a GeneralServiceAsync instance. As long as you do not invoke GWT.create on any RemoteService subtype but GeneralService, you will limit the number of TypeSerializers to one.

作为旁注,RemoteServiceProxy 子类型是无状态的,因此确保您只创建一个实例可能会使构建更容易一致,但不会节省运行时内存或时间,因为它们几乎可以肯定编译为静态方法.*_TypeSerializer 类确实有状态,但每个类只有一个实例,因此组合所有 RemoteService 可能会节省很少量的工作内存.

As a side note, the RemoteServiceProxy subtypes are stateless, so ensuring that you create only one instance might make it easier to build consistently, but saves no runtime memory or time, as they are almost certainly compiled out to static methods. The *_TypeSerializer classes do have state however, but there is only one instance of each, so combining all of your RemoteServices might save a very small amount of working memory.

这篇关于GWT 如何减少用于 RPC 调用的代码序列化程序的大小的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆