Spring autowiring Views and Vaadin Navigation

Hi,

I have my Vaadin Views annotated as @SpringComponent, like this:


@SpringComponent
@Route("SelectUsecase")
public class SelectUsecaseView extends VerticalLayout {

In a listenerClass I have an Autowiring like this:

	@Autowired
	protected SelectUsecaseView selectUsecaseView;

	@Override
	public void notify(DelegateExecution execution) throws Exception {
	...
	selectUsecaseView.setMyModel(selectModel);
	UI.getCurrent().navigate(SelectUsecaseView.class);

The Problem is that the Contructor of SelectUsecaseView is called twice. The one instance is created by Spring and one is created when the code ‘UI.getCurrent().navigate(SelectUsecaseView.class)’ is called the first time. The instance created by Spring will receive the ‘selectModel’ and the other instance is actually being displayed (and part of the Vaadin component tree). Is there a way to let Vaadin use the instances created by Spring?

regards,
Arno

It seems this has something to do with the scope of the spring beans. When I annotate the Views with @VaasinSession all will work ok.
But If i used the UIScope annotation, then it will create 2 instanes of the SelectUsecaseView. While debugging I saw that there are 2 instances of UI, also there is only 1 browser window. The first UI instane is serving the LoginForm, the seond actualy the SelectUsecaseView. Anybody knows why there are 2 UI instances?

If you annotate the route with @SpringComponent, you have to set the scope because by default it’s a singleton.
The scope should be prototype or uiScope. @VaadinSessionScope will be a problem since you cannot use the same component in two UI.

If you add @UIScope to @Route the annotation will be ignored if you don’t add @SpringComponent.

I tried to reproduce the problem but the component seems created only once. But it’s added It will be re-created if you refresh the page.

Here an example:

@SpringComponent
@UIScope
@Route("page3")
public class Page3View extends VerticalLayout {

    public Page3View(@Autowired Page4View page4View) {
        System.out.println("building Page3View()");
        // Use TextField for standard text input
        TextField textField = new TextField("Page3");

        Button button = new Button("navigate page 4", e -> {
            getUI().ifPresent(ui -> ui.navigate(Page4View.class));
        });

        add( textField, button, page4View);
    }
}
@SpringComponent
@UIScope
@Route("page4")
public class Page4View extends VerticalLayout {

    public Page4View() {
        System.out.println("building Page4View()");
        // Use TextField for standard text input
        TextField textField = new TextField("Page4");

        Button button = new Button("navigate page 3", e -> {
            getUI().ifPresent(ui -> ui.navigate(Page3View.class));
        });

        add( textField, button);
    }
}

Unfortunately my use case shows a error, the autowired page4 will be removed from the Page3 once you navigate to Page4. (because you can’t add the same component twice).

thanks for your follow-up. I actually figured it out now. The 2 instances actually were caused by the following problem. The sucessful login through spring boot forward to an URL and the FormLogin::addSucessfulLoginListener, which I implemented also was causing another request for a view. The 2 requests for view caused 2 the 2 instances. Removing the LoginListener did the trick. I found this in the Backery-app provided as example by Vaadin.

That’s great you find out.