How does the Spring Integration work

When I add @Route to my class I can use Springs Dependency Injection.

BUT I cannot get the Bean from the ApplicationContext because it’s not registered as Bean.

If I add @Component to a @Route to make it a Spring bean I get:


Caused by: java.lang.IllegalStateException: No VaadinSession bound to current thread
	at com.vaadin.flow.spring.scopes.AbstractScope.getVaadinSession(AbstractScope.java:75) 

My questions:

  1. How is the Spring Integration done?
  2. How can I get a Route from the Spring ApplicationContext?

Components with @Route annotation are not spring-managed beans, so they are not available from the application context even though they support dependency injection. Instantiation of routed components is [managed by vaadin-spring]
(https://github.com/vaadin/spring/blob/4af221293af88b67ae011b378f5c304ddfbfc2c6/vaadin-spring/src/main/java/com/vaadin/flow/spring/SpringInstantiator.java#L104).

Regarding your second question, the Router (ui.getRouter()) allows to inspect the declared routes. You can also declare Routes as actual spring beans, and in that case they would be both spring-managed and available as navigation targets.

Thanks Javier.

I understand the answer to my 1. question.

But the the answer to the 2. question doesn’t work.
If I add @Component to my @Route I get the above exception. I have to mention that my Route is @UIScope
Is this a problem?

When is that exception raised? It’s correct to add @UIScoped, because otherwise they would be singletons (which is not correct because each time the user navigates into a view, a new instance has to be created).

The application does not start when I add @Component to the route class.

jooqRepository is also UIScoped

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jooqRepository': 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:365) ~[spring-beans-5.1.7.RELEASE.jar:5.1.7.RELEASE]

	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) ~[spring-beans-5.1.7.RELEASE.jar:5.1.7.RELEASE]

	at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:277) ~[spring-beans-5.1.7.RELEASE.jar:5.1.7.RELEASE]

	at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1248) ~[spring-beans-5.1.7.RELEASE.jar:5.1.7.RELEASE]

	at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1168) ~[spring-beans-5.1.7.RELEASE.jar:5.1.7.RELEASE]

	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:593) ~[spring-beans-5.1.7.RELEASE.jar:5.1.7.RELEASE]

	... 24 common frames omitted
Caused by: java.lang.IllegalStateException: No VaadinSession bound to current thread
	at com.vaadin.flow.spring.scopes.AbstractScope.getVaadinSession(AbstractScope.java:75) ~[vaadin-spring-11.0.0.jar:na]

	at com.vaadin.flow.spring.scopes.VaadinUIScope.getBeanStore(VaadinUIScope.java:121) ~[vaadin-spring-11.0.0.jar:na]

	at com.vaadin.flow.spring.scopes.AbstractScope.get(AbstractScope.java:44) ~[vaadin-spring-11.0.0.jar:na]

	at com.vaadin.flow.spring.scopes.VaadinUIScope.get(VaadinUIScope.java:42) ~[vaadin-spring-11.0.0.jar:na]

	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:353) ~[spring-beans-5.1.7.RELEASE.jar:5.1.7.RELEASE]

	... 29 common frames omitted

I’m sorry but the route had the wrong scope.

Everything works now as expected. Thanks for your help

Hi simon, I am facing a similar problem and this old post is the closest thing to an answer,
I have a SPA, with a “main view” @router @uiscope , we are trying to create dialogs (these are not annotated with anything) so we are trying to create them from Beans, we made a configuration class, declared the bean methods but as soon as we add the fields to be injected in the mainView, we got the same error

I don’t fully understand can you please share a code example?

Sure…

@Route
@CssImport(
        themeFor = "vaadin-grid",
        value = "./themes/my-theme/styles.css"
)
@UIScope
public class MainView extends Div implements BeforeEnterObserver {

    private final MainViewService mainViewController; // this is with @Service @UIScope
    private final ImportFileService importFileController; // this too @Service @UIScope
    private EditEmpleadoConvenioForm editEpleadoConvDialog; //but this one has no annotations

So we created a @Config class to provide the beans


@Configuration
public class FormConfig {
    @Bean
    public EditEmpleadoConvenioForm getEditEmpleadoConvenioForm(EmpleadoService empleadoService, AnotherService anotherService) {
        return new EditEmpleadoConvenioForm("a title...", empleadoService,  adicionalesSelectorViewService);
    }

EmpleadoService and AnotherService are also annotated with @Service and @UIScope

I would not make UI components as Spring Beans. I either pass dependencies in the constructor or use something like this

but if those UI Components (Dialogs/forms), use @services as constructor parameters? and have dynamic parameters like “title”?


public class MyDialog extends Dialog {
       private final OneService one; //these 2 are @Service and @UIScope annotated
       private final AnotherService another; //these 2 are @Service annotated
     
       public MyDialog(String someTitle, OneService one, Another...) { ...}

}

Doesn’t matter. I usually inject them in the view.

would you mind giving an example? how to inject in something that is not managed by spring nor vaadin

Just call the constructor and pass all you need