membersound
membersound

Reputation: 86905

Initialise CDI injected components in constructor or post-method?

I'm using CDI in Vaadin context, but that should not matter for my question: Is it in general better to inject objects inside the constructor, or directly as a member variable? Especially if these objects have to be further configured for the component to work.

The following shows two different CDI possibilities:

@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);
    }
}

Is there a best practice? Why should one prefer the one option over the other? Or is it just a matter of personal choice?

Upvotes: 5

Views: 3731

Answers (2)

Petr Mensik
Petr Mensik

Reputation: 27536

Always use @PostConstruct when you work with injected resources(CDI and EJB beans for instance) because only then you can be sure that they really have been already injected into the bean (this is provided by the container). So that's the reason why you shouldn't rely on constructor when it comes to injected resources (they might get injected but you can't be sure).

However, constructor initialization can still be useful if you deal with non-injected resources, so you can call some methods or init variables, it's more matter of taste in this case. But you can never make mistake by using @PostConstruct all the time.

Upvotes: 4

Nikos Paraskevopoulos
Nikos Paraskevopoulos

Reputation: 40318

The constructor is ONLY for object construction stuff; i.e. NEVER CALL BUSINESS LOGIC FROM THE CONSTRUCTOR. Allways use @PostConstruct for business initialization logic. See my answer to this for a more detailed explanation.

In short the constructor may be called by the system in "unexpected" ways.

Additionally, in @PostConstruct you are guaranteed to have all dependencies (event fields) injected.

Upvotes: 6

Related Questions