从Spring EventListener更新Vaadin 8 UI

时间:2018-04-27 08:28:29

标签: java spring spring-boot events vaadin8

我有一个Spring Boot Vaadin应用程序,在服务层中有一个长时间运行的线程(从UI触发)。当线程正在运行时,我想将进度的更新返回给View类并将其显示给用户。

我以为我可以使用Spring Event机制(ApplicationEventPublisher,EventListener)从服务层发送事件,并在UI中做出相应的反应。

但是,服务无法将视频发布到视图中,如Scope 'vaadin-ui' is not active for the current thread

查看:

@SpringView
public class CustomView extends Composite implements View {
    private void triggerService() {
        new Thread(() -> service.executeLongRunningOperation()).start();
    }

    @EventListener
    private void onUpdate(UpdateEvent event) {
        getUI().access(() -> doSomething...);
    }
}

服务:

@Service
public class CustomService {
    @Autowired
    private ApplicationEventPublisher publisher;

    @Transactional
    public void executeLongRunningOperation() {
        // Some operation
        publisher.publishEvent(new UpdateEvent());
    }
}

我的UI类使用@Push进行注释。

例外:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'viewCache': Scope 'vaadin-ui' is not active for the current thread; consider defining a scoped proxy for this bean if you intend to refer to it from a singleton; nested exception is java.lang.IllegalStateException: No VaadinSession bound to current thread
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:362)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:224)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveNamedBean(DefaultListableBeanFactory.java:1015)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:339)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:334)
    at com.vaadin.spring.internal.ViewScopeImpl$BeanFactoryContextViewCacheRetrievalStrategy.getViewCache(ViewScopeImpl.java:132)
    at com.vaadin.spring.internal.ViewScopeImpl.getViewCache(ViewScopeImpl.java:109)
    at com.vaadin.spring.internal.ViewScopeImpl.get(ViewScopeImpl.java:77)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:350)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)

我错过了什么?另一种方式会更合适吗?

我的设置:

  • Vaadin 8.3.3
  • Spring Boot 2.0.1

1 个答案:

答案 0 :(得分:1)

看起来你正在从后台线程触发事件,后台线程不是从主UI线程产生的,例如使用执行程序,@ Async。因此,您会收到有关未绑定到线程的UI的错误。因此,View无法确定。因此,我认为这是对我们的CDI附加组件中提交的类似问题的嘲讽https://github.com/vaadin/cdi/issues/226作为一种解决方法,我建议使用事件总线。