在我的应用程序中,我发现我的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规范是否提及此问题?我在这里遇到麻烦吗?
答案 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
注入)。