我有一个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)
我错过了什么?另一种方式会更合适吗?
我的设置:
答案 0 :(得分:1)
看起来你正在从后台线程触发事件,后台线程不是从主UI线程产生的,例如使用执行程序,@ Async。因此,您会收到有关未绑定到线程的UI的错误。因此,View无法确定。因此,我认为这是对我们的CDI附加组件中提交的类似问题的嘲讽https://github.com/vaadin/cdi/issues/226作为一种解决方法,我建议使用事件总线。