GWT:如何在两个模块之间共享java对象(即EventBus)

GWT: How to share a java Object (ie: EventBus) between two modules

本文关键字:共享 之间 java 对象 EventBus 模块 两个 GWT      更新时间:2023-09-26

我正在构建一个大型应用程序,我想把它分成几个模块,如核心模块初始化,用户管理等,客户模块,生产模块等…

我想将其拆分为多个GWT模块(不使用GWT拆分技术),并共享一个EventBus来广播一些事件,如LoginEvent, LogoutEvent。我不想使用代码分割技术,因为我想减少编译时间,只重新编译我修改过的模块。这也允许通过注释HTML主机页中的脚本标签来启用或禁用模块。

我使用JSNI编写了以下代码:

CoreModule’s EntryPoint:
private static SimpleEventBus eventBus = null;
public void onModuleLoad() {
    export();
    getEventBus().addHandler(MyEvent.TYPE, new MyEventHandler() {
        @Override
        public void onEvent(MyEvent myEvent) {
            Window.alert(myEvent.getMessage());
        }
    });
}
public static SimpleEventBus getEventBus() {
    if (eventBus == null)
        eventBus = new SimpleEventBus();
    return eventBus;
}
public static native void export() /*-{
    $wnd.getEventBus = $entry(@testExporter.client.TestExporter::getEventBus());
}-*/;
CustomerModule’s EntryPoint:
public void onModuleLoad() {
    Button button = new Button("Click me");
    button.addClickHandler(new ClickHandler() {
        @Override
        public void onClick(ClickEvent event) {
            getEventBus().fireEvent(new MyEvent("Button clicked !"));
        }
    });
    RootPanel.get().add(button);
}
public static native SimpleEventBus getEventBus() /*-{
    // Create a useless eventBus because the GWT compiler make a call to a null instance
    var eventBus = @com.google.gwt.event.shared.SimpleEventBus::new()();
    eventBus = $wnd.getEventBus();
    return eventBus;
}-*/;

但是当在浏览器中执行时,我在Firebug中有以下例外:

uncaugth exception [object Object]

我还复制了实现/接口客户事件的MyEvent和MyEventHandler类。

注::我也知道的技术,包括注释其他模块引用,以避免编译它。

一个更简单的答案是不要使用多个入口点。

==========================================

如果你想把你的代码分解成可管理的单元,但又想在同一个页面中使用它们,你可以:

    创建一个带有入口点的"Application.gwt.xml"模块(如果我理解正确,相当于您的初始化模块)
  • 创建"UserManagement.gwt.xml"模块,没有入口点类
  • 创建不带入口点的其他XXX模块

要创建没有入口点的模块,只需删除

<entry-point class='xxx'/>

从你的gwt.xml文件,除了"Application"一个

然后需要使用

将这些模块包含到"Application"模块中
<inherits name="com.yourpackage.Module1Name" />
<inherits name="com.yourpackage.Module2Name" />

然后需要在一个GWT构建模块"com.yourpackage.Application"中编译所有这些。

当你这样做时,确保所有模块的编译*.class和源。java文件在类路径上都是可用的。

你的"Application"入口点只需要初始化并使用来自其他模块的对象

您不能在不同的GWT编译模块之间共享代码,除非您通过jsni提供代码的某些部分,并通过jsni调用这些导出的方法,就像您在查询中尝试的那样。

但是要注意:首先,共享类是不兼容的,因为每次编译都会以不同的方式重命名类/方法,其次,每次编译都会删除不同的死代码段。

所以在你的案例中,window.getEventBus导出方法中返回的SimpleEventBus在其他模块中是未知的,尽管其他模块也在使用SimpleEventBus

最简单的方法是使用gwt -export。首先,正确选择要在每个模块中导出的js-api,选择要如何命名它,然后方便地实现Exportable并注释方法。其次,考虑您将使用哪些对象进行通信,因为其中一些对象可能不兼容。我会使用gwt -export

中支持的基本类型、javascript对象和函数。

我认为与gwt -出口商,共享类,如果你在同一个命名空间中注释它们,你导出相同的方法,希望你可以在所有模块中使用它们,但我不确定。

因此通过jsni或gwt-export导出一个js API,并在它们之间传输纯原语或js对象。

您可以使用框架并通过WebMessage协议设置模块之间的通信。只有当模块在一个页面和模块在分开的战争。