@UIScope annotation not respected for spring view?

不打扰是莪最后的温柔 提交于 2020-01-14 19:50:29

问题


I am facing an issue with the Vaadin spring annotation @UIScope, defined as follows:

@SpringComponent
@SpringView(name = AdminView.VIEW_NAME)
@UIScope
public class AdminView extends NavigatingView {
    ...
}

The view is created every time the navigation is opening the view. I would expect that it is created only once, on first time access.

However, if I replace @UIScope with @Scope(UIScopeImpl.VAADIN_UI_SCOPE_NAME) then it works as expected. Did I miss something?


回答1:


It's related to the order of the @SpringView and @UIScope annotations, as the tutorial and the older wiki page briefly suggest:

// Pay attention to the order of annotations

It's probably related to how and when the annotations are processed. I did not dig that deep into the Vaadin code, but as per the the @SpringView javadoc it puts the view into a view-scope by default. Furthermore, I don't think you require the @SpringComponent annotation because you're already using @SpringView to register it a spring component.

Annotation to be placed on View-classes that should be handled by the SpringViewProvider.

This annotation is also a stereotype annotation, so Spring will automatically detect the annotated classes. By default, this annotation also puts the view into the view scope. You can override this by using another scope annotation, such as the UI scope, on your view class. However, the singleton scope will not work!

In the sample below, you'll find 2 views, the first one with the annotations in the correct order, and the second one with them swapped:

@SpringUI
@SpringViewDisplay
public class MyVaadinUI extends UI implements ViewDisplay {

    /* UI */

    private Panel springViewDisplay;

    @Override
    protected void init(VaadinRequest request) {
        VerticalLayout mainLayout = new VerticalLayout();
        HorizontalLayout buttonLayout = new HorizontalLayout();
        springViewDisplay = new Panel();

        buttonLayout.addComponent(new Button("1", event -> getNavigator().navigateTo(FirstView.VIEW_NAME)));
        buttonLayout.addComponent(new Button("2", event -> getNavigator().navigateTo(SecondView.VIEW_NAME)));
        mainLayout.addComponents(buttonLayout, springViewDisplay);
        setContent(mainLayout);

    }

    @Override
    public void showView(View view) {
        springViewDisplay.setContent((Component) view);
    }


    /* VIEWS */

    @UIScope
    @SpringView(name = FirstView.VIEW_NAME)
    public static class FirstView extends HorizontalLayout implements View {

        public static final String VIEW_NAME = "";

        @PostConstruct
        private void init() {
            System.out.println("Created first view");
            addComponent(new Label("First view - " + LocalDateTime.now()));
        }

        @Override
        public void enter(ViewChangeListener.ViewChangeEvent event) {
            // no-op
        }
    }

    @SpringView(name = SecondView.VIEW_NAME)
    @UIScope
    public static class SecondView extends HorizontalLayout implements View {

        public static final String VIEW_NAME = "secondView";

        @PostConstruct
        private void init() {
            System.out.println("Created second view");
            addComponent(new Label("Second view - " + LocalDateTime.now()));
        }

        @Override
        public void enter(ViewChangeListener.ViewChangeEvent event) {
            // no-op
        }
    }
}

As you'll notice in the animation below, when navigating to the second view a new instance is always created, while navigating to the first one will reuse the initial instance:



来源:https://stackoverflow.com/questions/44903429/uiscope-annotation-not-respected-for-spring-view

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!