问题
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