Currently I try to create a sample implementation utilizing Spring Boot and Vaadin. I tried to initialize the vaadin navigator in a spring managed bean, but therefore I need access to the UI object.
I implemented the MVP pattern which needs a lot of classes and interfaces but the problem boils down to the following sample code:
@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
}
}
I've already read that the UI instance is kept in a ThreadLocal variable. I could verify that by debugging. I don't understand why the wired bean MainPresenter is in a different thread. It also shouldn't be a matter of scopes.
So far the application runs fine until I try to access the UI instance in the Presenter.
The VAADIN wiki did not help and I couldn't find a helpful answer in this forum.
After several hours I can answer this myself.
The solution to this problem is keeping the order of initialization in mind: When the @PostConstruct of MainPresenterImpl is called there is no UI yet and the UI is not yet registered in the ThreadLocal instance. I fixed the problem like this:
@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
}
}