Внедрить бин vaadin @UIScope весной @Component

Я использую Vaadin Spring 1.0.0 и пытаюсь понять, как я могу внедрить bean-компоненты, доступные только в рамках пользовательского интерфейса (когда пользователь открыл страницу) в классические bean-компоненты spring @Component. Просто, давайте классы:

@Component
public class A {

    @Inject
    private IB b;
}

@UIScope
@SpringComponent
public class B implements IB {
}

И, очевидно, во время запуска:

Caused by: java.lang.IllegalStateException: No VaadinSession bound to current thread

Что такое нормальный способ, как это сделать? Я понимаю всю концепцию, что bean-компоненты инициализируются при запуске, когда область пользовательского интерфейса недоступна, но я использую общие библиотеки, которые реализованы в Spring с помощью @Component, и я хочу реализовать некоторые интерфейсы, но я могу сделать это только в области пользовательского интерфейса. а не при запуске.


person Mejmo    schedule 14.10.2015    source источник
comment
Класс A также должен быть UIScope.   -  person Mark Rotteveel    schedule 14.10.2015
comment
In addition to @MarkRotteveel's comment, вики vaadin также объясняет причину: ...Anything injected with that annotation will get the same instance while within the same UI. Load a different UI and you'll get a different instance. If the session expires or the UI is closed, the instances will be cleaned up.   -  person Morfic    schedule 14.10.2015
comment
@MarkRotteveel Да, это возможно, но класс A взят из общей библиотеки и использует десятки других классов. Это означает, что я должен добавить @UIScope к каждому зависимому классу в общей библиотеке. Однако эта общая библиотека также используется в приложениях с весенней загрузкой, где нет области пользовательского интерфейса или Vaadin.   -  person Mejmo    schedule 14.10.2015
comment
Хорошо, я назначил UIScope только для некоторых классов, которым он действительно был нужен, и теперь он должен работать.   -  person Mejmo    schedule 14.10.2015
comment
@Mejmo Тогда вам, вероятно, потребуется создать подкласс, чтобы вы могли аннотировать его с помощью ViewScope или определить конкретный именованный компонент с аннотацией, которую вы используете вместо обнаруженного компонента.   -  person Mark Rotteveel    schedule 14.10.2015
comment
Эй, Меймо, ты смог это решить? Я не могу внедрить аннотированные классы UIScope в RestControllers   -  person Enoobong    schedule 27.07.2019
comment
Да, я решил это - удалив любые весенние аннотации для моих классов пользовательского интерфейса. Я просто добавляю все необходимые компоненты в свой основной класс пользовательского интерфейса и вызываю его с помощью UI.getInstance().getSomeBean(). Это хакерский способ, но в следующий раз я бы вообще не использовал интеграцию spring/vaadin.   -  person Mejmo    schedule 27.07.2019


Ответы (2)


Вместо этого попробуйте внедрить прокси с областью действия aop.

Например:

@Scope(value="vaadin-ui", proxyMode=ScopedProxyMode.INTERFACES)
@SpringComponent
public class B implements IB {
}

Я думаю, это должно сработать.

person Jose Luis Martin    schedule 15.10.2015

Вам нужно получить его от самого ApplicationContext:

@Component
public class A {

      @Autowired
      private ApplicationContext context;

      public B getCurrentB(){
            return context.getBean(B.class);
      }
}

Обратите внимание, что будет выдано исключение, если пользовательский интерфейс не привязан к текущему потоку (обычно). Другими словами, вы ДОЛЖНЫ убедиться, что этот метод вызывается только во время запроса пользовательского интерфейса. Любой слушатель в Vaadin должен быть в порядке, если вы находитесь в том же потоке с запросом.

person bekce    schedule 14.10.2015