GWT多模块间解耦合调用(一)

使用GWT已经半年了,查了很多资料,但发现国内关注它的人很少,而且骂声也不少(当然GWT也有让我恶心的地方),所以就把平时实验的结果和感想,在这里和大家分享一下。



GWT困扰我的一个最恶心的缺点,就是凡事要编译。系统一大,模块之间依赖很强,修改一个客户端(界面)的小功能,就要重编译整个项目,费时费劲,我们项目现在重编一次已经需要800多秒了——好在有Development mode(感叹这个东东的强大)。


之前看到过GWT提供JSNI的功能,能够使gwt 的java code与纯JavaScript互通信,因此打算尝试使用JSNI作为中介,看看能不能减轻模块间的依赖——或者实现多模块之间实现分模块编译。



想法是这样的,大部分模块基本是不变的,希望不要经常编译,假设其为Dll1;有些为客户开发的模块Dll2,它依赖于Dll1,而且经常发生变化(需求总是变化的)。希望修改了Dll2后,不重新编译Dll1。

Dll1和Dll2只是一个命名,并不是真正的dll啊!




如果按照GWT的依赖实现,Dll2中的gwt.xml中,声明inherit name="demo1.Dll1"后,重编Dll2其实就包含重编Dll1


使用JSNI,见http://code.google.com/webtoolkit/doc/latest/DevGuideCodingBasicsJSNI.html


将Dll1的接口,使用$entry方法,发布成为标准的javascript;Dll2不直接依赖Dll1,使用JSNI,调用Dll1发布成为javascript的接口。


Dll1中,用GWT的java实现了3个方法

ExpandedBlockStart.gif 代码
package  demo1.client;
import  java.util.Date;
import  com.extjs.gxt.ui.client.data.BaseModel;
import  com.extjs.gxt.ui.client.js.JsonConverter;
import  com.extjs.gxt.ui.client.widget.TabItem;
import  com.extjs.gxt.ui.client.widget.TabPanel;
import  com.extjs.gxt.ui.client.widget.layout.FitLayout;
import  com.google.gwt.dom.client.Element;
import  com.google.gwt.json.client.JSONObject;
import  com.google.gwt.user.client.Window;
import  com.google.gwt.user.client.ui.RootPanel;
public   class  DllImpl {
    
public   static   void  method1(String value) {
        Window.alert(value);
    }
    
public   static  String methodJson() {
        BaseModel result 
=   new  BaseModel();
        result.set(
" int " 1 );
        result.set(
" double " new  Double( 1.2 ));
        result.set(
" string " " str " );
        result.set(
" date " new  Date());
        result.set(
" boolean " true );
        JSONObject obj 
=  JsonConverter.encode(result.getProperties());
        String str 
=  obj.toString();
        
return  str;
    }
    
public   static  Element methodJS() {
        TabPanel p 
=   new  TabPanel();
        TabItem item 
=   new  TabItem();
        item.setClosable(
true );
        item.setText(
" dll 1 " );
        item.setLayout(
new  FitLayout());
        p.add(item);
        RootPanel.get(
" cross " ).add(p);
        
return  item.getElement();
    }
    
public   static   native   void  exportStaticMethod()  /* -{
        $wnd.method1 =
        $entry(@demo1.client.DllImpl::method1(Ljava/lang/String;));
        $wnd.methodJson =
        $entry(@demo1.client.DllImpl::methodJson());
        $wnd.methodJS =
        $entry(@demo1.client.DllImpl::methodJS());
    }-
*/ ;
}

 

 

exportStaticMothod是将类中的3个方法,发布为javascript,其路径就是$wnd.method1、$wnd.methodJson和$wnd.methodJS,参数列表参考google文档中的JSNI。

在Dll1的EntryPoint中,调用这个exportStaticMethod方法。

ExpandedBlockStart.gif Dll1的Entry代码
package  demo1.client;
import  com.google.gwt.core.client.EntryPoint;
/**
 * Entry point classes define <code>onModuleLoad()</code>.
 
*/
public   class  Dll1  implements  EntryPoint {
    
public   void  onModuleLoad() {
        DllImpl.exportStaticMethod();
    }
}

 

 在Dll2中,就使用JSNI调用javascript,路径就是之前的$wnd.method1、$wnd.methodJson和$wnd.methodJS

ExpandedBlockStart.gif 代码
package  demo2.client;
import  java.util.Date;
import  java.util.Map;
import  com.extjs.gxt.ui.client.data.BaseModel;
import  com.extjs.gxt.ui.client.js.JsonConverter;
import  com.extjs.gxt.ui.client.widget.form.FormPanel;
import  com.google.gwt.core.client.EntryPoint;
import  com.google.gwt.dom.client.Element;
import  com.google.gwt.user.client.Timer;
/**
 * Entry point classes define <code>onModuleLoad()</code>.
 
*/
public   class  Dll2  implements  EntryPoint {
    
public   void  onModuleLoad() {
        Timer t  =   new  Timer() {
            @Override
            
public   void  run() {
                
//  由于Dll1和Dll2没有声明依赖,所以使用Timer强制延时
                callMethod1( " Hello world form dll2. " );
                String json  =  callMethodJSON();
                Map < String, Object >  map  =  JsonConverter.decode(json);
                BaseModel m  =   new  BaseModel(map);
                System.out.println(m.get( " int " instanceof  Integer);
                System.out.println(m.get( " double " instanceof  Double);
                System.out.println(m.get( " string " instanceof  String);
                System.out.println(m.get( " date " instanceof  Date);
                System.out.println(m.get( " boolean " instanceof  Boolean);
                Element x  =  callMethodJS();
                FormPanel f2  =   new  FormPanel();
                f2.setHeading( " dll 2 " );
                f2.render((com.google.gwt.user.client.Element) x);
            }
        };
        t.schedule( 2000 );
    }
    
protected   native   void  callMethod1(String value) /* -{
        $wnd.method1(value);
    }- */ ;
    
protected   native  String callMethodJSON() /* -{
        return $wnd.methodJson();
    }- */ ;
    
protected   native  Element callMethodJS() /* -{
        var x = $wnd.methodJS();
        //alert(x);
        return x;
    }- */ ;
}

 

 之所以要用timer,是因为Dll2没有直接依赖Dll1,所以HTML声明加载Dll1和Dll2时,不能确定Dll2就是在Dll1加载后才被加载。如果Dll2在Dll1前加载,则调用的$wnd.method1()就还没被Dll1所“导出”,调用就会失败。

 

HTML是这样加载2个模块的——"mce:"是CSDN的blog自动添加上去的,主要参考那两个script标记,分别使html加载dll1模块和dll2模块。

ExpandedBlockStart.gif 代码
<! DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" >
< html >
< head >
< meta  http-equiv ="content-type"  content ="text/html; charset=UTF-8" >
< link  type ="text/css"  rel ="stylesheet"  href ="DoubleMain.css"  mce_href ="DoubleMain.css" >
< title > Web Application Starter Project </ title >
< mce:script  type ="text/javascript"  language ="javascript"
    src
="doublemain/doublemain.nocache.js" ></ mce:script >
< mce:script  type ="text/javascript"  language ="javascript"
    src
="doublemain2/doublemain2.nocache.js" ></ mce:script >
</ head >
< body >
<!--  OPTIONAL: include this if you want history support  -->
< iframe  src ="javascript:''"  mce_src ="javascript:''"  id ="__gwt_historyFrame"  tabIndex ='-1'
    
style ="position: absolute; width: 0; height: 0; border: 0" ></ iframe >
</ body >
</ html >

 

至此,实现了一个简单的多模块间解耦合的调用,但是这里面的问题很多,不是一劳永逸,留待下篇博文来分解。 


转载于:https://www.cnblogs.com/anic/archive/2010/02/02/1662184.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
项目:– JavaScript 中的患者数据管理系统 患者数据管理系统是为医院开发的 node JS 项目。通过使用此系统,您可以轻松访问患者数据,它具有成本效益,可改善患者护理和数据安全性。不仅如此,它还减少了错误范围。在运行项目之前,您需要下载 node.js。 这个患者数据管理项目包含 javascript、node.js 和 CSS。我们必须让服务器监听端口 3000,并使用 JSON 在客户端和服务器之交换数据。这个项目会不断询问您有关插件更新的信息,因此请保持互联网畅通。此系统允许您执行 crud 操作。在这里,您是系统的管理员。您还可以添加所需的员工人数。此外,您还可以更新患者记录。该系统功能齐全且功能齐全。 要运行此项目,您需要在计算机上安装NodeJS并使用现代浏览器,例如 Google Chrome、  Mozilla Firefox。ReactJS项目中的此项目可免费下载源代码。有关项目演示,请查看下面的图像滑块。 对于手动安装 1.将主项目文件夹解压到任意目录 2.从 cmd 设置项目目录的路径 3. 输入命令“npm install” 4.完成后输入命令“npm start” 5.现在,您将获得一个 localhost:portnumber,并转到该 URL 演示: 该项目为国外大神项目,可以作为毕业设计的项目,也可以作为大作业项目,不用担心代码重复,设计重复等,如果需要对项目进行修改,需要具备一定基础知识。 注意:如果装有360等杀毒软件,可能会出现误报的情况,源码本身并无病毒,使用源码时可以关闭360,或者添加信任。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值