GWT的反思

2009年9月2日由恩里克 留下一个回复»

简介

认为是错过了使用GWT的功能之一是Java的能力来执行豆类反省。 此限制的原因是,GWT没有反射API仿真(java.lang.reflect)。 在这篇文章中我们将看到我们如何才能实现在GWT样的反省。 我们还将探讨反省一些应用,因为在原则上是不平凡的事业。

为什么?

我们首先看到的就是我们想要的。

假设我们要开发一个具有数据绑定(能力“挂钩”的对象属性的可视组件)可视化组件的框架。 当然任何人谁摸她的“精彩”的实施CURD(ABM克里奥尔语)的工作是会见开始的,繁琐的设置的对象,反之亦然可视组件的读数。 如果你做到这一点,你做错了什么 :) 那么,这是一个以枯燥的容易出错的任务,特别是控制- C + CTRL - V。 如果我们可以这样说:“这在UI组件的属性看起来该对象”,那么我们可以缓解这一任务,以及为例子,我们保存所有的事件处理代码。

因此,如果我们做到这一点,我们可以建立一个组件,我们设置简单的bean和说,“看”,以及组件的值的变化会自动在bean,反之亦然反映属性集。

但如何做没有反省呢?

如何? 什么?

正如我们在GWT(至少到1.7)看到没有反映,所以我们没有选择,而是要找到另一种方式来实现的反省。 首先让我们看看在Java反省。 根据JavaDoc的Java.bean.Introspector类:

他说:“Introspector类提供了一种标准方法为工具,以了解有关的属性,事件,方法和目标Java Bean的支持。”

在西班牙:

他说:“Introspector类提供了一个标准的方法来发现的工具属性,事件和一个Java Bean支持的方法。”

我们感兴趣的部分是该财产的一部分。 换句话说,我们要实现一个机制,通过它可以是一个Java Bean来问他们有什么属性,什么是这些值。

其形式是要通过创建为每个类内省我们希望有洞察力类。

那么对于类:

 公共类Person {
    私人字符串名称;
    私人字符串的地址;
    私人出生日期;
    私人布尔性;

    公众人物(){
     }

    公共字符串的getName(){
        返回的名称;
     }
    公共无效的setName(String名称){
         this.name =名称;
     }

     / / getter和setter ...更多...
 } 

我们要贯彻“洞察”类型:

  {公共PersonaIntrospection
    私人身份的人;

    公共PersonaIntrospeccion(){
     }

     GetPerson公众人物(){
        返回的人;
     }

     setPersona公众人物(人P){
        人= P;
     }

    公开名单getProperties <String>的(){
        表L = <String>的<String>的新的ArrayList();
         l.add(“名称”);
         l.add(“地址”);
         l.add(“诞生”);
         l.add(“性”);
     }

    公共对象的getProperty(String属性){
        如果(“名”。等于(属性))
             persona.getNombre返回();
        否则,如果(“地址”。等于(属性))
             persona.getDireccion返回();
        否则,如果(“诞生”。等于(属性))
             persona.getNacimiento返回();
        否则,如果(“性”。等于(属性))
             persona.getSexo返回();
        其他
            抛出新IllegalArgumentException异常(财产);
     }

    公共无效的setProperty(String属性,对象的值){
        如果(“名”。等于(属性))
             persona.setNombre((字符串)值);
        否则,如果(“地址”。等于(属性))
             persona.setDireccion((字符串)值);
        否则,如果(“诞生”。等于(属性))
             persona.setNacimiento((日期)值);
        否则,如果(“性”。等于(属性))
             persona.setSexo((布尔)值);
        其他
            抛出新IllegalArgumentException异常(财产);
     }
 } 

除了优化,你可以对代码(列表缓存),这个想法是要了解为什么这个类为我们提供了洞察到一个人的对象。 至于应该想象,优雅是没有写的类PersonaIntrospection。 格雷斯正在无聊的东西少,更“好玩”的事情 :)

输入发电机!

我们要做的是GWT生成PersonaIntrospection类。 如何? 使用发电机。 这是一个非常有趣的GWT功能。 本文的重点是解释发电机,在互联网上有很多文献。 这里是一个 只是不必成为专家,了解我们做什么。

基本上,我们将编写一个类,生成类XXX XxxIntrospection代码我们在例子中看到的人。 Y(以避免作出任何朝着建立与一些外部实用工具类的编译步骤),我们将使用API​​,它允许你扩展GWT编译器(com.google.gwt.core.ext)。 注意:那些谁使用的Java APT会看到一个(几个相似之处http://java.sun.com/javase/6/docs/technotes/guides/apt/index.html )。

当GWT编译器遇到的声明GWT.create(类),它返回一个接口实现类发电机调用的类(该协会是在模块gwt.xml声明)关联的接口。 该发电机是“写”的代码,实现了接口类。 为了写这个代码已获得API,这是非常令人想起com.google.gwt.core.ext.typeinfo API Java反射镜的协助。

生成

现在让我们看看发生器。 但首先让我们看看如何使用它。 GWT.create()接受一个接口,并返回它的一个实现。 然后,我们定义一个接口的品牌,我们会打电话给内省。 任何一种你想要的将不得不实现这个接口将反省的支持:

 introspectible {} public接口 

然后,类人:

 公共类Person {实现introspectible
     / / ... 属性和方法... ...
 } 

我们还需要有内省界面语言:

 公共接口扩展<I Introspectable> {反思
    我getIntrospectable();
     setIntrospectable无效(I I);
     <T> T的getProperty(弦乐PROPNAME);
    无效的setProperty(弦乐PROPNAME,对象的值);
     GetPropertyName <String>的集合();
 } 

而对于反省和使用:

 人人=新的Person();
反思<person>的GWT.create instrospection =(Persona.class);
 instrospection.setIntrospectable(人);

为(弦乐道具:instrospection.getPropertyNames()){
     System.out.println(道具+“=”+ instrospection.getProperty(支柱));
 }

 Instrospection.getProperty字符串名称=(“名称”);
 Instrospection.getProperty字符串的地址=(“地址”);
出生日期= instrospection.getProperty(“诞生”);
 Instrospection.getProperty性=布尔(“性”); 

要关联的接口发生器内省,添加下面的代码片断:

 类=“com.aquait.utils.gwt.rebind.IntrospectionGenerator”> <产生,与
    类=“com.aquait.utils.gwt.introspection.Introspectable”/> <当型可分配
 </生成,与> 

因此,当GWT编译器GWT.create(Persona.class),称为发电机的类人实现内省。 然后我们有一个Person类的自省接口的实现。

对于在一个项目中使用,添加在<module>的这个Gwt.xml:

 名称=“com.aquait.utils.gwt.Introspection”/> <继承 

在GWT模块可以在这里下载: introspection4gwt

编辑:更新文件由于小错误。

编辑:再次更新由于一个错误,没有考虑到超类的属性。

Blogger帖子 DIGG 书签交易 谷歌阅读器 分享
广告

发表评论

垃圾邮件保护WP验证码-免费