So you need something to happen at startup in your Spring Boot app? That’s no problem.

Fortunately, Spring Boot offers a few different ways to handle that.

We’ll go over some of the best options in this brief guide.

As always, feel free to check out the code on GitHub if you just want to look at some examples.

 

The Problem

The problem is this: Spring Boot is a framework.that requires a bit of setup time when it’s launched.

If you just decide to run some initialization code in any constructor, you might find that you’re trying to access dependent objects that Spring Boot hasn’t yet instantiated.

What you need to do, then, is wait until the Spring context has been initialized. Then, you can run some setup code specific to your app.

Fortunately, the good folks over at Pivotal have anticipated that. As a result, they’ve given you a few different ways to include startup code in your Spring Boot app.

Let’s go through the process of creating a Spring Boot app that handles initialization in a few different ways.

 

The Spring Boot Application

First, create a Spring Boot application. That’s pretty easy with this boilerplate code:

1
2
3
4
5
6
7
@SpringBootApplication
public class InitializeApplication {
     
    public static void main(String[] args) {
        SpringApplication.run(InitializeApplication.class,args);
    }
}

Nothing fancy there.

You’ll also need the basic stuff in pom.xml.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.careydevelopment</groupId>
    <artifactId>spring-boot-initialize</artifactId>
    <version>1.0</version>
    <name>spring-boot-initialize</name>
   
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.0.RELEASE</version>
    </parent>
   
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
     
        <dependency>
            <groupId>org.json</groupId>
            <artifactId>json</artifactId>
            <version>20180813</version>
        </dependency>   
    </dependencies>
   
    <properties>
        <java.version>1.8</java.version>
    </properties>
   
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
   
</project>

Once you’ve got the code in place, run your Spring Boot app by right-clicking on the InitializeApplication class in Eclipse, and choosing Run As… Java Application from the context menu.

You should see your Spring Boot app start up in the console. It will take a few seconds.

 

The ApplicationListenerMethod

Stop your Spring Boot application by pressing the little red button at the top of the console in Eclipse.

Now, create a new component:

1
2
3
4
5
6
7
8
9
@Component
public class ApplicationListenerInitialize implements ApplicationListener<ApplicationReadyEvent>  {
     
    private static final Logger logger = LoggerFactory.getLogger(ApplicationListenerInitialize.class);
 
    public void onApplicationEvent(ApplicationReadyEvent event) {
        logger.info("I waited until Spring Boot finished before getting here!");
    }
}

That class implements an interface called ApplicationListener. Since ApplicationListener can handle different types of events, it uses a type parameter to specify the kind of event it’s listening for in this case.

Here, it’s listening for ContextRefreshedEvent. As the name implies that event gets raised when the Spring Boot application context is refreshed or initialized.

As with just about every other interface, ApplicationListener forces you to implement a method. That method is called onApplicationEvent().

The code above is just logging a simple message when onApplicationEvent() runs. You would normally do something much more sophisticated in that space.

With that class completed, launch your Spring Boot app again and check the console. It should look something like this:

console

As you can see, right at the end of the initialization process, the method is executed and prints the logging info.

But wait. It’s not all the way at the end, is it?

There are two lines logged by the framework following your line.

What if you want to wait until absolutely everything is finished before running your code?

Good news: you can do that.

Go back into your ApplicationListenerInitialize class and swap out ApplicationReadyEvent for ContextRefreshedEvent. You’ll need to do that in two different lines.

Save the file and launch Spring Boot again.

Check the console. You should see something like this:

console2

Aha! Now it’s at the very end.

That’s how you’d make sure to wait until everything is finished before running your init code.

 

The EventListener Annotation

There’s yet another way to get some initialization code running in Spring Boot. It’s with the use of the @EventListener annotation.

Here’s what a simple class with that annotation looks like:

1
2
3
4
5
6
7
8
9
10
@Component
public class EventListenerInitialize {
 
    private static final Logger logger = LoggerFactory.getLogger(EventListenerInitialize.class);
     
    @EventListener(ApplicationReadyEvent.class)
    public void initializeSomething() {
        logger.info("I am now initializing something!");
    }
}

Although the class is a Spring component, you only annotate the method that you want to run the initialization code. In this case, that’s the initializeSomething() method.

You might recognize the class in the parentheses. That’s the ApplicationReadyEvent class that you just used in the previous section.

The method itself just spits out some logging just like in the previous example.

Save that class and run Spring Boot again. Check the console and you should see this:

console3

There it is. Right at the very end, after the context has loaded and the application is ready.

 

CommandLineRunner

You can also use CommandLineRunner to run initialization code.

CommandLineRunner is an interface. So, as with ApplicationListener, you implement it and add the necessary method.

Here’s what the code looks like:

1
2
3
4
5
6
7
8
9
10
11
@Component
public class CommandLineRunnerInitialize implements CommandLineRunner {
 
    private static final Logger logger = LoggerFactory.getLogger(CommandLineRunnerInitialize.class);
     
     
    @Override
    public void run(String... args) {
        logger.info("This is from CommandLineRunner");
    }  
}

The run() method does the heavy lifting. In this case, it’s just logging a simple statement.

That’s really all that’s needed. Restart Spring Boot with that class and take a look at the console.

console4

Great. Another success!

 

SmartInitializingSingleton

Yes, believe it or not, there is an interface called SmartInitializingSingleton that’s part of the Spring framework. You can use it to run some initialization code.

One way to use it is to write a class that implements it and override its single method. But sometimes you might want to take a different approach.

Maybe you’d like to run the initialization code in a configuration class. Here’s how to do that with SmartInitializingSingleton.

1
2
3
4
5
6
7
8
9
10
11
12
@Configuration
public class AppConfig {
 
    private static final Logger logger = LoggerFactory.getLogger(AppConfig.class);
     
    @Bean
    public SmartInitializingSingleton initialize() {
        return () -> {
            logger.info("This was from the smart initializing bean");
        };
    }
}

The method initialize() returns a type of SmartInitializingSingleton. It’s annotated with @Bean so the object is managed by the Spring container.

The interface is implemented via a lambda expression. There’s only one method in the interface and it takes no parameters, so that’s why you see the empty parentheses.

Once again, the “initialization” code just prints something to the log.

That’s it for that class. Relaunch Spring Boot and take a look at the console.

console5

Well look at that. The code runs after the context is initialized but not after the application is ready.

That’s something to keep in mind if you decide to go with this solution.

 

Wrapping It Up

So there you have it. Four different ways that you can run initialization code within a Spring Boot app.

Feel free to check out the source code on GitHub.

And, as always, have fun!