When our Micronaut application starts we can listen for the ServiceStartedEvent event and write code that needs to run when the event is fired. We can write a bean that implements the ApplicationEventListener interface with the type ServiceStartedEvent. Or we can use the @EventListener annotation on our method with code we want to run on startup. If the execution of the code can take a while we can also add the @Async annotation to the method, so Micronaut can execute the code on a separate thread.

In our example application we have a reactive repository for a Mongo database and we want to save some data in the database when our Micronaut application starts. First we write a bean that implements the ApplicationEventListener:

Listing 1. src/main/java/mrhaki/Dataloader.java
package mrhaki;

import io.micronaut.context.annotation.Requires;
import io.micronaut.context.env.Environment;
import io.micronaut.context.event.ApplicationEventListener;
import io.micronaut.discovery.event.ServiceStartedEvent;
import io.micronaut.scheduling.annotation.Async;
import io.reactivex.Flowable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.inject.Singleton;

@Singleton
@Requires(notEnv = Environment.TEST) // Don't load data in tests.
public class DataLoader implements ApplicationEventListener {

    private static final Logger log = LoggerFactory.getLogger(DataLoader.class);

    /**
     * Reactive repository for Mongo database to store
     * Conference objects with an id and name property.
     */
    private final ConferenceRepository repository;

    public DataLoader(final ConferenceRepository repository) {
        this.repository = repository;
    }

    @Async
    @Override
    public void onApplicationEvent(final ServiceStartedEvent event) {
        log.info("Loading data at startup");

        // Transform names to Conferences object and save them.
        Flowable.just("Gr8Conf", "Greach", "JavaLand", "JFall", "NextBuild")
                .map(name -> new Conference(name))
                .forEach(this::saveConference);
    }

    /**
     * Save conference in repository.
     *
     * @param conference Conference to be saved.
     */
    private void saveConference(Conference conference) {
        repository
                .save(conference)
                .subscribe(
                        saved -> log.info("Saved conference {}.", saved),
                        throwable -> log.error("Error saving conference.", throwable));
    }
}

Alternatively we could have used the @EventListener annotation on a method with an argument of type ServiceStartedEvent:

Listing 2. src/main/java/mrhaki/Dataloader.java
package mrhaki;

import io.micronaut.context.annotation.Requires;
import io.micronaut.context.env.Environment;
import io.micronaut.context.event.ApplicationEventListener;
import io.micronaut.discovery.event.ServiceStartedEvent;
import io.micronaut.runtime.event.annotation.EventListener;
import io.micronaut.scheduling.annotation.Async;
import io.reactivex.Flowable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.inject.Singleton;

@Singleton
@Requires(notEnv = Environment.TEST) // Don't load data in tests.
public class DataLoader {

    private static final Logger log = LoggerFactory.getLogger(DataLoader.class);

    /**
     * Reactive repository for Mongo database to store
     * Conference objects with an id and name property.
     */
    private final ConferenceRepository repository;

    public DataLoader(final ConferenceRepository repository) {
        this.repository = repository;
    }

    @EventListener
    @Async
    public void loadConferenceData(final ServiceStartedEvent event) {
        log.info("Loading data at startup");

        // Transform names to Conferences object and save them.
        Flowable.just("Gr8Conf", "Greach", "JavaLand", "JFall", "NextBuild")
                .map(name -> new Conference(name))
                .forEach(this::saveConference);
    }

    /**
     * Save conference in repository.
     *
     * @param conference Conference to be saved.
     */
    private void saveConference(Conference conference) {
        repository
                .save(conference)
                .subscribe(
                        saved -> log.info("Saved conference {}.", saved),
                        throwable -> log.error("Error saving conference.", throwable));
    }
}

When we start our Micronaut application we can see in the log messages that our conference data is created:

22:58:17.343 [pool-1-thread-1] INFO  mrhaki.DataLoader - Loading data at startup
22:58:17.343 [main] INFO  io.micronaut.runtime.Micronaut - Startup completed in 1230ms. Server Running: http://localhost:9000
22:58:17.573 [Thread-11] INFO  mrhaki.DataLoader - Saved conference Conference{id=5bb134f505d4feefa74d19c7, name='JFall'}.
22:58:17.573 [Thread-8] INFO  mrhaki.DataLoader - Saved conference Conference{id=5bb134f505d4feefa74d19c3, name='Gr8Conf'}.
22:58:17.573 [Thread-10] INFO  mrhaki.DataLoader - Saved conference Conference{id=5bb134f505d4feefa74d19c5, name='Greach'}.
22:58:17.573 [Thread-9] INFO  mrhaki.DataLoader - Saved conference Conference{id=5bb134f505d4feefa74d19c8, name='NextBuild'}.
22:58:17.573 [Thread-6] INFO  mrhaki.DataLoader - Saved conference Conference{id=5bb134f505d4feefa74d19c6, name='JavaLand'}.

Written with Micronaut 1.0.0.RC1.

shadow-left