2012-01-28 31 views
8

Có thể sử dụng phương sai loại trong các sự kiện CDI không? đây là trường hợp:Làm thế nào để sử dụng kế thừa và danh sách các sự kiện CDI?

  • Giả sử tôi có một loại sự kiện gốc MyEvent và lớp con DummyEvent
  • Mục tiêu của tôi là để xử lý một danh sách các sự kiện nhận được từ một nguồn ở xa List<? extends MyEvent>, chứa DummyEvent trường

Tôi có thể làm cái này như thế nào?

Nếu tôi lặp lại bộ sưu tập gọi fire() trên mỗi sự kiện, nó sẽ gọi @Observes MyEvent evt nhưng không phải là phương thức @Observes DummyEvent evt.

** cập nhật **

Tạo một mẫu mã để làm rõ vấn đề này:

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

Tôi muốn sự kiện được bắn hai lần, một lần cá nhân và một lần từ danh sách .

+0

Bạn đang sử dụng CDI nào? –

+0

hàn trong jboss là 7 –

Trả lời

1

Mhh Tôi không hiểu ... mã thực sự của bạn kích hoạt sự kiện như thế nào? ASFAIK bạn tiêm giao diện javax.enterprise.event.Event và truyền một thể hiện tới phương thức lửa của nó, mà bằng cách khai báo người quan sát được gọi. Và nếu thừa kế có liên quan, như trong trường hợp của bạn, cả hai Observer sẽ được gọi, nếu bạn bắn một DummyEvent. Nếu bạn muốn chỉ định thêm các sự kiện bạn sẽ sử dụng Vòng loại.

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

/* chỉnh sửa */

Các "vấn đề" là dòng mã sau đây:

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

Ngay sau khi bạn thể chỉ định kiểu của sự kiện (MyEvent.class), loại cá thể sự kiện thực tế (evt) không quan trọng nữa. Một khả năng là mở rộng lớp học hirachy của bạn với Vòng loại. Ví dụ:

@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"); 
    }  
} 

Sau đó tiếp tục xác định Observer:

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

Cuối cùng, khi bạn vừa truy cập đến các lớp học cơ sở, như trong ví dụ của bạn, nơi bạn itarate thông qua một danh sách, bạn có thể xác định chính xác loại/vòng loại trước khi kích hoạt sự kiện như vậy:

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

Như đã đề cập ở trên, nếu bạn có một người quan sát chung (bên dưới), nó sẽ được gọi cho mỗi sự kiện.

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

Vui lòng xem ví dụ mã tôi vừa thêm, hy vọng sẽ làm cho vấn đề rõ ràng hơn một chút. –

+0

Đã chỉnh sửa câu trả lời, có thể giúp ích. –

+0

Nó giúp, nhưng tôi có một giải pháp chỉ sử dụng các loại ... cảm ơn bạn đã đăng bài, đã học được mẹo :) –

Các vấn đề liên quan