`
stone
  • 浏览: 36675 次
  • 性别: Icon_minigender_1
  • 来自: 天津
社区版块
存档分类
最新评论

Gwt延迟绑定介绍

阅读更多
Gwt延迟绑定介绍

Gwt的延迟绑定是一种gwt对反射机制的一种支持方案。简单的说就是在使用gwt进行代码开发的时候,可以使用接口和抽象类,而不用管它的实现,在编译后或者host模式的情况下,gwt会自己跟模块配置的信息来使用具体哪一个实现类替代代码中的接口和抽象类。

使用说明:

1. 定义接口或者抽象类,然后再定义一个实现类。

2. 在xxx.gwt.xml(模块文件中定义)替换的参数信息和具体替换的类
<replace-with class="com.google.gwt.user.client.impl.DOMImplMozilla">
		<when-type-is class="com.google.gwt.user.client.impl.DOMImpl"/>
		<when-property-is name="user.agent" value="gecko1_8"/>
	</replace-with>

上面的配置是将在firefox浏览器里面使用DOMImpl该类的地方使用DOMImplMozilla这个类进行替换。其中的replace-with是指实际用到的类,when-type-is则是要替换的类,when-property-is则是一些参数信息,可以添加0到多个。另外,关于参数的配置还可以加一些逻辑的限制,如Any,
<any>
      <when-property-is name="user.agent" value="gecko"/>
      <when-property-is name="user.agent" value="gecko1_8" />
    </any>


3. 在代码中使用
通过GWT.create方法可以动态的获取不同的实现类,如下:
DOMImpl impl = (DOMImpl) GWT.create(DOMImpl.class);
再结合gwt的dom模块的配置信息(如下),impl对象将会根据不同的浏览器而动态采用不同的domimpl类的实现。

<module>
	<inherits name="com.google.gwt.core.Core"/>
	<inherits name="com.google.gwt.user.UserAgent"/>

	<replace-with class="com.google.gwt.user.client.impl.DOMImplOpera">
		<when-type-is class="com.google.gwt.user.client.impl.DOMImpl"/>
		<when-property-is name="user.agent" value="opera"/>
	</replace-with>

	<replace-with class="com.google.gwt.user.client.impl.DOMImplSafari">
		<when-type-is class="com.google.gwt.user.client.impl.DOMImpl"/>
		<when-property-is name="user.agent" value="safari"/>
	</replace-with>

	<replace-with class="com.google.gwt.user.client.impl.DOMImplIE6">
		<when-type-is class="com.google.gwt.user.client.impl.DOMImpl"/>
		<when-property-is name="user.agent" value="ie6"/>
	</replace-with>

	<replace-with class="com.google.gwt.user.client.impl.DOMImplMozilla">
		<when-type-is class="com.google.gwt.user.client.impl.DOMImpl"/>
		<when-property-is name="user.agent" value="gecko1_8"/>
	</replace-with>

	<replace-with class="com.google.gwt.user.client.impl.DOMImplMozillaOld">
		<when-type-is class="com.google.gwt.user.client.impl.DOMImpl"/>
		<when-property-is name="user.agent" value="gecko"/>
	</replace-with>
</module>





参考:
http://code.google.com/docreader/#p=google-web-toolkit-doc-1-5&s=google-web-toolkit-doc-1-5&t=DevGuideDeferredBinding
分享到:
评论
17 楼 crazywan 2008-11-28  
这个功能很好用,可以自动生成代码,让RPC变得简单而且统一了!在和spring配合,绝了!
16 楼 stone 2008-11-27  
weirihai 写道
我不会这个啊你能说具体点啊!!!

那个地方不明白?我已经在帖子里面引用了gwt官方介绍的文档,那个应该更详细一些。
15 楼 weirihai 2008-11-27  
我不会这个啊你能说具体点啊!!!
14 楼 jvincent 2008-11-18  
你的意思是把类名放到xml文件里?那如果新增一个菜单怎么办?写文件?

我给你发了消息..
13 楼 edokeh 2008-11-18  
再次确认下需求,呵呵
1.已经实现了一个业务系统
2.根据需求,需要增加一个模块
3.为这个模块写好对应的UI类,其余代码不做改动
4.系统中的菜单会自动地多出与这个模块对应的项,点击即可显示这个模块


如果是这样的话,用我帖子里面的代码是可以实现的,不需要把类名放数据库
12 楼 jvincent 2008-11-18  
不是,就是个业务系统,实现增加功能不修改代码...
11 楼 edokeh 2008-11-18  
是不是为了实现权限系统?
10 楼 jvincent 2008-11-18  
是的,只不过是在初始化的时候把当前登陆的用户的所有菜单都取出来,然后放到一个对象里,在点击菜单的时候就实例化对应的类...

要是支持反射就好了....
9 楼 edokeh 2008-11-18  
你是不是希望实现这样的需求:
1.点击菜单某项
2.发AJAX请求从服务器取得这个菜单项对应的UI类名
3.实例化UI类并显示

要是这样的话不如用iframe来显示对应的UI,菜单项控制iframe的src
要不这么做的话。。。我一时也没想到什么好办法。。。
8 楼 jvincent 2008-11-18  
是啊...菜单可以手工增加,这样就必须在增加菜单的时候指定执行类,然后在加载的时候实例化...
7 楼 edokeh 2008-11-18  
类名写在数据库里面?
6 楼 jvincent 2008-11-18  
执行类是保存在数据库中,在加载菜单的时候才取出...
这时怎么写xml文件?
5 楼 edokeh 2008-11-18  
jvincent 写道
如果有个功能菜单,当点击后实例化该菜单对应的执行类,从而显示该菜单对应的界面...没有反射,这种功能如何实现?

实例化执行类这个步骤应当在点击之前就完成,然后将相应的对象与菜单项绑定,例如对于TreeItem类有个setUserObject的方法,可以用来进行绑定用户自定义对象
4 楼 jvincent 2008-11-18  
如果有个功能菜单,当点击后实例化该菜单对应的执行类,从而显示该菜单对应的界面...没有反射,这种功能如何实现?
3 楼 stone 2008-10-28  
edokeh 写道
最近正好项目用到延迟绑定,顺便帮楼主完善一下这篇文章“在代码中使用”的部分
延迟绑定很强大,反射,注解都可以支持
我用个实际例子来介绍:例如现在GWT中有很多Animal接口的实现类,比如Cat,Dog等等,现在需要在onModuleLoad的时候能够将Animal的所有实现类实例化,简单的写法就是一个一个地new,当实现类很多时候不仅累而且容易出错,这时候可以用延迟绑定来实现


非常感谢edokeh的完善。
2 楼 edokeh 2008-10-28  
最近正好项目用到延迟绑定,顺便帮楼主完善一下这篇文章“在代码中使用”的部分
延迟绑定很强大,反射,注解都可以支持
我用个实际例子来介绍:例如现在GWT中有很多Animal接口的实现类,比如Cat,Dog等等,现在需要在onModuleLoad的时候能够将Animal的所有实现类实例化,简单的写法就是一个一个地new,当实现类很多时候不仅累而且容易出错,这时候可以用延迟绑定来实现

首先在入口类里面写个空的类,然后用GWT.create方法来实例化它

private static class AnimalCreator{}

public void onModuleLoad(){
  GWT.create(AnimalCreator.class);
}


在配置XML文件里面做如下配置
<generate-with class="com.google.generator.AnimalGenerator">
  <when-type-assignable class="com.google.client.AnimalCreator"/>  
</generate-with>


解释一下这个配置:
当代码执行到GWT.create(AnimalCreator.class)时,GWT会调用AnimalGenerator这个类的generate方法(AnimalGenerator必须实现com.google.gwt.core.ext.Generator接口),generate方法返回一个类名的字符串(含package name),GWT.create方法将会根据这个字符串找到实际的类,然后将它实例化。
需要指出的是,上述过程都是在compile期间发生。也就是说这个Generator的实现类并不会被编译成js,所以不要把这个类放到client包下面;同时,这也意味着在这个Generator类里面,我们可以使用jdk提供的类,而不是局限于GWT JRE Emulation

下面直接给出AnimalGenerator的代码

public class ShowcaseGenerator extends Generator {
	private String className=null;
	private String packageName=null;
	
  public String generate(TreeLogger logger, GeneratorContext context,String typeName) throws UnableToCompleteException {
    try{
    	JClassType classType=context.getTypeOracle().getType(typeName);
    	//取包名
    	packageName=classType.getPackage().getName();
    	//取类名,然后加上Impl,也就是AnimalCreatorImpl
    	className=classType.getClass().getSimpleSourceName()+"Impl";
    	generateClass(logger,context);
  	}catch(Exception e){
  		logger.log(TreeLogger.ERROR, "ERROR!!!", e); 
  	}
  	return packageName+"."+className;
  }
  
  //尝试创建AnimalCreatorImpl这个类
  private void generateClass(TreeLogger logger, GeneratorContext context){
		PrintWriter printWriter = null;
		
		printWriter = context.tryCreate(logger, packageName, className);
		if (printWriter == null) return; 

		ClassSourceFileComposerFactory composer = null; 
		composer = new ClassSourceFileComposerFactory(packageName, className); 
		SourceWriter sourceWriter = null; 
		sourceWriter = composer.createSourceWriter(context, printWriter); 
		//手工写入代码 
		sourceWriter.println("public "+className+" {");
		sourceWriter.indent(); 
		try{
			JClassType superType=context.getTypeOracle().getType("com.google.client.Animal");
			JClassType[] Types=superType.getSubtypes();
			for(JClassType type:types){
				sourceWriter.println("new "+type.getPackage().getName()+"."+type.getName()+"();");
			}
		}catch(NotFoundException e){
			e.printStackTrace();	
		}
		sourceWriter.outdent(); 
		sourceWriter.println("}"); 		
		
		sourceWriter.outdent(); 
		sourceWriter.println("}"); 		
		//提交写入的新类
		context.commit(logger, printWriter); 
	}
}

generate方法返回的是com.google.client.AnimalCreatorImpl,但是我们目前并没有这个类,所以执行generateClass方法来动态生成这个类,在方法里面看到,我们首先找到com.google.client.Animal的所有实现类,然后将这些类名都以new Cat();这样的形式写入类的构造函数
那么当我们执行GWT.create(AnimalCreator.class)时,GWT会实例化我们用代码生成的AnimalCreatorImpl类,这个类的构造函数里面写着new Cat();new Dog();等等的代码,如果我们新建一个Animal接口的实现类,不用改动任何代码,这个类就会在onModuleLoad时被实例化
仔细查看GWT的com.google.gwt.core.ext包下面的API,我们可以发现更多对反射,注解等高级特性支持的方法
1 楼 crazywan 2008-10-24  
呵呵,牛人必做牛事!我支持!谢谢

相关推荐

    Grails 中文参考手册

    6.7.3 用GWT实现Ajax 6.7.4 服务端的Ajax 6.8 内容协商 7. 验证 7.1 声明约束 7.2 验证约束 7.3 客户端验证 7.4 验证和国际化 8. 服务层 8.1 声明式事务 8.2 服务的作用域 8.3 依赖注入和服务 8.4 使用Java的服务 9....

    java开源包1

    Chronicle 是一个超低延迟、高吞吐、持久化的消息和事件驱动的内存数据库,延迟只有16纳秒以及支持每秒钟 500-2000 万消息/记录。 google-api-translate-java(Java 语言对Google翻译引擎的封装类库) 语音识别程序 ...

    java开源包11

    Chronicle 是一个超低延迟、高吞吐、持久化的消息和事件驱动的内存数据库,延迟只有16纳秒以及支持每秒钟 500-2000 万消息/记录。 google-api-translate-java(Java 语言对Google翻译引擎的封装类库) 语音识别程序 ...

    java开源包2

    Chronicle 是一个超低延迟、高吞吐、持久化的消息和事件驱动的内存数据库,延迟只有16纳秒以及支持每秒钟 500-2000 万消息/记录。 google-api-translate-java(Java 语言对Google翻译引擎的封装类库) 语音识别程序 ...

    java开源包3

    Chronicle 是一个超低延迟、高吞吐、持久化的消息和事件驱动的内存数据库,延迟只有16纳秒以及支持每秒钟 500-2000 万消息/记录。 google-api-translate-java(Java 语言对Google翻译引擎的封装类库) 语音识别程序 ...

    java开源包6

    Chronicle 是一个超低延迟、高吞吐、持久化的消息和事件驱动的内存数据库,延迟只有16纳秒以及支持每秒钟 500-2000 万消息/记录。 google-api-translate-java(Java 语言对Google翻译引擎的封装类库) 语音识别程序 ...

    java开源包5

    Chronicle 是一个超低延迟、高吞吐、持久化的消息和事件驱动的内存数据库,延迟只有16纳秒以及支持每秒钟 500-2000 万消息/记录。 google-api-translate-java(Java 语言对Google翻译引擎的封装类库) 语音识别程序 ...

    java开源包10

    Chronicle 是一个超低延迟、高吞吐、持久化的消息和事件驱动的内存数据库,延迟只有16纳秒以及支持每秒钟 500-2000 万消息/记录。 google-api-translate-java(Java 语言对Google翻译引擎的封装类库) 语音识别程序 ...

    java开源包4

    Chronicle 是一个超低延迟、高吞吐、持久化的消息和事件驱动的内存数据库,延迟只有16纳秒以及支持每秒钟 500-2000 万消息/记录。 google-api-translate-java(Java 语言对Google翻译引擎的封装类库) 语音识别程序 ...

    java开源包8

    Chronicle 是一个超低延迟、高吞吐、持久化的消息和事件驱动的内存数据库,延迟只有16纳秒以及支持每秒钟 500-2000 万消息/记录。 google-api-translate-java(Java 语言对Google翻译引擎的封装类库) 语音识别程序 ...

    java开源包7

    Chronicle 是一个超低延迟、高吞吐、持久化的消息和事件驱动的内存数据库,延迟只有16纳秒以及支持每秒钟 500-2000 万消息/记录。 google-api-translate-java(Java 语言对Google翻译引擎的封装类库) 语音识别程序 ...

    java开源包9

    Chronicle 是一个超低延迟、高吞吐、持久化的消息和事件驱动的内存数据库,延迟只有16纳秒以及支持每秒钟 500-2000 万消息/记录。 google-api-translate-java(Java 语言对Google翻译引擎的封装类库) 语音识别程序 ...

    java开源包101

    Chronicle 是一个超低延迟、高吞吐、持久化的消息和事件驱动的内存数据库,延迟只有16纳秒以及支持每秒钟 500-2000 万消息/记录。 google-api-translate-java(Java 语言对Google翻译引擎的封装类库) 语音识别程序 ...

    Java资源包01

    Chronicle 是一个超低延迟、高吞吐、持久化的消息和事件驱动的内存数据库,延迟只有16纳秒以及支持每秒钟 500-2000 万消息/记录。 google-api-translate-java(Java 语言对Google翻译引擎的封装类库) 语音识别程序 ...

    JAVA上百实例源码以及开源项目源代码

    Java 源码包 Applet钢琴模拟程序java源码 2个目标文件,提供基本的音乐编辑功能。编辑音乐软件的朋友,这款实例会对你有所帮助。 Calendar万年历 1个目标文件 EJB 模拟银行ATM流程及操作源代码 ...

    JAVA上百实例源码以及开源项目

    百度云盘分享 简介 笔者当初为了学习JAVA,收集了很多经典源码,源码难易程度分为初级、中级、高级等,详情看源码列表,需要的可以直接下载! 这些源码反映了那时那景笔者对未来的盲目,对代码的热情、执着,对...

Global site tag (gtag.js) - Google Analytics