在构造函数或后期方法中初始化CDI注入的组件?

mem*_*und 5 java java-ee vaadin cdi

我在Vaadin上下文中使用CDI,但这对我的问题无关紧要:在构造函数中注入对象或者直接作为成员变量注入更好吗?特别是如果必须进一步配置这些对象以使组件工作.

以下显示了两种不同的CDI可能性:

@UIScoped
public class MyMenuBar extends CustomComponent {
    @Inject @New private Label label;
    @Inject @New private MenuBar menuBar;

    @PostConstruct
    private void init() {
        //set label text, define menu entries
        setCompositionRoot(menuBar);
    }
}

@UIScoped
public class MyMenuBar extends CustomComponent {
    private Label label;
    private MenuBar menuBar;

    @Inject
    public MyMenuBar(@New Label label, @New MenuBar menuBar) {
        //set label text, define menu entries
        setCompositionRoot(menuBar);
    }
}
Run Code Online (Sandbox Code Playgroud)

有最好的做法吗?为什么一个人更喜欢一个选项?或者这仅仅是个人选择的问题?

Nik*_*los 6

构造函数用于对象构造; 即永远不要从构造者那里打电话给商业逻辑.Allways @PostConstruct用于业务初始化逻辑.有关更详细的说明,请参阅我的答案.

简而言之,系统可以以"意外"的方式调用构造函数.

此外,@PostConstruct您可以保证注入所有依赖项(事件字段).


Pet*_*sik 4

当您使用注入的资源(例如 CDI 和 EJB bean)时始终使用@PostConstruct,因为只有这样您才能确定它们确实已经注入到 bean 中(这是由容器提供的)。这就是为什么在注入资源时不应该依赖构造函数的原因(它们可能会被注入,但你不能确定)。

但是,如果您处理非注入资源,构造函数初始化仍然很有用,因此您可以调用一些方法或初始化变量,在这种情况下,这更取决于品味。@PostConstruct但一直使用就永远不会出错。