在我的应用程序中,我发现我的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规范是否提到了这一点?我在这里遇到麻烦吗?
前言:这些是CDI托管bean,而不是JSF托管bean.我已经解决了你的问题.
至于你的具体问题,CDI规范第4章说明如下:
第4章继承和专业化
bean可以从其超类继承类型级元数据和成员.
通过使用Java元
@Inherited注释来控制来自其超类的bean对类型级元数据的继承.类型级元数据永远不会从bean实现的接口继承.
所以,如果它有metaannotation ,让我们看一下@Namedjavadoc@Inherited:
注释类型命名
Run Code Online (Sandbox Code Playgroud)@Qualifier @Documented @Retention(value=RUNTIME) public @interface Named
不,它没有.我们来检查一下@RequestScopedjavadoc:
注释类型RequestScoped
Run Code Online (Sandbox Code Playgroud)@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,则它在EL上不可用${viewBacking}(但@Inject由于范围注释仍然可以注入).