当我尝试从另一个配置文件中注入参数时,我没有找到类型[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) {
我得到了#34;无法自动装配。限定符bean必须是'组件'类型"错误。我对Spring感到新鲜,我不确定我做错了什么,不应该使用VerticalLayout模板(HorizontalLayout navigationBar)参数将我的HorizontalLayout navigationBar方法与Spring匹配?
答案 0 :(得分:1)
您收到的错误消息告诉您,限定符bean(这是HorizontalLayout
注释为@Qualifier("navigationBar")
)需要是一个Spring @Component,即HorizontalLayout
需要用@Component
注释,这显然是不可能的。
你的方法遇到的另一个问题是Spring bean默认是单例。因此,您最终会在应用程序中使用navigationBar
布局的一个实例。这当然是不够的,因为您需要为为用户创建的每个新UI对象都有一个新实例。 navigationBar
Spring bean需要prototype scope,以便每个注入事件的应用程序上下文创建一个新实例。
除此之外,我强烈建议您不要使用单独的Vaadin UI组件进行自动装配。 Spring依赖注入机制并不打算在这个级别上使用。您应该使用更粗粒度的组件作为Spring bean,例如整个Vaadin views或后端服务。构建单个UI组件(如导航栏,表单或视图)应该在没有依赖注入的情况下完成。使用DI是一种过度杀伤,因为您只需调用其构造函数即可为常用UI组件创建实例,例如导航栏,汉堡按钮或elenx徽标。 UI组件内部不需要自动装配,这使得Spring容器的使用在这种情况下完全是多余的。
编辑:在组件级别上模块化Vaadin代码的最佳方法是使用类CustomComponent作为新组件的基类。您将构建一个名为NavigationBar
的新的CustomComponent子类,然后您可以将其实例化并添加到布局中,就像任何其他Vaadin组件一样。