Where do you add initialization code in a Spring Boot application.

Some people think Spring and Spring Boot adds to much “magic” to a Java app, and to some extend I agree.

Have they gone too far in making Java more like a DSL, and have they managed to hide away all imperative code?

I wont go into whether “too far” is the right way to describe it, but it can be quite tricky to understand what is going on under the hood.

One such thing is: I know where my main() method is, but how do I pas arguments, and after starting up Spring Boot, how do I know it has finished
setting up, and done its “startup-whatsamacallit”? When can I assume all beans are setup and ready to use?

I found the following things regarding startup:

  • A CmdlineRunner()
  • An ApplicationRunner()
  • Listening for “startup events”
  • There are more but very obscure…

So which one whould I use?

CommandLineRunner

You could provide a Bean of type CommandLineRunner.

The downside is that ALL CommandLineRunners in a project will be called. Not good.

@Bean
CommandLineRunner commandLineRunner() {
  return new CommandLineRunner() {
    @Override
    public void run(String... args) throws Exception {
      log.info("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
      log.info("These Lines will get printed on application startup");
      log.info("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
    }
  };
}

ApplicationRunner

You could provide a Bean of type ApplicationRunner interface. Similar to CommandLineRunner but you get access to the ApplicationArguments

@Bean
ApplicationRunner applicationRunner() {
  return new ApplicationRunner() {
    @Override
    public void run(ApplicationArguments args) throws Exception {
      log.info("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
      log.info("These Lines will get printed on application startup too");
      log.info("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
    }
  };
}

ApplicationStartedEvent EventListener

@EventListener
public void executeOnStartup(ApplicationStartedEvent event) {
  log.info("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
  log.info("Another way to run something on application startup with event {}", event);
  log.info("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
}

ContextRefreshedEvent EventListener

To run your code after the context is complete but before the application is started, Then you should use the ContextRefreshedEvent.

@EventListener
public void executeOnStartup(ContextRefreshedEvent event) {
  log.info("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
  log.info("Another way to run something on application startup with event {}", event);
  log.info("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
}

Arguments to SpringApplication.run()

This is the classic way of handling args, old-style

@SpringBootApplication
public class Example {
 public static void main(String[] args) {
  
    // Reading Command-Line arguments
      for(String arg:args) {
            System.out.println(arg);
      }
    SpringApplication.run(Example.class, args);
 }
}

Other ways of passing arguments

There are also a number of ways you could pass arguments to your Spring Boot app:

  • mvn spring-boot:run -Dspring-boot.run.arguments=”–firstName=Peter –lastName=Andersson”
  • mvn package java -jar target/[FILENAME.JAR HERE] –firstName=Peter –lastName=Andersson
  • server.port=8080 // default values in application.properties
  • mvn spring-boot:run -Dspring-boot.run.arguments=–server.port=8081 // overwrite port num using CLI

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.