Micronaut Mastery: Running Code on Startup
Learn the steps to run microservice code on startup with Micronaut.
Join the DZone community and get the full member experience.
Join For FreeWhen 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
:
// File: 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<ServiceStartedEvent> {
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
:
// File: 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.
Published at DZone with permission of Hubert Klein Ikkink, DZone MVB. See the original article here.
Opinions expressed by DZone contributors are their own.
Comments