@ManagedBean 和@XxxScope 可以放在一个base class 中吗?

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

我有两个 @ManagedBean (javax.faces.bean.ManagedBean)、parent 和 child。 parent 托管 bean 不是抽象的,因为我们必须给予开发人员足够的自由来使用 parent 或使用具有特定功能的 child 继承它。

我对注入 bean 和 parent bean 中的 @PostConstruct 注释方法有问题。

以下代码是我发现它唯一有效的方法。

@ManagedBean(name = "myBean")
@SessionScoped
public class BaseBean implements Serializable {
    @ManagedProperty(value = "#{serviceManagerController}")
    protected ServiceManagerController serviceManagerController;

     @PostConstruct
     public void init() {
       //do things
     }
}

和 child bean

public class ChildBean extends BaseBean {
    @PostConstruct
    public void init() {
       super.init();
    }
}

要覆盖 "myBean" bean 并强制应用程序在需要时使用 child bean,我必须在 faces-config.xml[= 中声明 child bean 26=]

<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>

这是唯一可行的方法,有些事情我不明白。

  1. 如果我不在 faces-config.xml 中声明 child bean,那么 beans 容器总是使用 parent bean 实现,尽管 @ManagedBean 是继承的。
  2. 除非我在 faces-config.xml child bean 声明中声明 <managed-property>,否则不会执行 parent bean 中的注入,例如 serviceManagerController
  3. @PostConstruct方法不在parentchild中执行,只在@PostConstructchild中执行。因此,我必须在 child bean
  4. 的空 @PostConstruct 方法中调用 super.init()

为什么我必须执行这三个步骤才能使 parent 中的注入和 postConstruct 工作?

当然,如果在我的应用程序中我不想继承 BaseBean 并且想在 facelets 中使用这个 bean,那么所有工作都没有问题。

此致

BaseBean 设计错误。 Bean 管理注释 继承。在同一个托管 bean name/identifier 上注册不同子 class 的多个实例在技术上没有任何意义。 BaseBean class 必须是 abstract 并且没有任何 bean 管理注释(这样您和 JSF 都不能“意外地”实例化它)。将那些 bean 管理放在 ChildBean 上。您的 faces-config.xml“修复”基本上就是这样做的。

public abstract class BaseBean implements Serializable {

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

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

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

Managed 属性 和 post construct / pre destroy annotations 是继承的,前提是您还没有在 subclass 中覆盖它们。所以你不需要重新定义它们。

另请参阅:

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