Vaadin component as Spring bean

Question:

When can a Vaadin bean be in a spring container ( @SpringComponent annotation)?

Clarification of the issue:

I ask this question because I know that Vaadin View can be spring bean after using @SpringView . But if I comment on the Button component with @SpringComponent , it will be created only once. Could this be a 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 to use them in different places - for example, in the Tab component (in Vaadin TabSheet). So I have an idea - tabContent could also be a 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 enter all the necessary beans:

 @SpringComponent public class SomeTabContent extends VerticalLayout { @Autowired private CustomerRepository customerRepository; @Autowired private UserRepository UserRepository; } 

Is this the right architecture?

Note. I know that Vaadin has CDI and Data Binding features, but I don't want to use them. I also know that I could manually create the spring application context anywhere, but I think this is not correct.

+4
source share
2 answers

After increasing my knowledge, I have a hypothesis.

Is it possible to use the Vaadin component as a spring bean? Why not. I tried this and it works. But...

But it also causes multiple listeners to appeal - since I have a Button object with a class.

Spring creates an instance of the component on its own and places it somewhere. Therefore, I cannot do anything in the component constructor. In addition, such a component should be cleaned and initialized before any use. Does this sound weird? I think yes. And that can cause a lot of problems - especially in a multi-threaded environment.

Therefore, I do not recommend creating a Bean for any Vaadin components (e.g. Tab, Buttons ...). Because they need to change their condition depending on the place of use.

But how to make all Spring beans available in an object that is not supported by the Spring container? This is not a new question, and there are at least two solutions:

  • Annotate such a class with @Configurable and enable any weaving (compilation or runtime). This is explained, for example, here or here .

  • Use the AutowireCapableBeanFactory and autowiredBeanProperty() methods AutowireCapableBeanFactory . A little explanation can be found here , as well as fooobar.com/questions/61969 / ....

+1
source

If you use only @Component (or @SpringComponent), the class will be created once for the application, yes, you will get problems with several sessions that will share the resulting objects when you do not want it. So you add @UIScope. This will ensure that one instance of this class is retrieved per session. You can store session data in a class (as if you were using Spring @Session, but this requires using Spring Dispatcher).

In the @UIScope class, you can use @Autowired and @PostConstruct, etc. I use it to continue windows and layout, etc. You need com.vaadin: vaadin-spring: 1.0.0 on your class path. Additional Info About vaadin- spring

+2
source

All Articles