Da eine Reflektion auf der Client-Seite nicht möglich ist, ist die einzige Lösung, die Sie nachahmen müssen, die verzögerte Bindung.
Verwenden Sie die verzögerte Bindung, um alle Klassen zu ermitteln, die Sie während der Kompilierung mit dem Klassennamen instanziieren möchten. Sie können eine Markierungsschnittstelle für alle diese Klassen verwenden, um TypeOracle dabei zu unterstützen, diese zu identifizieren. Sie generieren dynamisch eine Factory-Klasse, die den einfachen Namen der Klasse übernimmt und ein neu instanziiertes Objekt dieser Klasse zurückgibt. Der Ansatz ist sehr geradlinig und Sie finden eine gute Erklärung der verzögerten Bindung in Googles Tutorials zu booten.
Bearbeiten: - Einige Skelett-Code, um loszulegen. (abgespeckte Version meines Produktionscode, überprüfen Sie Compiler-Fehler in der generierten Datei! Und debuggen den Fluss)
Zuerst> den folgenden Klappentext in Ihren * .gwt.xml hinzufügen, um damit Der Compiler ruft unseren com.package.ReflectionGenerator auf, der eine einfache Factory-Klasse generiert, um die Reflektion auf der Client-Seite nachzuahmen.
<generate-with class="com.package.ReflectionGenerator">
<when-type-assignable class="com.package.client.Reflection" />
</generate-with>
Weiter> eine Schnittstelle für unsere Fabrik Klasse definieren
public interface Reflection {
public <T, V extends T> T instantiate(Class<V> clazz);
}
Letzte> ReflectionGenerator Implement
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import com.google.gwt.core.ext.BadPropertyValueException;
import com.google.gwt.core.ext.Generator;
import com.google.gwt.core.ext.GeneratorContext;
import com.google.gwt.core.ext.PropertyOracle;
import com.google.gwt.core.ext.TreeLogger;
import com.google.gwt.core.ext.UnableToCompleteException;
import com.google.gwt.core.ext.typeinfo.JClassType;
import com.google.gwt.core.ext.typeinfo.TypeOracle;
import com.google.gwt.user.rebind.ClassSourceFileComposerFactory;
import com.google.gwt.user.rebind.SourceWriter;
public class ReflectionGenerator extends Generator
{
@Override
public String generate(TreeLogger logger, GeneratorContext context, String typeName) throws UnableToCompleteException
{
TypeOracle oracle = context.getTypeOracle();
JClassType instantiableType = oracle.findType(MarkerInterface.class.getName());
List<JClassType> clazzes = new ArrayList<JClassType>();
PropertyOracle propertyOracle = context.getPropertyOracle();
for (JClassType classType : oracle.getTypes())
{
if (!classType.equals(instantiableType) && classType.isAssignableTo(instantiableType))
clazzes.add(classType);
}
final String genPackageName = "com.package.client";
final String genClassName = "ReflectionImpl";
ClassSourceFileComposerFactory composer = new ClassSourceFileComposerFactory(genPackageName, genClassName);
composer.addImplementedInterface(Reflection.class.getCanonicalName());
composer.addImport("com.package.client.*");
PrintWriter printWriter = context.tryCreate(logger, genPackageName, genClassName);
if (printWriter != null)
{
SourceWriter sourceWriter = composer.createSourceWriter(context, printWriter);
sourceWriter.println("ReflectionImpl() {");
sourceWriter.println("}");
printFactoryMethod(clazzes, sourceWriter);
sourceWriter.commit(logger);
}
return composer.getCreatedClassName();
}
private void printFactoryMethod(List<JClassType> clazzes, SourceWriter sourceWriter)
{
sourceWriter.println();
sourceWriter.println("public <T, V extends T> T instantiate(Class<V> clazz) {");
for (JClassType classType : clazzes)
{
if (classType.isAbstract())
continue;
sourceWriter.println();
sourceWriter.indent();
sourceWriter.println("if (clazz.getName().endsWith(\"." + classType.getName() + "\")) {");
sourceWriter.indent();
sourceWriter.println("return (T) new " + classType.getQualifiedSourceName() + "();");
sourceWriter.outdent();
sourceWriter.println("}");
sourceWriter.outdent();
sourceWriter.println();
}
sourceWriter.indent();
sourceWriter.println("return (T) null;");
sourceWriter.outdent();
sourceWriter.println();
sourceWriter.println("}");
sourceWriter.outdent();
sourceWriter.println();
}
}
Dies sollte die Factory-Klasse ReflectionGenerator in Ihrem Arbeitsbereich erzeugen, Scheck die generierte Datei und optimieren Sie den Quelltext des Writers, um den Code zu generieren de du begehrst.
Nutzungs GWT.create(Reflection.class).instantiate(YourClass.class);
ich eine Markierungsschnittstelle 'MarkerInterface'
im Generator verwendet haben, die Anzahl der Klassen durch die Fabrik, also als Ergebnis alle teilnehmenden Klassen implementieren müssen 'MarkerInterface'
sieht aus wie ein Duplikat von http://stackoverflow.com/questions/451658/gwt-dynamic-loading-using-gwt-create-with-string-literals-instead-of-class-lite –
Thanks.I am erwarte auch dasselbe. – DonX