Intro
Una delle caratteristiche che vengono perse quando si usa GWT è la capacità di Java per eseguire l'introspezione sui fagioli. La ragione di questa limitazione è che GWT non ha emulazione API di riflessione (java.lang.reflect). In questo articolo vedremo come sia possibile realizzare una sorta di introspezione in GWT. Esploreremo anche alcune applicazioni di introspezione, poiché in linea di principio non è di utilità banale.
Per che cosa?
La prima cosa che vediamo è ciò che vogliamo.
Supponiamo di voler sviluppare un quadro di componenti visuali che hanno l'associazione dei dati (capacità di "agganciare" la proprietà di un oggetto a un componente visiva). Sicuramente chi ha toccato il suo lavoro "meraviglioso" di attuare una cagliata (ABM creolo) è stata accolta con la lettura di partenza e noioso dei componenti visiva dell'oggetto e viceversa. Se dovessi farlo, hai fatto qualcosa di sbagliato
. Bene, questo è un compito noioso come soggetti a errori, soprattutto Control-C + Ctrl-V. Se si potesse dire qualcosa del tipo: "Questo componente UI guarda alla proprietà come di quell'oggetto," allora possiamo alleviare questo compito così per esempio salviamo tutto il codice per la gestione degli eventi.
Quindi, se facciamo questo, possiamo costruire un insieme di componenti a cui abbiamo impostato semplicemente il fagiolo e la proprietà che "guardare", così come i cambiamenti componente di valore verranno automaticamente riflesse nel chicco e viceversa.
Ma come fare questo senza introspezione?
Come? Cosa?!
Come abbiamo visto in GWT (almeno fino a 1,7) non c'è riflessione, per cui non abbiamo scelta se non quella di trovare un altro modo di implementare l'introspezione. In primo luogo vediamo cosa è l'introspezione in Java. Secondo il JavaDoc classe java.beans.Introspector:
"La classe Introspector Fornisce un metodo standard per gli strumenti per conoscere le proprietà, eventi, e supportata da un obiettivo metodi Java Bean".
In spagnolo:
"La classe Introspector fornisce un metodo standard per gli strumenti per scoprire le proprietà, gli eventi ei metodi supportati da un Bean Java."
La parte che ci interessa è la parte della proprietà. In altre parole, vogliamo implementare un meccanismo attraverso il quale si può essere un Bean Java per chiedere quali sono le loro proprietà e quali sono i valori di questi.
La forma sta andando per la sua attuazione attraverso la creazione di una classe per ogni classe di introspezione vogliamo avere intuito.
Poi per la classe:
classe Person pubblico { private String nome; String indirizzo privato; Data di nascita privati; privati sesso boolean; Persona pubblico () { } String getName pubblico () { ritorno nome; } void setName pubblici (String name) { this.name name =; } / / Metodi getter e setter ... di più ... }
Dobbiamo implementare il tipo di "insight":
Persona pubblico PersonaIntrospection {privato, PersonaIntrospeccion pubblico () {} public Person GetPerson () {persona return;} Persona setPersona pubblico (Persona p) {persona = p;} public getProperties <String> Lista () {l <String> List <string> = new ArrayList (); l.add ("nome"); l.add ("indirizzo"); l.add ("nascita"); l.add ("sesso");} getProperty oggetto pubblico ( proprietà di stringa) {if ("nome" è uguale a (proprietà.)) persona.getNombre ritorno (); else if ("indirizzo" è uguale a (proprietà.)) persona.getDireccion ritorno ();. else if ("nascita" è uguale a ( proprietà)) return persona.getNacimiento (); else if ("sesso" è uguale a (proprietà)) return persona.getSexo ();. IllegalArgumentException altro gettare nuova (di proprietà);} public void setProperty (proprietà String, Object value) {if (. "nome" è uguale a (proprietà)) persona.setNombre ((String) value); else if ("indirizzo" è uguale a (proprietà).) persona.setDireccion ((String) value);. else if ("nascita" è uguale a (proprietà)) persona.setNacimiento ((Data) value); else if ("sesso" è uguale a (proprietà.)) persona.setSexo ((Boolean) value); altro gettare nuova IllegalArgumentException (proprietà);}} Al di là delle ottimizzazioni che si possono apportare al codice (e cache elenchi), l'idea è capire perché questa classe ci fornisce una visione in un oggetto di persona. Come dovrebbe essere immaginare, la grazia non si trova a dover scrivere il PersonaIntrospection classe. Grazia sta lavorando su cose meno noiose e più "divertente" le cose ![]()
Inserisci i generatori!
Quello che facciamo è che GWT genera classe PersonaIntrospection. Come? Utilizzando generatori. Questa è una caratteristica molto interessante di GWT. Il focus di questo articolo è spiegare generatori, c'è molta letteratura su Internet. Ecco un Basta non essere un esperto per capire quello che facciamo.
Fondamentalmente scriveremo una classe che genera codice per il XxxIntrospection Xxx classe come abbiamo visto nell'esempio di Persona. Y (per evitare di dover fare qualsiasi passo verso la creazione di compilation tipo con qualche utilità esterna) useremo l'API che consente di estendere il compilatore GWT (com.google.gwt.core.ext). NOTA: Coloro che hanno utilizzato Java APT vedrà alcune somiglianze ( http://java.sun.com/javase/6/docs/technotes/guides/apt/index.html ).
Quando il compilatore GWT incontra il GWT.create dichiarazione (di classe), che restituisce una implementazione dell'interfaccia di classe generatore invoca l'interfaccia associato alla classe (questa associazione è dichiarato nel modulo gwt.xml). Questo generatore è "scrivere" il codice che implementa la classe di interfaccia. Per scrivere questo codice sono l'assistenza delle API che ricorda molto com.google.gwt.core.ext.typeinfo Specchio API Reflection di Java.
Generare
Ora vediamo se il generatore. Ma prima vediamo come vengono utilizzati. GWT.create () prende un'interfaccia e restituisce un'implementazione di esso. Quindi definiamo un marchio di interfaccia e chiameremo introspettivo. Qualsiasi tipo che si desidera avere il supporto di introspezione costretta a implementare questa interfaccia:
introspectible {} public interface Poi la classe Persona:
Persona {public class implementa introspectible / / ... attributi e metodi ... }
Abbiamo anche bisogno di avere la lingua dell'interfaccia di introspezione:
interfaccia pubblica si estende <I Introspectable> {Introspezione I getIntrospectable (); vuoto setIntrospectable (I i); <T> T getProperty (String propName); vuoto setProperty (String propName, Object value); GetNomeProprietà Collezione <String> (); }
E per l'introspezione e l'utilizzo:
Persona persona = new Person (); GWT.create introspezione introspezione <person> = (Persona.class); instrospection.setIntrospectable (persona); for (String prop: instrospection.getPropertyNames ()) { System.out.println (prop + "=" + instrospection.getProperty (prop)); } Instrospection.getProperty String name = ("nome"); Instrospection.getProperty String address = ("indirizzo"); Data di nascita = instrospection.getProperty ("nascita"); Instrospection.getProperty sesso = booleani ("sesso");
Per associare l'interfaccia generatore introspettivo, aggiungere il seguente frammento:
class = "com.aquait.utils.gwt.rebind.IntrospectionGenerator"> <generate-con class = "com.aquait.utils.gwt.introspection.Introspectable" /> <quando di tipo assegnabile </ Genera-con>
Così, quando il compilatore GWT è GWT.create (Persona.class), chiamato il generatore per la Persona classe implementa introspettivo. Poi abbiamo una implementazione dell'interfaccia introspezione per la classe Persona.
Per l'utilizzo in un progetto, in aggiunta nella <module> Gwt.xml.:
name = "com.aquait.utils.gwt.Introspection" /> <eredita Il modulo di GWT può essere scaricato qui: introspection4gwt
EDIT: aggiornato il file a causa di un piccolo bug.
EDIT: aggiornato ancora una volta a causa di un bug che non tiene conto delle proprietà delle classi super.
