我有一个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。作为一种解决方法,我建议改为使用事件总线。