Can @ManagedPropery and @PostConstruct be placed in a base class?
Asked Answered
O

1

5

I'm using a hierarchy of classes and what I would optimally try to do is have @ManagedBean's that inherit a class that have @ManagedProperty members and @PostConstruct methods.

Specifically, will this work? :

public class A {

    @ManagedProperty
    private C c;

    @PostConstruct
    public void init() {
        // Do some initialization stuff
    }

    public C getC() {
        return c;
    }

    public void setC(C c) {
        this.c = c;
    }
}

@ManagedBean
@SessionScoped
public class B extends A {
    // Content...
}

Thanks in Advance!

Ornithology answered 29/10, 2012 at 8:0 Comment(1)
I have a similar set-up that uses CDI and EJB injection in the superclass and the injected objects are used by subclasses. My superclass is @SessionScoped and the subclasses are @ViewScoped. I have @PostConstruct in the superclass and in the subclasses as well. All is working fine. However, I don't know how @ManagedProperty injection will behave in this set-up.Knepper
I
13

The @ManagedProperty is inherited and will just work that way. The @PostConstruct will also be inherited, provided that the subclass itself doesn't have a @PostConstruct method. There can namely be only one. So if the subclass itself has a @PostConstruct, then the superclass' one won't be invoked.

So if you override the @PostConstruct in the subclass, then you'd need to explicitly invoke the superclass' one.

public class SuperBean {

    @PostConstruct
    public void init() {
        // ...
    }

}
@ManagedBean
public class SubBean extends SuperBean {

    @PostConstruct
    public void init() {
        super.init();
        // ...
    }

}

Alternatively, provide an abstract method which the subclass must implement (without @PostConstruct!).

public class SuperBean {

    @PostConstruct
    public void superInit() {
        // ...
        init();
    }

    public abstract void init();

}
@ManagedBean
public class SubBean extends SuperBean {

    @Override
    public void init() {
        // ...
    }

}
Inception answered 29/10, 2012 at 11:54 Comment(5)
Another option would be to give the @PostConstruct annotated methods different names in the superclass and the subclass. Then you don't need to call the superclass method explicitly.Knepper
@Matt: Are you talking about omitting the super keyword, or the whole super.init() call?Inception
The whole super.init() call. It works im my scenario (See my comment to the question).Knepper
@Matt: OP is managing beans by JSF, not by CDI. That might be the difference. JSF doesn't invoke multiple @PostConstruct methods, only the one "closest" in the class hierarchy will be invoked. I must however admit that I'm at this point not sure if this is by specification or not.Inception
@Inception Thank you. How the injection mechanism works is still a mystery to me but i'm glad it works the way I need it to.Ornithology

© 2022 - 2024 — McMap. All rights reserved.