没有为依赖项vaadin找到符合条件的类型的bean



当我尝试从另一个配置文件中注入参数时,没有发现类型为[com.vadin.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) {

我得到了"无法自动连接。限定符bean必须为"Component"类型"错误。我刚接触过Spring,我不确定我做错了什么,Spring不应该将我的HorizontalLayout导航栏方法与VerticalLayout模板的参数(HorizontalLayout导航栏)匹配吗?

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

您的方法存在的另一个问题是,Springbean默认情况下是singleton。因此,您的应用程序中只会出现navigationBar布局的一个实例。这当然是不够的,因为为用户创建的每个新UI对象都需要一个新实例。navigationBarSpringbean需要具有原型作用域,以便应用程序上下文在每个注入事件上创建一个新实例。

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

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

最新更新