问题
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