spring 视图不尊重@UIScope 注释?
@UIScope annotation not respected for spring view?
我遇到了 Vaadin spring 注释 @UIScope
的问题,定义如下:
@SpringComponent
@SpringView(name = AdminView.VIEW_NAME)
@UIScope
public class AdminView extends NavigatingView {
...
}
每次导航打开视图时都会创建视图。我希望它只在第一次访问时创建一次。
但是,如果我将 @UIScope
替换为 @Scope(UIScopeImpl.VAADIN_UI_SCOPE_NAME)
,那么它会按预期工作。我错过了什么吗?
它与 @SpringView
和 @UIScope
注释的顺序有关,如 tutorial and the older wiki page 简要地 建议:
// Pay attention to the order of annotations
这可能与注释的处理方式和时间有关。我没有深入研究 Vaadin 代码,但根据 @SpringView
javadoc,它默认将视图放入 view-scope。此外,我认为您不需要 @SpringComponent
注释,因为您已经在使用 @SpringView
将其注册为 spring 组件。
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!
在下面的示例中,您会发现 2 个视图,第一个视图的注释顺序正确,第二个视图调换了顺序:
@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
}
}
}
正如您将在下面的动画中注意到的那样,当导航到第二个视图时,总是会创建一个新实例,而导航到第一个视图将重用初始实例:
我遇到了 Vaadin spring 注释 @UIScope
的问题,定义如下:
@SpringComponent
@SpringView(name = AdminView.VIEW_NAME)
@UIScope
public class AdminView extends NavigatingView {
...
}
每次导航打开视图时都会创建视图。我希望它只在第一次访问时创建一次。
但是,如果我将 @UIScope
替换为 @Scope(UIScopeImpl.VAADIN_UI_SCOPE_NAME)
,那么它会按预期工作。我错过了什么吗?
它与 @SpringView
和 @UIScope
注释的顺序有关,如 tutorial and the older wiki page 简要地 建议:
// Pay attention to the order of annotations
这可能与注释的处理方式和时间有关。我没有深入研究 Vaadin 代码,但根据 @SpringView
javadoc,它默认将视图放入 view-scope。此外,我认为您不需要 @SpringComponent
注释,因为您已经在使用 @SpringView
将其注册为 spring 组件。
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!
在下面的示例中,您会发现 2 个视图,第一个视图的注释顺序正确,第二个视图调换了顺序:
@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
}
}
}
正如您将在下面的动画中注意到的那样,当导航到第二个视图时,总是会创建一个新实例,而导航到第一个视图将重用初始实例: