【问题标题】:Autowiring services in Vaadin view and components not workingVaadin 视图中的自动装配服务和组件不起作用
【发布时间】:2019-12-19 12:19:21
【问题描述】:

各位程序员大家好!我对 Vaadin 比较陌生,所以请放过我。 我正在尝试将我的服务层自动连接到我的视图中,如下所示:

@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;

并且 customerService 依赖注入可以正常工作,但是当我尝试在组件中使用它时,它返回 null:

@Route
public class CustomerForm extends FormLayout {

    @Autowired
    private CustomerService customerService;

我尝试使用 @Component 和 @SpringComponent 注释类,但依赖注入不起作用,我认为问题不在于该类不是 bean,因为 MainView 类也不是豆子。

我的愿望是我创建的自定义子组件可以访问服务层。

提前感谢您的帮助!

【问题讨论】:

  • 您是使用new CustomerForm() 自己创建customerForm,还是实际的Route?如果是前者,注射就不行了。如果是后者,您是否尝试在构造函数中访问注入的服务?因为字段注入属性是在 构造函数完成后注入的 - 在这种情况下,您应该使用构造函数注入(将服务添加为构造函数的参数,并删除字段上的自动装配注释)
  • @KasparScherrer 我删除了 Route 注释并尝试了您的建议:public CustomerForm(MainView mainView, CustomerService customerService) { this.mainView = mainView; this.customerService = customerService; 但它仍然为空。
  • @AlexVulchev,您可能会从这篇解释 Spring 和 Vaadin 的依赖注入和控制反转的文章(或视频)中受益:vaadin.com/blog/…Cheers!

标签: java spring dependency-injection vaadin


【解决方案1】:

当您使用 new 关键字自己创建实例时,注入不起作用。

如果该类使用@Route 注释,则在导航到该路由时,Vaadin 框架将注入依赖项。

在您的情况下,如果您不导航到它,则必须将其设为 Spring bean。添加@Component@SpringComponent(第一个别名),然后将其自动连接到您的MainView,或自动连接ApplicationContext 并从那里获取。

同时拥有@Route@Component 很好,这样它就可以自动连接,也可以导航到。

如果您添加 @Component 注释,请记住选择适当的范围,@UIScope 以在导航时重复使用相同的实例,或 Scope.PROTOTYPE 始终创建一个新实例。

【讨论】:

    【解决方案2】:

    在 Vaadin UI 中,您只能在路由端点(具有 @Route 注释的视图)中注入,并且仅当通过导航到注释中指定的路由打开该视图时。 (因为只有这样该视图的实例化才会“自动”完成)。

    根据经验:每当您使用 new 关键字自己实例化某些东西时,注入/自动装配都不起作用。

    我对您的情况的了解是:
    你有一个MainView,你想在其中添加一个CustomerForm

    以下是实现该目标的方法:
    CustomerService注入MainView,并将CustomerService实例传递给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){
            ...
        }
    }
    

    另一种方法是把CustomerForm变成@Component(记得在spring配置类中正确扫描),将服务注入其中,然后将整个表单注入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
            ...
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2023-03-21
      • 1970-01-01
      • 2017-10-16
      • 2015-01-24
      • 1970-01-01
      • 1970-01-01
      • 2014-09-01
      • 2017-01-19
      • 1970-01-01
      相关资源
      最近更新 更多