UI.getCurrent在Spring Managed Bean中返回Null

时间:2016-05-20 09:39:31

标签: spring spring-boot vaadin vaadin4spring

目前我尝试使用Spring Boot和Vaadin创建一个示例实现。我试图在spring托管bean中初始化vaadin导航器,但因此我需要访问UI对象。

我实现了需要大量类和接口的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变量中。我可以通过调试来验证。我不明白为什么有线bean MainPresenter 在不同的线程中。它也不应该是范围问题。

到目前为止,应用程序运行正常,直到我尝试访问Presenter中的UI实例。

VAADIN wiki没有帮助,我在这个论坛找不到有用的答案。

1 个答案:

答案 0 :(得分:2)

几个小时后,我可以自己回答。

此问题的解决方案是牢记初始化的顺序:当

> MainPresenterImpl @PostConstruct 时>被称为还没有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
    }
}