【问题标题】:Update Vaadin 8 UI from Spring EventListener从 Spring EventListener 更新 Vaadin 8 UI
【发布时间】:2018-04-27 08:28:29
【问题描述】:

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

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

但是,Service 无法将事件发布到视图,如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

【问题讨论】:

    标签: java spring spring-boot events vaadin8


    【解决方案1】:

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

    【讨论】:

    • 谢谢你的解释,我明白你的意思了。我希望更多的人在 vaadin 中使用带有后台线程的 spring 事件机制,并且会有一个解决方案,但显然情况并非如此。作为一种解决方法,我将消费者接口作为回调函数传递给后台线程。不确定我是否要使用事件总线插件,因为它似乎不再维护......
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-24
    • 2015-04-01
    • 1970-01-01
    相关资源
    最近更新 更多