recommended Spring usage pattern for UI components


I am wondering how and if people wire up Spring dependencies to UI components. For example, a ComboBox needs to load items from a database. Should we make that combobox a specific class with UIScope, inject services into it and let it be responsible itself for loading the data ? Or should we rather let the composing View handle the dataloading of all the components it uses and only inject Spring services or repositories there?

I prefer the second approach, but also have seen the first one - it depends on the complexity of loading data and components involved. I would also recommend to use prototype as scope - UI scope is to broad for components like comboxes you probably use multiple times per page

I wonder if there is an overhead when such ‘complex’ combobox with Spring components injected is serialized to the client? Should Autowired components be marked as transient in order for them not to get serialized along? Or is Vaadin intelligent enough not to do this?

Vaadin doesn’t send anything like this to the client

I usually don’t use DI in components but get the Bean from the Application context. That way the components don’t need to be Spring Beans

Interesting idea with ApplicationContextAware :face_with_monocle: Did you also tried that with beans with a scope != singleton? Like UI scope? Would it also be possible to get the “correct” instance from it? Currently I’m using the Instantiator interface from Vaadin which is delegating the calls to the spring context

Yes. Everything works see expected

I use that approach in all Vaadin projects.

@adaptable-uakari It looks a bit hard to unit test, but other than that a valid approach. I guess most people don’t do unit tests for their Vaadin views anyway.

Unittesting is no issue you can use for example MockBean to create mocks. But unittests often don’t make sense in a UI

I personally avoid direct dependencies as much as possible and inject functionality into the component. That way my components only depend on functional interfaces and they are easily testable and re-usable. It does mean that it may lead to less readable code, but that’s a small tradeoff in my opinion.