Réflexion GWT

5 décembre 2009 par Enrique Laisser une réponse »

Intro

S'inscrivant dans la ligne de l'introspection, aujourd'hui, nous allons voir une simple réflexion qui va nous permettre d'invoquer sur une instance d'une méthode de classe par son nom.

Pour quoi faire?

La réflexion est une caractéristique intéressante, ce qui est fondamental pour la conception de médicaments génériques. Nous pouvons créer des instances d'une classe avec le nom de la classe ou encore appeler des méthodes sur une instance d'une classe ayant le nom de la méthode. C'est, par exemple, il simplifie grandement la mise en œuvre du modèle de commande.

Comment? Qu'est-ce?!

Dans GWT (au moins jusqu'à 1,7) il n'ya pas de réflexion. Qu'est-ce que nous faisons dans cette mise en œuvre de la réflexion est de fournir un mécanisme pour appeler les méthodes par son nom. En supposant que nous avons une classe appelée MaClasse possède une méthode appelée myMethod nous pourrions faire quelque chose comme ceci:

  MyClass instance = new MaClasse (); 
  Chaîne NombreMetodo = "maMethode"; 
  Object [] parameters = new Object [] {...}; 
  invoquer (par exemple, nombreMetodo, paramètres); 

Entrez les générateurs!

Qu'est-ce que nous faisons est que GWT génère la classe MiClaseReflection. Comment? Utilisation des générateurs. C'est une caractéristique très intéressante de GWT. L'objectif de cet article est d'expliquer les générateurs, il ya beaucoup de littérature sur l'Internet. Voici une va Il suffit de ne pas être un expert pour comprendre ce que nous faisons.

Fondamentalement, nous allons écrire une classe qui génère le code MiClaseReflection, qui a une seule méthode de garde-c'est une chaîne si .. elseif .. d'autre qui demande pour chaque méthode de MaClasse et si n'importe quel match, il invoque. Il serait quelque chose comme ceci:

  si (nombreMetodo.equals ("miMetodo1")) { 
  target.miMetodo1 (params) / / void 
  } Else if (nombreMetodo.equals ("miMetodo2")) { 
  target.miMetodo2 retour (params) / / pas de vide 
  Else {} 
  throw new Exception ("méthode de recherche:" + nombreMetodo); 
 } 

Il est évident manque contrôles de paramètres.

Pour éviter d'avoir à faire aucune étape vers la création de la compilation genre avec une certaine utilité externe sera en utilisant l'API qui vous permet d'étendre le compilateur de GWT (com.google.gwt.core.ext). NOTE: Ceux qui ont utilisé Java APT verrez quelques similitudes ( http://java.sun.com/javase/6/docs/technotes/guides/apt/index.html ).

Lorsque le compilateur de GWT rencontre le GWT.create déclaration (classe)-qui renvoie une classe d'implémentation d'interface, invoque le générateur associé à la classe d'interface (cette association est déclarée dans le module gwt.xml). Ce générateur est "écrire" le code qui implémente la classe d'interface. Pour écrire ce code ont l'aide de l'API com.google.gwt.core.ext.typeinfo très rappelle à Mirror API de réflexion de Java.

Générer

Le GWT.create instruction () prend une interface et retourne une mise en œuvre de celui-ci. Ensuite, nous définissons une stratégie de marque d'interface et que nous appellerons être réfléchi. Toute classe qui veulent avoir le soutien de réflexion devra implémenter cette interface:

  Être réfléchi {interface publique 
  } 

Puis la classe MyClass:

  public class MyClass implémente être réfléchi { 
  miMetodo1 vide (); 
  miMetodo2 int (); 
  } 

En outre, nous devons avoir la langue d'interface de réflexion:

  interface publique s'étend être réfléchi> {réflexion <I 
  Objet invoquer (je cible, String methodName, objet ... params) 
  InvocationException jette; 
  } 

Pour une réflexion et myMethod utilisation en supposant qu'aucun des paramètres:

  MaClasse objet = new MaClasse (); 
  <MiClase> Réflexion Réflexion = GWT.create (MiClase.class); 
  reflection.invoke (objet, "maMethode"); 

Pour associer l'interface générateur être réfléchi, ajoutez le code suivant à:

  <generate-with class="com.aquait.utils.gwt.rebind.ReflectionGenerator"> 
  class="com.aquait.utils.gwt.reflection.Reflectable"/> <when-type-assignable 
  </ Générer-avec> 

Ainsi, lorsque le compilateur de GWT est GWT.create (MiClase.class), appelé le générateur pour la class MyClass implements être réfléchi. Ensuite, nous avons une mise en œuvre de l'interface pour être réfléchi MyClass.

Pour une utilisation dans un projet, ajoutez ceci dans le <module> gwt.xml.:

  <inherits name="com.aquait.utils.gwt.Reflection"/> 

Le JAR peut être téléchargé ici: l'introspection-reflection4gwt.jar

Remarque: Ce JAR dispose d'une version mise à jour de l'introspection qui élimine méthodes getIntrospectable () et l'interface d'introspection setIntrospectable (). Par conséquent, la méthode getProperty () et setProperty () prend comme premier paramètre à Introspectable.

Blogger Message Digg Reddit Google Reader Part
Publicité

3 commentaires

  1. pepe dit:

    Tout bon, mais encore inutile que d'avoir à passer le MiClase.class classe littéral, vous devez savoir à l'avance quel type il s'agit et avez une référence à elle. Comment faites-vous si vous ne connaissez pas le nom de la classe à instancier à l'exécution? Puisque vous ne pouvez pas gwt ne vous laissera pas faire. La seule solution à ce problème est d'avoir un ensemble limité de classes et pré-traitées par le générateur et inséré dans une bibliothèque ou un dossier. Par exemple. register.add (GWT.create nouvelle (MiClase.class)) ainsi, alors invoquer grave register.invocarmetodo («classe», «méthode»). Cela conduit au problème de savoir à l'avance toutes les classes possibles à utiliser.

  2. Enrique Enrique dit:

    Tout ce que vous dites, oui, sauf qu'il est inutile :) .
    J'ai aussi rencontré ces problèmes et j'ai fini par mettre en œuvre le même enregistrement que comme vous le dites.
    Puis j'ai réalisé que GWT ne supporte pas les initialiseurs statiques lors de «charge» de la classe (même si vous les exécutez au moment de la nouvelle).
    Aussi nous a donné de bons résultats. Le temps fait déjà, mais je pense que nous l'utilisons pour rendre un composant générique du menu utilisateur qui pourraient être configurées et stockées dans la base de données ou de quelque chose.
    Salutations et remerciements pour l'entrée.

  3. pepe dit:

    Désolé près inutile, j'ai appris à exprimer. J'ai utilisé pour les classes de domaine dématérialisés de générer automatiquement l'interface utilisateur. Une approche similaire, mais avec GWT OpenXava. Fondamentalement «lire» les annotations JPA et les miens propres à l'exécution et de créer une enveloppe qui contient les informations nécessaires pour hacerca de cette classe. Ex-GWT puis je avoir une composante lors de l'exécution AbmMenuItem et vous montre une complète Abm cette classe, qui comprend des filtres, le formulaire d'inscription avec des composants spéciaux pour trouver un objet associé à ManyToOne par exemple.
    Salutations.

Laisser un commentaire

Protection contre les spams par WP Captcha-Free