Search code examples
javadependency-injectionjava-ee-6

Execution Order of @PostConstruct


I have 2 singletons in my JEE application that I want to initialize at start up. Something like this:

@Singleton
@Startup
public class ServiceB {

    @EJB
    private ServiceA a;

    @PostConstruct
    private void init() {
        ....
    }
}

ServiceB doesn't really need ServiceA, I just added the dependency to make sure that ServiceA is fully initialized (read: @PostConstruct-method finished) before ServiceB's init() -Method starts.

But it doesn't wait. ServiceB actually starts before ServiceA.

Is there any way to ensure that one Bean's @PostConstruct- method waits for another Bean's @PostConstruct-method to finish?

I know I could just remove the @PostConstruct Annotation in ServiceA and call it directly from ServiceB

    @PostConstruct init() {
        a.init();
    }

but I have deployments where there is no ServiceB. So I can't rely on ServiceB to init ServiceA. ServiceA has to do that itself. And ServiceB must wait for ServiceA to be done with it.


Solution

  • Use the @DependsOn annotation to declare an initialization dependency on startup beans.

    Example:

    @Singleton
    @Startup
    public class ServiceA {
        @PostConstruct
        public void init() { ... }
    }
    
    @Singleton
    @Startup
    @DependsOn("ServiceA")
    public class ServiceB {
        @EJB
        ServiceA a;
    
        @PostConstruct
        public void init() { ... } // will be called after a is initialized
    }