0

当我尝试从像这样的另一个配置文件注入参数时,我没有找到类型为 [com.vaadin.ui.Horizo​​ntalLayout] 的合格 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;
    }
}

那么实现这种注入的正确方法是什么?我希望每个元素都有 Bean,然后注入它们来构建整个布局。当我尝试更改此行时:

 @Bean
 VerticalLayout template(HorizontalLayout navigationBar) {

对此:

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

我收到“无法自动装配。限定符 bean 必须为‘组件’类型”错误。我对 Spring 很陌生,我不确定我做错了什么,Spring 不应该将我的 Horizo​​ntalLayout navigationBar 方法与 VerticalLayout 模板(Horizo​​ntalLayout navigationBar)的参数匹配吗?

4

1 回答 1

1

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

您的方法遇到的另一个问题是 Spring bean 默认是单例的。所以你最终会navigationBar在你的应用程序中得到一个布局实例。这当然是不够的,因为您需要为每个为用户创建的新 UI 对象创建一个新实例。navigationBarSpring bean 需要具有原型范围,以便应用程序上下文在每个注入事件上创建一个新实例。

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

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

于 2015-11-12T07:16:03.940 回答