How to create an EJB Startup Service

In this tutorial, we’ll explore how to use the @Startup and @Singleton annotations in Jakarta EE applications. These annotations allow us to initialize components during application startup and ensure that they are available throughout the application’s lifecycle. We’ll cover the basics of each annotation, how to use them together, and provide examples to illustrate their usage.

Common use cases for the @Startup services

Firstly, let’s cover which are the common use cases of the @Startup service:

  1. Initialization of Application State: When an application requires certain components or resources to be initialized before handling incoming requests, @Startup can be used to ensure that these components are ready as soon as the application starts. This can include initializing caches, loading configuration settings, or establishing connections to external systems.
  2. Eager Initialization of Singleton Beans: Singleton session beans annotated with @Startup are initialized eagerly when the application starts up, rather than being lazily instantiated upon first access. This is useful for beans that provide application-wide functionality or manage shared resources.
  3. Setting Up Background Tasks or Schedulers: @Startup can be used to kick off background processing tasks or scheduling jobs using EJB timers or other scheduling mechanisms. This ensures that background tasks are running and ready to perform their designated functions as soon as the application starts.
  4. Initialization of EJB Timer Services: For applications that rely on EJB timer services for scheduling tasks or events, @Startup can be used to initialize timer configurations or start timers during application startup. This ensures that scheduled tasks are set up and ready to execute according to their defined schedule.
  5. Preloading Application Data: @Startup can be used to preload application data into memory, such as initializing lookup tables, caching frequently accessed data from a database, or loading configuration settings. This helps improve application performance by reducing the latency associated with fetching data from external sources on-demand.
  6. Initializing External Resources: When an application depends on external resources such as connecting to a messaging system, starting a connection pool, or initializing a JMS context, @Startup can be used to ensure that these resources are initialized and available for use as soon as the application starts.

An example of @Startup and @Singleton

In the following example we will show how to eagerly initialize some resources in your application by using the following annotations:

  • @Startup: Annotates a singleton session bean to indicate that it should be initialized eagerly when the application starts up.
  • @Singleton: Specifies that a session bean is a singleton, meaning that there is only one instance of the bean per application.
package com.mastertheboss;

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

@Startup
@Singleton
public class StartupBean {
  private String status;
 
  @PostConstruct
  public void init() {
    status = "Ready";
    // Here init your resources
  }
  
}
@startup annotation tutorial

You can monitor the State of your Service by adding a simple property which you can access from your clients:

package com.mastertheboss;

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

@Singleton
@Startup
public class StartupBean {
    public enum States {BEFORESTARTED, STARTED, PAUSED, SHUTTINGDOWN};
    private States state;
    @PostConstruct
    public void initialize() {
        state = States.BEFORESTARTED;
        // Perform intialization
        state = States.STARTED;
        System.out.println("Service Started");
    }
    @PreDestroy
    public void terminate() {
        state = States.SHUTTINGDOWN;
        // Perform termination
        System.out.println("Shut down in progress");
    }
    public States getState() {
        return state;
    }
    public void setState(States state) {
        this.state = state;
    }
}

Then your client will simply check the state property and verify what’s the current state of the service

@Inject
StartupBean ejb;

System.out.println("State is "+ejb.getState());

Using multiple Startup Beans

Sometimes multiple singleton session beans are used to initialize data for an application and therefore must be initialized in a specific order. In these cases, use the javax.ejb.DependsOn annotation to declare the startup dependencies of the singleton session bean.

Here the PostStartupBean will fire after the StartupBean executes:

package com.mastertheboss;

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

@Startup
@Singleton
@DependsOn("StartupBean")
public class PostStartupBean {
 
  @PostConstruct
  public void init() {
    // Here init your resources
  }
  
}

Conclusion

In this tutorial, we’ve learned how to use the @Startup and @Singleton annotations in Java EE applications to initialize components during application startup. By annotating a singleton session bean with @Startup, we can ensure that it is initialized eagerly when the application starts. Combined with the @Singleton annotation, we can create components that are available throughout the application’s lifecycle. We’ve also seen an example of initializing application settings during application startup using these annotations.