2016-05-20 60 views
3

當前我嘗試使用Spring Boot和Vaadin創建示例實現。我嘗試在spring管理bean中初始化vaadin導航器,但因此我需要訪問UI對象。UI.getCurrent在Spring Managed Bean中返回空值

我實現它需要大量的類和接口的MVP模式,但問題歸結爲下面的示例代碼:

@SpringUI 
public class MyVaadinUI extends UI 
{ 
    @Autowired 
    private MainPresenter mainPresenter; 

    protected void init(VaadinRequest request) 
    { 
     setContent(mainPresenter.getView()); 
    } 
} 

@UIScope 
@SpringComponent 
public class MainPresenterImpl implements MainPresenter 
{ 
    @Autowired 
    public MainPresenterImpl(MainModel model, MainView view) 
    { 
     super(model, view); 
    } 

    @PostConstruct 
    public void init() 
    { 
     UI ui = UI.getCurrent(); 
     Assert.isNull(ui); // ui is always null 
    } 
} 

我已經讀過了UI實例保存在一個ThreadLocal變量。我可以通過調試來驗證。我不明白爲什麼有線豆在一個不同的線程中,爲什麼有線豆MainPresenter。這也不應該是一個範圍問題。

到目前爲止,應用程序運行正常,直到我嘗試訪問Presenter中的UI實例。

VAADIN wiki沒有幫助,我在這個論壇上找不到有用的答案。

+0

你有沒有經歷過這個列表? http://stackoverflow.com/search?q=vaadin+spring+autowire+null –

+0

我之前看到的大部分搜索結果。 90%的用戶抱怨由於錯誤配置而導致null的自動佈線字段或者在未由Spring實例化的對象中使用@Autowire。最後的10%也不符合我的問題。 –

回答

2

幾小時後,我可以自己回答。

到這個問題的辦法是保持初始化順序記:當@PostConstructMainPresenterImpl被稱爲沒有UI又和UI尚未在ThreadLocal實例註冊。我修正了這樣的問題:

@SpringUI 
public class MyVaadinUI extends UI 
{ 
    @Autowired 
    private MainPresenter mainPresenter; 

    protected void init(VaadinRequest request) 
    { 
     mainPresenter.initAfterBeanCreation() 
     setContent(mainPresenter.getView()); 
    } 
} 

@UIScope 
@SpringComponent 
public class MainPresenterImpl implements MainPresenter 
{ 
    @Autowired 
    public MainPresenterImpl(MainModel model, MainView view) 
    { 
     super(model, view); 
    } 

    @PostConstruct 
    public void init() 
    { 
     UI ui = UI.getCurrent(); // ui is always null 
    } 

    public void initAfterBeanCreation() 
    { 
     UI ui = UI.getCurrent(); // now ui is not null 
    } 
}