不调用抽象祖先的@PostConstruct [英] @PostConstruct of abstract ancestors are not invoked

查看:43
本文介绍了不调用抽象祖先的@PostConstruct的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个 JAX-RS 库(不是应用程序).

I'm writing a JAX-RS library (not an application).

我有:

abstract class A {

    @PostConstruct
    private void constructed_a() {} // not invoked

    @Inject
    private Some some;
}


public abstract class B extends A {

    @PostConstruct
    private void constructed_b() {} // not invoked
}

和测试类:

@Path("c")
public class C extends B {

    @PostConstrct
    private void constructed_c() {} // invoked
}

我正在使用 jersey 测试框架 v2.17 进行测试

I'm testing with jersey test framework v2.17

我发现只有 constructed_c() 被调用,而祖先中定义的那些方法没有被调用.请注意,在类 A 中使用 @Inject 声明的字段(some) 已正确注入.

I found that only constructed_c() is invoked and those method defined in ancestors are not invoked. Note that the field(some) declared with @Inject in class A is properly injected.

这正常吗?我该怎么办?

Is this normal? What should I do?

结论

我使用嵌入式 glassfish 进行了测试,发现正如 Antonin Stefanutti 指出的那样,这些回调方法按预期顺序调用.

I tested with embedded-glassfish and found that, as Antonin Stefanutti pointed, those callback methods invoked in order as expected.

constructed_a()
constructed_b()
constructed_c()

推荐答案

根据JSR 318 - 拦截器 1.2 规范:

According to section Invocation Order of Interceptors Declared on the Target Class of the JSR 318 - Interceptors 1.2 specification:

在目标类或其超类上声明的拦截器方法按以下顺序调用:

Interceptor methods declared on the target class or its superclasses are invoked in the following order:

  • 如果目标类具有超类,则调用在这些超类上定义的任何拦截器方法,首先是最通用的超类.
  • 调用目标类本身的拦截器方法(如果有).

如果一个拦截器方法被另一个方法覆盖(不管是否该方法本身是一个拦截器方法),它不会被调用.

If an interceptor method is overridden by another method (regardless of whether that method is itself an interceptor method), it will not be invoked.

这意味着在编写库/框架时,可以在父类和子类中使用 @PostConstruct 生命周期回调来实现可扩展性.

That means that when writing a library / framework, it is possible to achieve extensibility while using the @PostConstruct lifecyle callback both in the parent class and the child class.

Camel CDI 扩展中使用了该机制,该扩展在 https://github.com/astefanutti/camel-cdi/blob/b6f52d91b247e36eefb16f3ecde6/impl/src/main/java/org/apache/camel/cdi/CdiCamelContext.java#L37

That mechanism is used in the Camel CDI extension that declares a default Camel context with a @PostConstruct lifecycle callback in https://github.com/astefanutti/camel-cdi/blob/b6f52d91b247e36eefb6f3ecde61016d681d3535/impl/src/main/java/org/apache/camel/cdi/CdiCamelContext.java#L37

这可以由用户扩展,例如 https://github.com/astefanutti/camel-cdi/blob/b6f52d91b247e36eefb6f3ecde61016d681d3535/envs/se/src/main/java/org/apache/camel/cdi/se/bean/CustomLifecycleCamelContext.java#L37 声明自己的 @PostConstruct 生命周期回调.

And that can be extended by users like in https://github.com/astefanutti/camel-cdi/blob/b6f52d91b247e36eefb6f3ecde61016d681d3535/envs/se/src/main/java/org/apache/camel/cdi/se/bean/CustomLifecycleCamelContext.java#L37 that declares its own @PostConstruct lifecycle callback.

两者都被容器按照指定的顺序调用.

Both being called by the container following the specified order.

这意味着从设计的角度来看,您的方法是正确的.但是,由于 Jersey 依赖注入基于 HK2 而不是 CDI,并且依赖于 jersey-gf-cdi 之类的桥接器,因此该级别可能存在问题.

That means that your approach is correct from the design standpoint. However, as Jersey dependency injection is based on HK2 and not CDI and relies on bridges like jersey-gf-cdi there might be an issue at that level.

这篇关于不调用抽象祖先的@PostConstruct的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆