Autowiring services in Vaadin view and components not working

百般思念 提交于 2020-01-15 10:26:51

问题


Hello fellow programmers! I am relatively new to Vaadin so spare me please. I am trying to autowire my service layer into my view as follows:

@Route("")
@PWA(name = "First time bruh", shortName = "Project Base")
public class MainView extends VerticalLayout {

    private TextField filterText = new TextField();
    private Grid<Customer> grid = new Grid<>(Customer.class);
    private CustomerForm customerForm = new CustomerForm(this);

    @Autowired
    private CustomerService customerService;

and the customerService dependency injections works properly, however when i try to use it in a component it returns null:

@Route
public class CustomerForm extends FormLayout {

    @Autowired
    private CustomerService customerService;

I've tried annotating the class with @Component and @SpringComponent but the dependency injection does not work and i think that the problem does not come from the fact that the class is not a bean, because MainView Class is also not a bean.

My wish is the custom sub components that i create to have access to the service layer.

Thanks in advance for your help!


回答1:


In Vaadin UI, you can inject only in route endpoints (views that have the @Route annotation), and only if that view is opened by navigating to the route specified in the annotation. (Because only then then instantiation of that view is done "automatically").

As a rule of thumb: Whenever you instantiate something yourself using the new keyword, injection/autowiring does not work.

What I understand of your situation is:
You have a MainView, within that you want to add a CustomerForm.

Here is how to achieve that:
Inject the CustomerService into the MainView, and pass the CustomerService instance into the constructor of CustomerForm

@Route
public class MainView extends VerticalLayout {
    public MainView(CustomerService customerService) { // customerService will be injected
        CustomerForm customerForm = new CustomerForm(customerService);
        add(customerForm);
    }
}

public class CustomerForm extends FormLayout {
    public CustomerForm (CustomerService customerService){
        ...
    }
}

Another approach would be to make the CustomerForm a@Component (do remember to scan it properly in the spring configuration class), inject the service into it, and then inject the whole form into the MainView:

@Route
public class MainView extends VerticalLayout {
    public MainView(CustomerForm customerForm) {  // customerForm will be injected
        add(customerForm);
    }
}

@Component
public class CustomerForm extends FormLayout {
    public CustomerForm (CustomerService customerService){ // customerService will be injected
        ...
    }
}



回答2:


Injection doesn't work when you create the instances yourself, using the new keyword.

If the class is annotated with @Route, dependencies will be injected by the Vaadin framework when navigating to that route.

In your case, if you're not navigating to it, you will have to make it a Spring bean. Add @Component or @SpringComponent (alias for the first), and either autowire it in your MainView, or autowire the ApplicationContext and get it from there.

It's fine to have both @Route and @Component, so that it can be autowired, but also navigated to.

Remember to choose an appropriate scope if you add the @Component annotation, either @UIScope to reuse the same instance while navigating around, or Scope.PROTOTYPE to always create a new one.



来源:https://stackoverflow.com/questions/59409682/autowiring-services-in-vaadin-view-and-components-not-working

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!