自实例化的HorizontalLayout中的自动装配服务



是否有一种通用的方式将自动连接的服务传递给自实例化的视图?假设我们有一个由Spring (@Autowired works)管理的VerticalLayout和一个HorizontalLayout按钮。我们需要创建多个HorizontalLayout实例,并且按钮执行服务的一些动作(@Autowired不起作用,service为null)。解决这个问题的最佳实践是什么?将服务作为参数传递给HorizontalLayout的构造函数是一种选择,但也许还有更好的方法。

@Service
public class SomeService {
    public void someMethod(){
    // do something
    }
}
@SpringView(name = "SomeView")
@ViewScope
public class SomeView extends VerticalLayout {
    @Autowired
    private SomeService service;
    public SomeView(){
        addComponent(new Subview());
        addComponent(new Subview());
    }
}
public class SubView extends HorizontalLayout {
    @Autowired
    private SomeService service;
    public SubView(){
        Button btn = new Button("Test");
        btn.addClickListener(e->service.someMethod());
        addComponent(btn);
    }
}
编辑:我添加了一个代码示例。SubView的对象为service获取null。解决方案是将服务传递给构造函数。但我想知道,是否有更好的解决方案。

你指的是vadin View还是普通的Component?View必须实现View接口(com.vaadin.navigator.View),因此你可以使用构造函数自动连接Service和enter()方法来创建ui:

@SpringView(name = "SomeView")
@ViewScope
public class SomeView extends VerticalLayout implements View {
    private SomeService service;
    @Autowired
    public SomeView(SomeService service){
        this.service = service;
    }
    @Override 
    public void enter(ViewChangeListener.ViewChangeEvent event) {
        //service is available here
        removeAllComponents();
        addComponent(new Subview());
        addComponent(new Subview());
    }
}

它的工作方式是,Spring将实例化SomeView,并在此过程中通过构造函数自动调用你的服务。然后,当视图被调用时,它将使用enter()方法来绘制其组件。

如果它只是一个常规组件(我认为这是你的情况),那么在方法中使用@PostConstruct注释而不是enter()。例如:

@Autowired
public SomeView(SomeService service){
    this.service = service;
}
@PostConstruct
public void init() {
    //service is available here
    addComponent(...);
}

我没有测试过这个注释,但它在Vaadin中有广泛的文档记录。请让我知道它是否适合你。

最新更新