2016-05-20 2 views
3

Actuellement, j'essaie de créer un exemple d'implémentation en utilisant Spring Boot et Vaadin. J'ai essayé d'initialiser le navigateur vaadin dans un bean géré par le printemps, mais j'ai donc besoin d'accéder à l'objet IU.UI.getCurrent renvoie Null dans Spring Bean géré

I mis en œuvre le modèle MVP qui a besoin d'un grand nombre de classes et d'interfaces, mais le problème se résume à l'exemple de code suivant:

@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 
    } 
} 

Je l'ai déjà lu que l'instance UI est maintenue dans une variable ThreadLocal . Je pourrais vérifier cela en déboguant. Je ne comprends pas pourquoi le haricot filaire MainPresenter est dans un fil différent. Cela ne devrait pas non plus être une question de portée. Jusqu'à présent, l'application fonctionne correctement jusqu'à ce que j'essaie d'accéder à l'instance de l'interface utilisateur dans le Presenter.

Le wiki VAADIN n'a pas aidé et je n'ai pas trouvé de réponse utile dans ce forum.

+0

Avez-vous parcouru cette liste? http://stackoverflow.com/search?q=vaadin+spring+autowire+null –

+0

La plupart de ces résultats de recherche que j'ai vus plus tôt. 90% se plaignent des champs autowired null en raison d'une mauvaise configuration ou de l'utilisation de @Autowire dans des objets qui n'ont pas été instanciés au printemps. Les 10% restants ne correspondent pas non plus à mon problème. –

Répondre

2

Après plusieurs heures, je peux répondre moi-même.

La solution à ce problème est de garder l'ordre d'initialisation à l'esprit: Lorsque le @PostConstruct de MainPresenterImpl est appelé il n'y a pas encore l'interface utilisateur et l'interface utilisateur est pas encore inscrite dans l'instance ThreadLocal . J'ai corrigé le problème comme ceci:

@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 
    } 
}