一个命名对象可以继承另一个

时间:2015-07-11 20:16:22

标签: jsf cdi

在我的应用程序中,我发现我的CDI托管bean之间有很多共同的方法,所以遵循DRY原则我想创建一个包含这些方法的超类。然后我会有十几个子课程。

所以超类不是抽象的 - 它有足够的功能来自己编写一个有用的页面。所以我有:

@Named
@RequestScoped
public class BasicBacking {

我是否可以像以下一样使用它:

@Named
@RequestScoped
public class SpecialBacking extends BasicBacking {
没有任何问题?如果我更改范围,例如:

,该怎么办?
@Named
@ViewScoped
public class ViewBacking extends BasicBacking implements Serializable {

CDI规范是否提及此问题?我在这里遇到麻烦吗?

1 个答案:

答案 0 :(得分:5)

前言:这些是CDI托管bean,而不是JSF托管bean。我已经解决了你的问题。

关于你的具体问题,CDI specification第4章说明如下:

  

第4章继承和专业化

     

bean可以从其超类继承类型级元数据和成员。

     

通过使用Java @Inherited元注释来控制来自其超类的bean对类型级元数据的继承。   类型级元数据永远不会从bean实现的接口继承。

所以,让我们看看@Named javadoc是否有@Inherited metaannotation:

  

注释类型命名

@Qualifier
@Documented
@Retention(value=RUNTIME)
public @interface Named

不,它没有。我们来查看@RequestScoped javadoc

  

注释类型RequestScoped

@Target(value={TYPE,METHOD,FIELD})
@Retention(value=RUNTIME)
@Documented
@NormalScope
@Inherited
public @interface RequestScoped

是的,它有。

让我们在CDI规范第4.1章中进一步了解后果:

  

4.1。继承类型级元数据

     

假设类X由托管bean或会话bean Y的bean类直接或间接扩展。

     

...

     
      
  • 如果X使用范围类型Z进行注释,则当且仅当Z声明@Inherited元注释时,Y才会继承注释   并且Y和X的子类以及Y的超类的任何中间类都不声明范围类型。
  •   

在您的情况下,ViewBacking声明了明确的范围@ViewScoped,因此将使用此方法。如果它没有任何范围,那就是@RequestScoped。如果它也没有@Named,则${viewBacking}上的EL不可用(但由于范围注释,仍可通过@Inject注入)。