2012-01-28 7 views
8

¿Es posible usar la varianza de tipo en eventos CDI? aquí es el caso:¿Cómo usar la herencia y las listas de eventos CDI?

  • Supongamos que tengo un tipo de evento raíz MyEvent y subclase DummyEvent
  • Mi objetivo es procesar una lista de eventos recibidos desde una fuente remota List<? extends MyEvent>, que contiene DummyEvent casos

¿Cómo puedo hacer esto?

Si recorro la colección llamando al fire() en cada evento, invocará @Observes MyEvent evt pero no los métodos @Observes DummyEvent evt.

** ** actualización

Creado un código de ejemplo para aclarar el tema:

https://github.com/jfaerman/jfaerman/blob/master/test-cdi/src/main/java/jfaerman/App.java

Me gustaría que el evento para ser disparado dos veces, una vez por separado y una vez en la lista .

+0

¿Qué implementación de CDI estás usando? –

+0

soldar en jboss como 7 –

Respuesta

1

Mhh No lo entiendo ... ¿Cómo es tu código actual para activar el evento? ASFAIK usted inyecta la interfaz javax.enterprise.event.Event y pasa una instancia a su método de disparo, que por eso declara al observador llamado. Y si se trata de herencia, como en su caso, se llamaría a ambos Observer, si activa un DummyEvent. Si desea especificar más los eventos, debería usar Calificadores.

@Inject @Any Event<DummyEvent> dummyEvent; 
... 
dummyEvent.fire(list.get(i)); 

/* Editar */

El "problema" es la siguiente línea de código:

weld.event().select(MyEvent.class).fire(evt); 

Tan pronto como se specifiy tipo de evento (MyEvent.class), el tipo de evento real (evt) ya no importa. Una posibilidad es extender su clase hirachy con Calificadores. Por ejemplo:

@ChildEvent.Child 
public class ChildEvent extends BaseEvent{ 

    @Qualifier 
    @Retention(RetentionPolicy.RUNTIME) 
    @Target({ElementType.TYPE, ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER}) 
    public @interface Child{ 
    } 

    public void eventAction() { 
     System.out.println("child"); 
    }  
} 

Después de que especificar aún más el Observador:

public void observerChild(@Observes @ChildEvent.Child BaseEvent child){ 
     System.out.println("child with annotation event"); 
} 

Por último, cuando acaba de acceder a clases de base, como en el ejemplo en el que itarate través de una lista, puede especificar la exacta escribir/calificador antes de disparar el evento como que:

for (BaseEvent e : list){ 
    childEvent.select(e.getClass().getAnnotations()[0]).fire(e); 
} 

como se mencionó anteriormente, si usted tiene un Observador general (se muestra a continuación), que se llamará para cada evento.

public void observerBase(@Observes BaseEvent base){ 
    System.out.println("base event"); 
} 
+0

Por favor, vea el ejemplo del código que acabo de agregar, espero que el problema sea un poco más claro. –

+0

Editado la respuesta, tal vez ayuda. –

+0

Ayuda, pero hay una solución usando solo los tipos ... gracias por publicar, aprendí el truco :) –

Cuestiones relacionadas