У меня есть приложение Spring Boot Vaadin с долго работающим потоком на уровне обслуживания (которое запускается из пользовательского интерфейса). Пока поток запущен, я хотел бы предоставить обновления о прогрессе обратно в класс View и показать его пользователю.
Я подумал, что мог бы использовать механизм Spring Event (ApplicationEventPublisher, EventListener), чтобы отправлять события из сервисного уровня и соответствующим образом реагировать в пользовательском интерфейсе.
Однако Служба не может опубликовать событие в представлении, как 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());
}
}
Мой класс пользовательского интерфейса помечен @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