2016-06-29 2 views
0

Vaadin 응용 프로그램 내에서 메서드에 대한 비동기 결과 개요를 구현할 계획입니다.스레드 내에서 CDI 이벤트 발생

결과 개요에는 가능한 결과에 대한 테이블이 있습니다. 이러한 결과는 백엔드 메소드가 스레드에서 비동기로 실행되는 동안 생성되어야합니다. 응용 프로그램의 백엔드와 프론트 엔드 간의 통신은 CDI 이벤트를 사용하여 계획됩니다 (결과에 대한 정보는 CDI 이벤트에 있습니다).

이미 CDI 이벤트를 발생 시키려면 결과 테이블에 넣고 메소드가 완료된 후에 테이블을 표시하십시오. 그러나 스레드 내에서 메소드를 실행할 때 (보기가 표시되고 이벤트가 전체 테이블을보기 위해 대기하는 대신 삽입되는 경우) CDI 이벤트가 실행되지 않습니다.

해결 방법이 있습니까? 나는 CDI-이벤트 비동기 (blog entry를) 수신에 대해 읽어,하지만 난 ... 스레드에서 이벤트를 발사에 대해 아무것도 찾지 못했습니다

제이보스 10.0.1.Final, 자바 (8), 자바 EE 7 angel이라는 7.6.6 . CDI-이벤트를 해고해야

스레드 :

public class Executer implements Runnable{ 

    @Override 
    public void run(){ 
    // Here will be the backend-method invocation for firing CDI-Events 

    // CDI-Dummy-Event - Does not fire properly. receiveStatusEvent() does not invoke 
    BeanManager beanManager = CDI.current().getBeanManager(); 
    beanManager.fireEvent(new ResultEvent("Result event example")); 
    } 

} 

콩 CDI 1.2에서 ManagedExecutorService

에서 도움을 스레드를 시작
public void executeAsynchBackendMethod(){ 

    // CDI-Dummy-Event works - receiveStatusEvent() invokes correctly 
    BeanManager beanManager = CDI.current().getBeanManager(); 
    beanManager.fireEvent(new ResultEvent("Result event example")); 

    /* The following alternative starts a thread, but the events, which are fired in the run() method, do not take any action in the receiveStatusEvent() method */ 

    // Getting managedExecuterService 
    this.managedExecuterService = (ManagedExecutorService) new InitialContext().lookup("java:comp/DefaultManagedExecutorService"); 

    // Getting Instance of executer-Runnable (for injecting the backend-service afterwards) 
    Instance<Executer> executerInstance = CDI.current().select(Executer.class); 
    Executer executer = executerInstance.get(); 

    // Start thread 
    this.managedExecuterService.submit(executer); 
} 
+0

다른 스레드에서 Vaadin 구성 요소에 액세스하려면 [UI 액세스 방법] (https://vaadin.com/docs/-/part/framework/advanced/advanced-push.html#advanced)이 필요합니다. push.running) 및 Vaadin Push 또는 [poll] (https://vaadin.com/wiki/-wiki/Main/Using+polling)과 같은 브라우저에 대한 비동기 업데이트의 일부 유형이 있습니다. 그렇지 않으면 UI 변경 사항이 다음 요청 (예 : 버튼 클릭)이 발생할 때까지 클라이언트에 전송되지 않습니다. –

+0

이 조언에 감사드립니다. UI 액세스는 .access()를 통해 이루어진다는 것을 알고 있습니다.하지만 AFAIC은 Concure UI 변경이 구현 될 때 (예 : 결과 테이블에 결과 하나 추가)와 같이 사용해야합니다. 응용 프로그램의 UI에 대한 액세스 권한을 제공합니다. 나는 이미 .access()로 시도했지만, UI가 블로킹되었고, 메소드가 완료 될 때까지 블럭되었다. complex backend-method를 실행하기 위해 managedExecuterService로 스레드를 생성한다. –

답변

0

을 CDI-이벤트

public class EventReceiver implements LoggingProvider{ 

    public EventReceiver(){ 

    } 

    public void receiveStatusEvent(@Observes ResultEvent event) { 
    this.info("Event received: " + event.toString()); 
    } 

} 

를 수신 아래 이벤트는 완전히 동기식입니다. CDI 2.0에는 이미 Weld의 비동기 이벤트가 구현 된 버전이 있지만 1.2 버전을 사용하고 있다고 가정합니다.

즉, 블로그 게시물에서 제안한 내용을 읽으면 악명 높은 EJB를 사용할 수 있습니다.

이 경우 CDI가 작동하지 않는 이유는 다음과 같습니다. 이것이 스레드 바인딩 된 것입니다. 다시 말해, 이벤트를 발생시키는 주어진 스레드에서 트리거 할 관찰자가 없습니다.

+0

답변 해 주셔서 대단히 감사합니다. 나는 해결책을 만들었고 스레드에서 메소드를 시작하는 대신 백엔드 메소드에'@Asynchronous & @TransactionAttribute (TransactionAttributeType.REQUIRES_NEW)'로 주석을 달았다. 이제는 CDI 1.2의 단점을 피하고 비동기 메서드를 호출하는 동안 이벤트를 얻을 수 있습니다 ... ** 매력은 **처럼 작동합니다! –

관련 문제