Can @ManagedBean and @XxxScope be placed in a base class?

萝らか妹 提交于 2019-12-10 17:28:28

问题


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.

  1. 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.
  2. The injections in parent bean, like serviceManagerController are not performed unless I declare the <managed-property> in the faces-config.xml child bean declaration.
  3. The @PostConstruct method is not executed in the parent child, just the @PostConstruct child. Because of that I have to call super.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


回答1:


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. The BaseBean class must be abstract and not have any bean management annotations (so that neither you nor JSF can "accidentally" instantiate it). Put those bean management on ChildBean instead. Your faces-config.xml "fix" does basically exactly that.

public abstract class BaseBean implements Serializable {

    @ManagedProperty("#{serviceManagerController}")
    protected ServiceManagerController serviceManagerController;

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

    // ...
}
@ManagedBean("myBean")
@SessionScoped
public class ChildBean extends BaseBean {
    // ...
}

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:

  • Can @ManagedPropery and @PostConstruct be placed in a base class?


来源:https://stackoverflow.com/questions/30820457/can-managedbean-and-xxxscope-be-placed-in-a-base-class

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!