showcase meaning ejemplos gwt

meaning - gwt vs angular



Carga dinĂ¡mica de GWT usando GWT.create() con literales de cadena en lugar de literales de clase (9)

Al no haber examinado el código de rocket / gwittir (que debe hacer si desea saber cómo lo hicieron, es de código abierto después de todo), solo puedo adivinar que emplean enlaces diferidos de tal manera que durante la compilación tiempo, resuelven todas las llamadas a la reflexión y generan estáticamente todo el código requerido para implementar esas llamadas. Entonces durante el tiempo de ejecución, no puedes hacer diferentes.

GWT.create () es el reflejo equivalente en GWT, pero solo toma literales de clase, cadena no totalmente calificada para el nombre de clase. ¿Cómo creo dinámicamente clases con cadenas usando GWT.create ()?

No es posible de acuerdo con muchas publicaciones del foro de GWT, pero ¿cómo se está haciendo en marcos como Rocket-GWT ( http://code.google.com/p/rocket-gwt/wiki/Ioc ) y Gwittir ( http: // code .google.com / p / gwittir / wiki / Introspection )


Lo que estás tratando de hacer no es posible en GWT.

Si bien GWT hace un buen trabajo al emular Java en tiempo de compilación, el tiempo de ejecución es completamente diferente. La mayoría de las reflexiones no son compatibles y no es posible generar o cargar dinámicamente clases en tiempo de ejecución.

He echado un vistazo breve al código de Gwittir y creo que están haciendo su "reflexión" en el momento de la compilación. Aquí: http://code.google.com/p/gwittir/source/browse/trunk/gwittir-core/src/main/java/com/totsp/gwittir/rebind/beans/IntrospectorGenerator.java


Todo es posible ... aunque puede ser difícil o incluso inútil. Como Jan ha mencionado, debes usar un generador para hacer eso. Básicamente, puede crear su interfaz del código del generador que toma esa interfaz y compilar en el momento de la creación y le devuelve la instancia. Un ejemplo podría ser:

//A marker interface public interface Instantiable { } //What you will put in GWT.create public interface ReflectionService { public Instantiable newInstance(String className); } //gwt.xml, basically when GWT.create finds reflectionservice, use reflection generator <generate-with class="...ReflectionGenerator" > <when-type-assignable class="...ReflectionService" /> </generate-with> //In not a client package public class ReflectionGenerator extends Generator{ ... } //A class you may instantiate public class foo implements Instantiable{ } //And in this way ReflectionService service = GWT.create(ReflectionService.class); service.newInstance("foo");

Todo lo que necesitas saber es cómo hacer el generador. Puedo decirte que al final lo que haces en el generador es crear código Java de esta manera:

if ("clase1".equals(className)) return new clase1(); else if ("clase2".equals(className)) return new clase2(); ...

En la final, pensé, común que puedo hacerlo a mano en una especie de InstanceFactory ... Saludos cordiales


Es posible, aunque complicado. Aquí están los detalles sangrientos:

Si solo piensas como GWT como un Java directo a JS, no funcionaría. Sin embargo, si considera Generadores - Clases especiales con su compilador GWT Compila y Ejecuta durante la compilación, es posible. Por lo tanto, puede generar fuente Java mientras compila.

Hoy tuve esta necesidad: nuestro sistema trata los recursos dinámicos de un servicio, terminando en una cadena y la necesidad de una clase. Aquí está la solución que he encontrado - por cierto, funciona en hosting, IE y Firefox.

  • Crea un módulo GWT declarando:
    • Una ruta fuente
    • Un generador (que debe mantenerse FUERA del paquete de la ruta de origen del Módulo GWT)
    • Un reemplazo de interfaz (inyectará la clase generada en lugar de la interfaz)
  • Dentro de ese paquete, cree una interfaz Marker (lo llamo Constructable). El generador buscará ese marcador
  • Crea una clase abstracta base para mantener esa fábrica. Lo hago para facilitar el código fuente generado
  • Declare que el módulo hereda en su Application.gwt.xml

Algunas notas:

  • La clave del entendimiento está en torno al concepto de generadores;
  • Para facilitar, la clase base Abstracta fue útil.
  • Además, entienda que hay un nombre mandling en la fuente .js generada e incluso la fuente Java generada
  • Recuerde que el generador genera archivos java
  • GWT.create necesita alguna referencia al archivo .class. La salida de su generador puede hacer eso, siempre que se haga referencia a ella de alguna manera (compruebe Application.gwt.xml hereda su módulo, que también reemplaza una interfaz con el generador que declara Application.gwt.xml)
  • Envuelva la llamada GWT.create dentro de un método de fábrica / singleton, y también bajo GWT.isClient ()
  • Es una muy buena idea también envolver sus llamadas de carga de clase de código alrededor de un GWT.runAsync, ya que podría necesitar activar una carga de módulo. Esto es MUY importante.

Espero publicar el código fuente pronto. Cruza tus dedos. :)



Brian,

El problema es que GWT.create no sabe cómo elegir la implementación correcta para su clase abstracta

Tuve el mismo problema con el nuevo estilo de codificación GWT MVP (consulte la documentación de GWT MVP )

Cuando llamé:

ClientFactory clientFactory = GWT.create(ClientFactory.class);

Estaba obteniendo el mismo error:

El tipo de resultado de enlace diferido ''com.test.mywebapp.client.ClientFactory'' no debe ser abstracto

Todo lo que tenía que hacer era agregar las siguientes líneas a mi archivo MyWebapp.gwt.xml:

<!-- Use ClientFactoryImpl by default --> <replace-with class="com.test.mywebapp.client.ClientFactoryImpl"> <when-type-is class="com.test.mywebapp.client.ClientFactory"/> </replace-with>

Entonces funciona como un encanto


Es posible que pueda evitar todo el problema al hacerlo en el lado del servidor. Diga con un servicio que toma String y devuelve una especie de super tipo serializable. Del lado del servidor puedes hacer

return (MySerializableType)Class.forName("className").newInstance();

Dependiendo de sus circunstancias, podría no ser un gran cuello de botella de rendimiento.


Me encontré con esto hoy y descubrí una solución. El que pregunta está queriendo escribir un método como:

public <T extends MyInterface> T create(Class<T> clz) { return (T)GWT.create(clz); }

Aquí MyInterface es simplemente una interfaz de marcador para definir el rango de clases que quiero ser capaz de generar dinámicamente. Si intenta codificar lo anterior, obtendrá un error. El truco es definir un "instanciador" como:

public interface Instantiator { public <T extends MyInterface> T create(Class<T> clz); }

Ahora defina un generador de enlace diferido GWT que devuelva una instancia de la anterior. En el generador, consulte el TypeOracle para obtener todos los tipos de MyInterface y genere implementaciones para ellos como lo haría con cualquier otro tipo:

p.ej:

public class InstantiatorGenerator extends Generator { public String generate(...) { TypeOracle typeOracle = context.getTypeOracle(); JClassType myTYpe= typeOracle.findType(MyInterface.class.getName()); JClassType[] types = typeOracle.getTypes(); List<JClassType> myInterfaceTypes = Collections.createArrayList(); // Collect all my interface types. for (JClassType type : types) { if (type.isInterface() != null && type.isAssignableTo(myType) && type.equals(myType) == false) { myInterfaceTypes.add(type); } for (JClassType nestedType : type.getNestedTypes()) { if (nestedType.isInterface() != null && nestedType.isAssignableTo(myType) && nestedType.equals(myTYpe) == false) { myInterfaceTypes.add(nestedType); } } } for (JClassType jClassType : myInterfaceTypes) { MyInterfaceGenerator generator = new MyInterfaceGenerator(); generator.generate(logger, context, jClassType.getQualifiedSourceName()); } } // Other instantiator generation code for if () else if () .. constructs as // explained below. }

La clase MyIntefaceGenerator es como cualquier otro generador de enlace diferido. Excepto que lo llame directamente dentro del generador anterior en lugar de hacerlo a través de GWT.create. Una vez que se realiza la generación de todos los subtipos conocidos de MyInterface (al generar subtipos de MyInterface en el generador, asegúrese de hacer que el nombre de clase tenga un patrón único, como MyInterface.class.getName () + "_MySpecialImpl") , simplemente crea el Instalador haciendo una nueva iteración a través de todos los subtipos conocidos de MyInterface y creando un grupo de

if (clz.getName().equals(MySpecialDerivativeOfMyInterface)) { return (T) new MySpecialDerivativeOfMyInterface_MySpecialImpl();}

estilo de código. Por último, lanza una excepción para que puedas devolver un valor en todos los casos.

Ahora donde llamarías a GWT.create(clz); en su lugar, haz lo siguiente:

private static final Instantiator instantiator = GWT.create(Instantiator.class); ... return instantiator.create(clz);

También tenga en cuenta que en su módulo GWT xml, solo definirá un generador para Instantiator, no para generadores MyInterface:

<generate-with class="package.rebind.InstantiatorGenerator"> <when-type-assignable class="package.impl.Instantiator" /> </generate-with>

¡Bingo!


¿Cuál es exactamente la pregunta? Supongo que desea pasar parámetros además del literal de la clase a un generador.

Como probablemente ya sepa, el literal de clase pasado a GWT.create () es principalmente un selector para que GWT pueda seleccionar y ejecutar un generador que al final escupe una clase. La forma más fácil de pasar un parámetro al generador es usar anotaciones en una interfaz y pasar el interface.class a GWT.create (). Tenga en cuenta, por supuesto, que la interfaz / clase debe extender la clase literal pasada a GWT.create ().

class Selector{ } @Annotation("string parameter...") class WithParameter extends Selector{} Selector instance = GWT.create( WithParameter.class )