一个命名对象可以继承另一个命名对象吗
Can one Named Object inherit another
在我的应用程序中,我发现我的 CDI 托管 bean 之间有很多共同的方法,因此遵循 DRY 原则,我想创建一个包含这些方法的超级 class。然后我会有十几个子classes.
所以超级 class 不是抽象的 -- 它具有足够的功能来单独编写一个有用的页面。所以我有:
@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 specification 第 4 章如下所述:
Chapter 4. Inheritance and specialization
A bean may inherit type-level metadata and members from its superclasses.
Inheritance of type-level metadata by beans from their superclasses is controlled via use of the Java @Inherited
metaannotation.
Type-level metadata is never inherited from interfaces implemented by a bean.
那么,让我们看看 @Named
javadoc if it has @Inherited
元注释:
Annotation Type Named
@Qualifier
@Documented
@Retention(value=RUNTIME)
public @interface Named
不,没有。让我们检查一下 @RequestScoped
javadoc:
Annotation Type RequestScoped
@Target(value={TYPE,METHOD,FIELD})
@Retention(value=RUNTIME)
@Documented
@NormalScope
@Inherited
public @interface RequestScoped
是的,它有。
让我们进一步了解 CDI 规范第 4.1 章的后果:
4.1. Inheritance of type-level metadata
Suppose a class X is extended directly or indirectly by the bean class of a managed bean or session bean Y.
...
- If X is annotated with a scope type Z then Y inherits the annotation if and only if Z declares the @Inherited metaannotation
and neither Y nor any intermediate class that is a subclass of X and a superclass of Y declares a scope type.
在您的例子中,ViewBacking
声明了一个明确的范围 @ViewScoped
,因此将使用它。如果它没有任何作用域,它应该是 @RequestScoped
。如果它也没有 @Named
,它就不会在 ${viewBacking}
上的 EL 中可用(但由于范围注释,仍然可以通过 @Inject
注入)。
在我的应用程序中,我发现我的 CDI 托管 bean 之间有很多共同的方法,因此遵循 DRY 原则,我想创建一个包含这些方法的超级 class。然后我会有十几个子classes.
所以超级 class 不是抽象的 -- 它具有足够的功能来单独编写一个有用的页面。所以我有:
@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 specification 第 4 章如下所述:
Chapter 4. Inheritance and specialization
A bean may inherit type-level metadata and members from its superclasses.
Inheritance of type-level metadata by beans from their superclasses is controlled via use of the Java
@Inherited
metaannotation. Type-level metadata is never inherited from interfaces implemented by a bean.
那么,让我们看看 @Named
javadoc if it has @Inherited
元注释:
Annotation Type Named
@Qualifier @Documented @Retention(value=RUNTIME) public @interface Named
不,没有。让我们检查一下 @RequestScoped
javadoc:
Annotation Type RequestScoped
@Target(value={TYPE,METHOD,FIELD}) @Retention(value=RUNTIME) @Documented @NormalScope @Inherited public @interface RequestScoped
是的,它有。
让我们进一步了解 CDI 规范第 4.1 章的后果:
4.1. Inheritance of type-level metadata
Suppose a class X is extended directly or indirectly by the bean class of a managed bean or session bean Y.
...
- If X is annotated with a scope type Z then Y inherits the annotation if and only if Z declares the @Inherited metaannotation and neither Y nor any intermediate class that is a subclass of X and a superclass of Y declares a scope type.
在您的例子中,ViewBacking
声明了一个明确的范围 @ViewScoped
,因此将使用它。如果它没有任何作用域,它应该是 @RequestScoped
。如果它也没有 @Named
,它就不会在 ${viewBacking}
上的 EL 中可用(但由于范围注释,仍然可以通过 @Inject
注入)。