Question:
When Vaadin component could be a bean in spring container (@SpringComponent
annotation)?
Question clarification:
I ask this question because I know that Vaadin View could be spring bean after using @SpringView
.
But if I annotate Button
component with @SpringComponent
it will be created only once. Can it make any problem?
Example:
I have a lot of JpaRepository bean:
public interface CustomerRepository extends JpaRepository<Customer, Long>
// ...
public interface UserRepository extends JpaRepository<User, Long> {
// ...
And I want use them in different places - for example in a Tab component (in Vaadin TabSheet). So I have an idea - the tabContent
can be also spring component:
@SpringView(name = "viewName")
public class SomeView extends VerticalLayout implements View {
@Autowired
private SomeTabContent tabContent;
//...
public void init() { // call every view enter()
removeAllComponents();
// Initialize whole view.
tabSheet.addTab(tabContent, /* ... */);
// ...
}
And then I can inject all needed beans:
@SpringComponent
public class SomeTabContent extends VerticalLayout {
@Autowired
private CustomerRepository customerRepository;
@Autowired
private UserRepository UserRepository;
}
Is it correct architecture?
Note: I know that Vaadin has CDI and Data Binding features, but I don't want use them. I also know that I could manually create Spring application context in any place - but I think this is not proper way.
If you use just @Component (or @SpringComponent) the class will be instantiated once for the application so, yes, you will get issues with multiple sessions sharing the resulting objects when you don't want them to. So you add @UIScope as well. That will ensure you get one instance of this class per session. You can store session data in the class (much as if you used Spring's @Session, but that requires you to use Spring's Dispatcher).
In a @UIScope class you can use @Autowired and @PostConstruct etc. I use it for extends of Windows and Layout etc. You need com.vaadin:vaadin-spring:1.0.0 on your classpath. Further info on vaadin-spring
After increasing my knowledge I have some hypothesis.
Can we use Vaadin component as Spring bean? Why not. I tried this and it works. But...
But it cause also multiple listeners invocation - as I have class-instated Button object.
Spring creates the instance of the component by itself and put it somewhere. So I can't do anything in component constructor. Moreover such component should be cleaned and initialized before any use. Does it sound weird? I think yes. And it might cause a lot of problems - especially in multithread environment.
So I don't recommend making a Bean of any Vaadin components (for example Tab, Buttons...). Because they need to change their state depending on place of use.
But how to make available all Spring beans in object which is not maintained by Spring container? This isn't new question and there are at least two solutions:
Annotate such class with @Configurable
and enable any weaving (compile or run time). This is explained for example here or here.
Directly use of AutowireCapableBeanFactory
and autowiredBeanProperty()
method. A little explanation can be find here and also on SO.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With