在我的应用程序中,我发现在我的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规范有提到这一点吗?我是在自找麻烦吗?
序言:这些是CDI管理bean,而不是JSF管理bean。我已经回答了你的问题。
关于你的具体问题,CDI规范第4章有如下规定:
第四章。继承和专门化
bean可以从它的超类继承类型级元数据和成员。
bean从其超类继承类型级元数据是通过使用Java@Inherited
元注释来控制的。类型级元数据永远不会从bean实现的接口继承。
那么,让我们看看@Named
javadoc中是否有@Inherited
mettaannotation:
标注类型命名
@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
注入)。