I'm writing a JAX-RS library (not an application).
I have:
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
}
And test class:
@Path("c")
public class C extends B {
@PostConstrct
private void constructed_c() {} // invoked
}
I'm testing with jersey test framework v2.17
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?
Conclusion
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()
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 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.
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.
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
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With