GWT如何减少RPC调用的代码序列化程序的大小

Dan*_*son 8 gwt gwt-rpc

我发现在我的应用程序中由GWT生成的超过60%的javaScript代码用于RPC序列化程序.另外我发现服务接口之间没有共享序列化器,我的意思是如果我在2个rpc服务接口上引用了例如AccountDTO类型,我会得到2个序列化器类而不是相同类型的1.为了减少编译代码的大小,我想也许我可以使用Deferred Binding来替换我拥有的一个大接口的所有服务接口.如果可能,那么GWTCompiler可能只生成一个AccountDTO序列化器而不是2.

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

我试图实现的是这样的:

// 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>
    ...
    ...
Run Code Online (Sandbox Code Playgroud)

但此刻我收到了错误:

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

任何有关该问题的想法将不胜感激.问候

丹尼尔

Col*_*rth 4

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

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

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

AccountingServiceAsync service = (AccountingServiceAsync) GWT.create(GeneralService.class)
Run Code Online (Sandbox Code Playgroud)

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

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