Micronaut Mastery: Running Code On Startup
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
:
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
:
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.