我有一个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)


我想念什么?另一种方法更合适吗?

我的设置:


瓦丹8.3.3
Spring Boot 2.0.1

最佳答案

看来您是从后台线程触发事件,而不是从主UI线程生成的,例如使用执行程序@Async。因此,您会得到有关UI未绑定到线程的错误。结果,无法确定视图。因此,我认为这可以解决我们在此处的CDI附加组件上提交的类似问题https://github.com/vaadin/cdi/issues/226。作为一种解决方法,我建议改为使用事件总线。

09-11 19:34
查看更多