java - 不调用抽象祖先的@PostConstruct

标签 java unit-testing jersey jax-rs cdi

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

我有:

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 进行测试

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

这正常吗?我该怎么办?


结论

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

constructed_a()
constructed_b()
constructed_c()

最佳答案

根据 在目标类上声明的拦截器的调用顺序 JSR 318 - Interceptors 1.2规范:

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

  • If a target class has superclasses, any interceptor methods defined on those superclasses are invoked, most general superclass first.
  • The interceptor method, if any, on the target class itself is invoked.

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 生命周期回调来实现可扩展性。

该机制在 Camel CDI 扩展中使用,它在 https://github.com/astefanutti/camel-cdi/blob/b6f52d91b247e36eefb6f3ecde61016d681d3535/impl/src/main/java/org/apache/camel/cdi/CdiCamelContext.java#L37 中使用 @PostConstruct 生命周期回调声明默认的 Camel 上下文

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

两者均由容器按照指定顺序调用。

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

关于java - 不调用抽象祖先的@PostConstruct,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29787068/

相关文章:

java - 使用多线程或优先队列确定特定 API 调用优先级的方法?

java - 我如何在 zk 中使用这个参数?

unit-testing - 如何测试永远循环的代码

unit-testing - Grails 单元测试 "CreateAlias"不起作用

unit-testing - 根据 AAA 正确使用 Moq 回调

tomcat - 将 MarvinFramework 添加到 Tomcat7 上的 Web 应用程序

java - Jersey POJOMappingFeature 将 null 转换为空字符串?

java - 是否可以从方法返回

java - 如何获取swing中的组件名称?

java - 从 JDK 1.6 切换到 1.7 后,Intellij Idea 无法编译我的项目