What is the equivalent of @ManagedBean(eager=true) in CDI

This is not provided by CDI or JSF. You could homegrow your own with a custom CDI qualifier and a ServletContextListener to hook on webapp start.

@Qualifier
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Eager {
    //
}

@WebListener
public class EagerListener implements ServletContextListener{

    private static final AnnotationLiteral<Eager> EAGER_ANNOTATION = new AnnotationLiteral<Eager>() {
        private static final long serialVersionUID = 1L;
    };

    @Override
    public void contextInitialized(ServletContextEvent event) {
        CDI.current().select(EAGER_ANNOTATION).forEach(bean -> bean.toString());
    }

    @Override
    public void contextDestroyed(ServletContextEvent event) {
        // NOOP.
    }

}

(note: toString() triggers lazy instantiation)

import com.example.Eager;
import javax.enterprise.context.ApplicationScoped;

@Eager
@ApplicationScoped
public class YourEagerApplicationScopedBean {

    @PostConstruct
    public void init() {
        System.out.println("Application scoped init!");
    }
}

As to existing libraries, only JSF utility library OmniFaces offers @Eager out the box.

import org.omnifaces.cdi.Eager;
import javax.enterprise.context.ApplicationScoped;

@Eager
@ApplicationScoped
public class YourEagerApplicationScopedBean {

    @PostConstruct
    public void init() {
        System.out.println("Application scoped init!");
    }
}

It's also supported on @SessionScoped, @ViewScoped and @RequestScoped.

Regardless of the approach, the only disadvantage is that FacesContext isn't available at the moment the bean is constructed. But that shouldn't be a big problem, with CDI you can simply directly @Inject artifacts of interest such as ServletContext or HttpSession.


CDI 1.1 also offers a standard way to observe scope lifecycle events, for instance:

public void processApplicationScopedInit(@Observes @Initialized(ApplicationScoped.class) ServletContext payload) {}
public void processApplicationScopedDestroyed(@Observes @Destroyed(ApplicationScoped.class) ServletContext payload) {}

For more information: http://www.next-presso.com/2014/06/you-think-you-know-everything-about-cdi-events-think-again/


As an alternative, you could use EJB instead of CDI. Then you can have a @Singleton with @Startup

import javax.annotation.PostConstruct;
import javax.ejb.Singleton;
import javax.ejb.Startup;

@Singleton
@Startup
public class SomeBean {

    @PostConstruct
    public void init(){
        //Do all needed application initialization.
    }
    ...
}