Skip to content

Latest commit

 

History

History
136 lines (104 loc) · 7.25 KB

bootstrap_se.asciidoc

File metadata and controls

136 lines (104 loc) · 7.25 KB

Bootstrapping a CDI container in Java SE

In Java SE, the CDI container must be explicitly bootstrapped by the user. This is performed by the SeContainerInitializer abstract class and its static method newInstance().

SeContainerInitializer is a service provider of the service jakarta.enterprise.inject.se.SeContainerInitializer declared in META-INF/services. This class allows a user to configure the CDI container before it is bootstrapped. The SeContainerInitializer.initialize() method bootstraps the container and returns a SeContainer instance.

User can shutdown the container manually by calling the close() method on SeContainer or automatically using try-with-resources since SeContainer extends AutoCloseable interface.

SeContainerInitializer class

CDI container can be configured and bootstrapped from jakarta.enterprise.inject.se.SeContainerInitializer abstract class.

A CDI implementation is required to provide an implementation of SeContainerInitializer declared as a service provider. Static method newInstance() uses Java service provider mechanism to obtain an implementation of SeContainerInitializer and return an instance of it. There must be exactly one provider available, otherwise an IllegalStateException is thrown.

SeContainerInitializer configuration allows explicit addition of elements to the set of automatically discovered elements. These additions are done in an internal synthetic bean archive that is added to the set of bean archives discovered by the container during deployment.

This synthetic bean archive behaves like an explicit bean archive (as defined in [bean_archive_full]).

public abstract class SeContainerInitializer {
    public static SeContainerInitializer newInstance() { ... }
    public SeContainerInitializer addBeanClasses(Class<?>... classes);
    public SeContainerInitializer addPackages(Class<?>... packageClasses);
    public SeContainerInitializer addPackages(boolean scanRecursively, Class<?>... packageClasses);
    public SeContainerInitializer addPackages(Package... packages);
    public SeContainerInitializer addPackages(boolean scanRecursively, Package... packages);
    public SeContainerInitializer addExtensions(Extension... extensions);
    public SeContainerInitializer addExtensions(Class<? extends Extension>... extensions);
    public SeContainerInitializer enableInterceptors(Class<?>... interceptorClasses);
    public SeContainerInitializer enableDecorators(Class<?>... decoratorClasses);
    public SeContainerInitializer selectAlternatives(Class<?>... alternativeClasses);
    public SeContainerInitializer selectAlternativeStereotypes(Class<? extends Annotation>... alternativeStereotypeClasses);
    public SeContainerInitializer addProperty(String key, Object value);
    public SeContainerInitializer setProperties(Map<String, Object> properties);
    public SeContainerInitializer disableDiscovery();
    public SeContainerInitializer setClassLoader(ClassLoader classLoader);
    public SeContainer initialize();
}

Unless specified differently each method of SeContainerInitializer returns the current SeContainerInitializer object.

  • newInstance() static method returns an instance of the implementation of SeContainerInitializer discovered by Java service provider. Each call returns a new instance of SeContainerInitializer. This method throws IllegalStateException if called in Jakarta EE container.

  • addBeanClasses() adds classes to the the synthetic bean archive

  • addPackages() adds packages content to the synthetic bean archive. There are other versions of this method, which enables user to add a package according to class or classes it contains and also to add packages recursively.

  • addExtensions() adds the provided extensions (class or instance) to the synthetic bean archive.

  • enableInterceptors() adds interceptor classes to the list of enabled interceptors for the synthetic bean archive.

  • enableDecorators() adds decorator classes to the list of enabled decorators for the synthetic bean archive.

  • selectAlternatives() adds alternatives classes to the list of selected alternatives for the synthetic bean archive.

  • selectAlternativeStereotypes() adds alternative stereotype classes to the list of selected alternative stereotypes for the synthetic bean archive.

  • addProperty() adds a configuration property to the container

  • setProperties() sets the Map of configuration properties for the container. Original properties Map is replaced by a new instance.

  • disableDiscovery() deactivates automatic type scanning and discovery. All bean archives will be ignored except the implicit bean archive.

  • setClassLoader() changes the default class loader for the container

  • initialize() bootstraps the container and returns a SeContainer as defined in SeContainer interface.

Every invocation of the SeContainerInitializer.initialize() method returns a new SeContainer instance. The application context is started automatically by the container on start up. An implementation does not need to support multiple calls of SeContainerInitializer.initialize() method when the SeContainer is running.

SeContainer interface

The jakarta.enterprise.inject.se.SeContainer interface provides access to the BeanManager and programmatic lookup as defined in [dynamic_lookup]. SeContainer also extends AutoCloseable, so when dereferenced, it should shutdown automatically.

public interface SeContainer extends Instance<Object>,AutoCloseable {
    void close();
    boolean isRunning();
    BeanManager getBeanManager();
}
  • close() method explicitly shuts down the container. If it is called and the container was already shutdown, it throws an IllegalStateException.

  • isRunning() method returns true if called before container shuts down and false after.

  • getBeanManager() method returns the BeanManager (as defined in [beanmanager]) for the running container. If it is called and the container was already shutdown, it throws an IllegalStateException.

SeContainer implements jakarta.enterprise.inject.Instance and therefore might be used to perform programmatic lookup as defined in [dynamic_lookup]. If no qualifier is passed to SeContainer.select() method, the @Default qualifier is assumed.

If any Instance.select() method is called and the container was already shutdown, the IllegalStateException is thrown.

The following code examples demonstrate the options of handling container shutdown:

public static void main(String... args) {
    SeContainerInitializer containerInit = SeContainerInitializer.newInstance();
    SeContainer container = containerInit.initialize();
    // retrieve a bean and do work with it
    MyBean myBean = container.select(MyBean.class).get();
    myBean.doWork();
    // when done
    container.close();
}
public static void main(String... args) {
    try(SeContainer container = SeContainerInitializer.newInstance().initialize()) {
        // start the container, retrieve a bean and do work with it
        MyBean myBean = container.select(MyBean.class).get();
        myBean.doWork();
    }
    // shuts down automatically after the try with resources block.
}