UrlRouting в обычных Spring Компонентах

Здравствуйте, есть ли возможность сделать WebUrlRouting без @UIScope? Или хотя бы вынести getRouteGenerator().getEditorRoute(entity) в отдельный компонент?

Стоит задача при создании определенных сущностей создавать другую сущность с url ссылкой на первую. Ну и UrlRouting нельзя инджектить в EntityListener тк падает ошибка:

Caused by: org.springframework.beans.factory.support.ScopeNotActiveException: Error creating bean with name 'ui_UrlRouting': 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:383) ~[spring-beans-5.3.22.jar:5.3.22]
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) ~[spring-beans-5.3.22.jar:5.3.22]
	at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:276) ~[spring-beans-5.3.22.jar:5.3.22]
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1391) ~[spring-beans-5.3.22.jar:5.3.22]
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1311) ~[spring-beans-5.3.22.jar:5.3.22]
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.resolveFieldValue(AutowiredAnnotationBeanPostProcessor.java:656) ~[spring-beans-5.3.22.jar:5.3.22]
	... 21 common frames omitted
Caused by: java.lang.IllegalStateException: No VaadinSession bound to current thread
	at com.vaadin.spring.internal.UIScopeImpl$VaadinSessionBeanStoreRetrievalStrategy.getVaadinSession(UIScopeImpl.java:144) ~[vaadin-spring-3.1.1.jar:3.1.1]
	at com.vaadin.spring.internal.UIScopeImpl$VaadinSessionBeanStoreRetrievalStrategy.getUIStore(UIScopeImpl.java:155) ~[vaadin-spring-3.1.1.jar:3.1.1]
	at com.vaadin.spring.internal.UIScopeImpl$VaadinSessionBeanStoreRetrievalStrategy.getBeanStore(UIScopeImpl.java:184) ~[vaadin-spring-3.1.1.jar:3.1.1]
	at com.vaadin.spring.internal.UIScopeImpl.getBeanStore(UIScopeImpl.java:103) ~[vaadin-spring-3.1.1.jar:3.1.1]
	at com.vaadin.spring.internal.UIScopeImpl.get(UIScopeImpl.java:79) ~[vaadin-spring-3.1.1.jar:3.1.1]
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:371) ~[spring-beans-5.3.22.jar:5.3.22]
	... 26 common frames omitted

Здравствуйте!

WebUrlRouting использует внутри себя UI класс и соответственно привязан к его жизненному циклу (UIScope), поэтому убрать эту аннотацию не получится.

Но это не должно мешать использовать его в бинах. При инжекции через студию добавляется код:

@Autowired
private ObjectProvider<UrlRouting> urlRoutingProvider;

Например, пользоваться им можно так:

public void useRouting() {
    UrlRouting urlRouting = urlRoutingProvider.getIfAvailable();
    if (urlRouting != null) {
        log.info(urlRouting);
    }
}
4 симпатии

Добрый день!
Jmix 1.5.5

@Autowired
private ObjectProvider<UrlRouting> urlRoutingProvider;

Не работает если бин используется в джобе.
urlRoutingProvider.getIfAvailable() выдает null.

Как быть?

Добрый день!

Не работает если бин используется в джобе.

Имеете в виду Quartz джобу? Там стартует отдельный поток, в котором UI не доступен. Соответственно и все бины c UIScope: UrlRouting, Screens и т.д.

Если нужен доступ к UI, то целесообразнее использовать BackgroundTask (Фоновые задачи :: Документация Jmix).

Да.

А как тогда BackgroundTask запускать по расписанию?

По рассписанию скорее всего не получится. Запущенная BackgroundTask по сути хранится в сессии пользователя, и когда сессия уничтожается все таски завершаются. Но при этом из таски можно достучаться до UI.