【问题标题】:Can one Named Object inherit another一个命名对象可以继承另一个吗
【发布时间】:2015-07-11 20:16:21
【问题描述】:

在我的应用程序中,我发现我的 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 规范是否提到过这一点?我在这里找麻烦吗?

【问题讨论】:

    标签: jsf cdi


    【解决方案1】:

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

    至于你的具体问题,CDI specification 第 4 章是这样说的:

    第四章继承与特化

    一个 bean 可以从它的超类继承类型级元数据和成员。

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

    那么,让我们看看@Named javadoc 是否有@Inherited 元注释:

    已命名的注释类型

    @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 进行注释,则 Y 继承该注释当且仅当 Z 声明了 @Inherited 元注释 Y 和作为 X 的子类和 Y 的超类的任何中间类都没有声明作用域类型。

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

    【讨论】:

    • 嗯。抱歉,我应该能够为自己找到该规范性文本,但感谢您的彻底回答。但看起来规范特别允许我做我想做的事,所以我会去做。一定要爱 OOP。
    猜你喜欢
    • 1970-01-01
    • 2012-05-19
    • 1970-01-01
    • 2013-08-12
    • 1970-01-01
    • 2011-01-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多