I have two @ManagedBean
(javax.faces.bean.ManagedBean), parent and child. The parent managed bean is not abstract because we have to give liberty to the developer to use the parent if enough or inherit it with a child that holds specifically funcionality.
I have problems with the injections bean and the @PostConstruct
annotated method in the parent bean.
The following code is the only way I found it works.
@ManagedBean(name = "myBean")
@SessionScoped
public class BaseBean implements Serializable {
@ManagedProperty(value = "#{serviceManagerController}")
protected ServiceManagerController serviceManagerController;
@PostConstruct
public void init() {
//do things
}
}
And the child bean
public class ChildBean extends BaseBean {
@PostConstruct
public void init() {
super.init();
}
}
To override the "myBean" bean and force to the app to use the child bean when needed I have had to declare the child bean in faces-config.xml
<managed-bean>
<managed-bean-name>myBean</managed-bean-name>
<managed-bean-class>package.ChildBean</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
<managed-property>
<property-name>serviceManagerController</property-name>
<property-class>package.ServiceManagerController</property-class>
<value>#{serviceManagerController}</value>
</managed-property>
</managed-bean>
That is the only way all works and I don´t understand some things.
- If I don´t declare the child bean in
faces-config.xml
then the beans container always uses the parent bean implementation though@ManagedBean
is inherited. - The injections in parent bean, like
serviceManagerController
are not performed unless I declare the<managed-property>
in thefaces-config.xml
child bean declaration. - The
@PostConstruct
method is not executed in the parent child, just the@PostConstruct
child. Because of that I have to callsuper.init()
in an empty@PostConstruct
mehtod in the child bean
Why do I have to do this three steps to make injections and postConstruct in the parent work?
Of course, if in my app I don´t want to inherit BaseBean and want to use this bean in the facelets all work without problems.
Regards
The
BaseBean
is wrongly designed. Bean management annotations are not inherited. It does technically not make any sense to have multiple instances of different subclasses registered on the very same managed bean name/identifier. TheBaseBean
class must beabstract
and not have any bean management annotations (so that neither you nor JSF can "accidentally" instantiate it). Put those bean management onChildBean
instead. Yourfaces-config.xml
"fix" does basically exactly that.Managed property and post construct / pre destroy annotations are however inherited, provided that you didn't already override them in the subclass. So you don't need to redefine them.
See also: