@PostConstruct is not invoked for @ApplicationScoped on initialisation?

What you are seeing is Weld's lazy approach to bean initialization. With all normal scoped beans (anything except @Dependent from CDI-provided scopes), you in fact inject a proxy which delegates calls to contextual instance. And until you try to invoke any bean method on that proxy, the contextual instance is not created.

CDI specification does not mandate beans to be eager or lazy, this is implementation-based choice (I am not sure whether Weld docs mention this now). In case of Weld this is mainly performance choice as many of those beans would be initialized for nothing (never used, for instance) and it would slow down bootstrap a lot.

Please note that this is not an inconsistent state, it works like this for every scope Weld provides. It is also not a contradiction to javax.inject.Provider.get() as it does not state that @PostConstruct has to be invoked before you get the instance back. Furthermore the instance you in fact get is the proxy instance and that one is fully initialized anyway.

So it boils to to general problem of lazy versus eager init and which is better and/or which feels more natural.

As for a "solution":

  • You can use EJB's @javax.ejb.Singleton and use @Startup annotation. This will behave pretty much like @ApplicationScoped would so it might be good enough if you are in EE environment of course.
  • Or you can create a dummy ping() method on your @ApplicationScoped bean and invoke it as soon as your application starts. This will force the creation of the bean hence invoking @PostConstruct - much like you did with test() method in your code sample above.

As a side note - in your example the @Inject annotation on your constructor is of no use. It is only required for constructors with params.