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

时间:2013-09-26 10:09:21

标签: 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);
    }
}

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

2 个答案:

答案 0 :(得分:6)

构造函数 ONLY 用于构造对象;即永远不会从构造函数中调用商业逻辑。 Allways使用@PostConstruct进行业务初始化逻辑。有关更详细的说明,请参阅my answer to this

简而言之,系统可能会以“意想不到的”方式调用构造函数。

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

答案 1 :(得分:4)

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

但是,如果处理非注入资源,构造函数初始化仍然有用,所以你可以调用一些方法或初始化变量,在这种情况下,更多的是品味。但是你永远不能错误地使用@PostConstruct