2017-07-04 62 views
1

我面臨的一個問題與Vaadin彈簧註釋@UIScope,定義如下:@UIScope註釋不適用於春季視圖?

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

視圖創建導航打開視圖每次。我希望它在第一次訪問時只創建一次。

但是,如果我將@UIScope替換爲@Scope(UIScopeImpl.VAADIN_UI_SCOPE_NAME),那麼它將按預期工作。我錯過了什麼?

回答

3

它關係到@SpringView@UIScope標註的順序,爲tutorial與老wiki page簡要建議:

//注意標註的順序

這是可能與註釋的處理方式和時間有關。我沒有深入研究Vaadin代碼,但是根據@SpringView javadoc,默認情況下它將視圖視爲視圖範圍。此外,我不認爲你需要@SpringComponent註釋,因爲你已經使用@SpringView來註冊一個彈簧組件。

要放置在應該由SpringViewProvider處理的視圖類上的註釋。

這個註解也是一個構造型註釋,所以Spring會自動檢測帶註釋的類。 默認情況下,此註釋還將視圖放入視圖範圍。您可以通過在視圖類上使用其他範圍註釋(如UI範圍)來覆蓋此內容。但是,單身作用域不起作用!

在下面的例子,你會發現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-view-uiscope

+0

謝謝您詳細的解答。不過,這個順序很重要。 –

+0

@SteffenHarbich是的。但是同時,默認的Spring @ @ Scope註解是不可重複的,所以你不能將2個作用域添加到同一個bean中。然而,'@UIScope'和'@SpringView'在視圖上設置了一個範圍,所以**我想**其中一個必須以某種方式優先...正如我所說的,我沒有深入到源我也不能找到應用多個範圍的實例/樣本,所以這是一個瘋狂的猜測 – Morfic