没有找到依赖类型的合格 bean,vaadin

No qualifying bean of type found for dependency, vaadin

当我尝试从另一个配置文件中注入参数时,我没有找到 [com.vaadin.ui.HorizontalLayout] 类型的合格 bean 以查找依赖错误: 主要配置:

@Configuration
@EnableVaadin
@Import(NavigationBar.class)
@ComponentScan("net.elenx")
public class SpringConfig {

    //Create whole view of MainView
    @Bean
    VerticalLayout template(@Qualifier("navigationBar") HorizontalLayout navigationBar) {
        VerticalLayout template = new VerticalLayout();
        //NavigationBar navigationBar = new NavigationBar();
        Sidebar sidebar = new Sidebar();
        template.setMargin(false);
        template.setSpacing(false);
        template.setHeight("100%");
        template.addComponent(navigationBar);
        template.addComponent(sidebar.getSidebar());
        template.setExpandRatio(sidebar.getSidebar(), 1.0f);
        return template;
    }
}

第二配置:

@Configuration
@EnableVaadin
public class NavigationBar {

    @Bean
    HorizontalLayout navigationBar(Button hamburgerButton, Label elenxLogo) {
        System.out.println("Hello from NavigationBar bean!");
        HorizontalLayout navbar = new HorizontalLayout();
        navbar.setWidth("100%");
        navbar.setMargin(true);
        navbar.setHeight(50, Sizeable.Unit.PIXELS);
        navbar.addComponent(hamburgerButton);
        navbar.addComponent(elenxLogo);
        navbar.addStyleName("navigation-bar");
        return navbar;
    }

    @Bean
    Button hamburgerButton() {
        Button hamburgerButton = new Button();
        hamburgerButton.addStyleName("hamburger-button");
        hamburgerButton.setIcon(VaadinIcons.MENU);
        return hamburgerButton;
    }

    @Bean
    Label elenxLogo() {
        Label logo = new Label("ElenX");
        logo.addStyleName("elenx-logo");
        logo.setWidthUndefined();
        logo.setEnabled(false);
        return logo;
    }
}

那么这个注入的正确实现方式是什么呢?我想为每个元素都添加 Beans,然后注入它们来构建整个布局。当我尝试更改此行时:

 @Bean
 VerticalLayout template(HorizontalLayout navigationBar) {

为此:

 @Bean
 VerticalLayout template(@Qualifier("navigationBar") HorizontalLayout navigationBar) {

我收到 "Could not autowire. Qualifier bean must of 'Component' type" 错误。我刚接触 Spring,我不确定我做错了什么,不应该 Spring 将我的 Horizo​​ntalLayout navigationBar 方法与 VerticalLayout 模板 (Horizo​​ntalLayout navigationBar) 的参数相匹配吗?

您收到的错误消息告诉您限定符 bean(这是用 @Qualifier("navigationBar") 注释的 HorizontalLayout)需要是一个 Spring @Component,即 HorizontalLayout 需要注解 @Component 这显然是不可能的。

您的方法的另一个问题是 Spring bean 默认是单例。因此,您最终会在应用程序中得到 navigationBar 布局的一个实例。这当然是不够的,因为您需要为为用户创建的每个新 UI 对象创建一个新实例。 navigationBar Spring bean 需要 prototype scope 以便应用程序上下文在每次注入事件时创建一个新实例。

除此之外,我强烈建议您不要使用单独的 Vaadin UI 组件进行自动装配。 Spring 依赖注入机制不适用于此级别。您应该使用更粗粒度的组件作为 Spring beans,例如整个 Vaadin views 或后端服务。构建单个 UI 组件(如导航栏、表单或视图)应该在没有依赖注入的情况下完成。使用 DI 有点矫枉过正,因为您可以简单地通过调用它们的构造函数来为常见的 UI 组件(例如导航栏、汉堡包按钮或 elenx 徽标)创建实例。 UI 组件内部不需要自动装配,这使得 Spring 容器的使用在这种情况下完全多余。

编辑: 在组件级别模块化 Vaadin 代码的最佳方法是使用 class CustomComponent 作为基础 class 用于新的组件。您将构建一个名为 NavigationBar 的 CustomComponent 的新子 class,然后您可以像任何其他 Vaadin 组件一样实例化并添加到布局中。