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

Ala*_*ect 1 jsf cdi

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

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

@Named
@RequestScoped
public class BasicBacking {
Run Code Online (Sandbox Code Playgroud)

是否可以使用它:

@Named
@RequestScoped
public class SpecialBacking extends BasicBacking {
Run Code Online (Sandbox Code Playgroud)

没有任何问题?如果我更改范围,例如:

@Named
@ViewScoped
public class ViewBacking extends BasicBacking implements Serializable {
Run Code Online (Sandbox Code Playgroud)

CDI规范是否提到了这一点?我在这里遇到麻烦吗?

Bal*_*usC 5

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

至于你的具体问题,CDI规范第4章说明如下:

第4章继承和专业化

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

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

所以,如果它有metaannotation ,让我们看一下@Namedjavadoc@Inherited:

注释类型命名

@Qualifier
@Documented
@Retention(value=RUNTIME)
public @interface Named
Run Code Online (Sandbox Code Playgroud)

不,它没有.我们来检查一下@RequestScopedjavadoc:

注释类型RequestScoped

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

是的,它有.

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

4.1.继承类型级元数据

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

...

  • 如果X用范围类型Z注释,那么Y继承注释当且仅当Z声明了@Inherited元注释时,Y和任何作为X的子类和Y的超类的中间类都没有声明范围类型.

在您的情况下,声明ViewBacking了显式范围@ViewScoped,因此将使用此范围.如果它没有任何范围,它本来就是@RequestScoped.如果它没有@Named,则它在EL上不可用${viewBacking}(但@Inject由于范围注释仍然可以注入).