ApplicationRunner Interface in Spring Boot

Hello Friends!, today we are going to learn about ApplicationRunner Interface.

Spring Boot provides two interfaces, CommandLineRunner and ApplicationRunner, to run specific pieces of code when an application is fully started. These interfaces get called just before run() once SpringApplication completes.

how to create Spring Boot Application using the below ways.

Using Spring Initializr.

Application in STS.

Application with Eclipse and Maven manually

ApplicationRunner Interface

you can implement ApplicationRunner interface as follow, run() gives access to ApplicationArguments.

ApplicationArguments has following methods

String[] getSourceArgs()

Return the raw unprocessed arguments that were passed to the application.

Set<String> getOptionNames()

Return the names of all option arguments. For example, if the arguments were “–foo=bar –debug” would return the values ["foo", "debug"].

boolean containsOption(String name)

Return whether the set of option arguments parsed from the arguments contains an option with the given name.

List<String> getOptionValues(String name)

Return the collection of values associated with the arguments option having the given name.

  • if the option is present and has no argument (e.g.: “–foo”), return an empty collection ([])
  • if the option is present and has a single value (e.g. “–foo=bar”), return a collection having one element (["bar"])
  • if the option is present and has multiple values (e.g. “–foo=bar –foo=baz”), return a collection having elements for each value (["bar", "baz"])
  • if the option is not present, return null
List<String> getNonOptionArgs()

Return the collection of non-option arguments parsed.

Example implementation of ApplicationRunner interface as follow.

package com.gyanideveloper.springboot.hook.command;

import java.util.Arrays;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;

@Component
public class CustApplicationRunner implements ApplicationRunner {

	private static final Logger logger = LoggerFactory.getLogger(CustApplicationRunner.class);

	@Override
	public void run(ApplicationArguments args) throws Exception {
		logger.info("Application started with CustApplicationRunner::run(-)");
		logger.info("Row Arguments :: " + Arrays.toString(args.getSourceArgs()));
		logger.info("getOptionNames() :: " + args.getOptionNames());
		logger.info("containsOption(-) :: " + args.containsOption("server.port"));
		logger.info("getOptionValues(-) :: " + args.getOptionValues("server.port"));
		logger.info("getNonOptionArgs() :: " + args.getNonOptionArgs());

	}

}

ApplicationRunner interface provides single run() , it gives access to the ApplicationArguments it provides access to the arguments that were used to run a SpringApplication.

If you need access to raw String instead of the ApplicationArguments consider using CommandLineRunner.

if you run the application, you can see application console log as follows, we have provides --server.port=8383 foo arguments while starting the application.

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.3.0.RELEASE)

2020-06-03 22:24:20.354  INFO 4480 --- [           main] c.g.s.hook.SpringBootHookApplication     : Starting SpringBootHookApplication on DESKTOP-R5VMSGQ with PID 4480 (F:\workspace-spring-tool-suite-4-4.6.1.RELEASE\spring-boot-hook\target\classes started by Sada in F:\workspace-spring-tool-suite-4-4.6.1.RELEASE\spring-boot-hook)
2020-06-03 22:24:20.357  INFO 4480 --- [           main] c.g.s.hook.SpringBootHookApplication     : No active profile set, falling back to default profiles: default
2020-06-03 22:24:20.925  INFO 4480 --- [           main] c.g.s.hook.SpringBootHookApplication     : Started SpringBootHookApplication in 0.931 seconds (JVM running for 1.398)
2020-06-03 22:24:20.928  INFO 4480 --- [           main] c.g.s.h.command.CustApplicationRunner    : Application started with CustApplicationRunner::run(-)
2020-06-03 22:24:20.928  INFO 4480 --- [           main] c.g.s.h.command.CustApplicationRunner    : Row Arguments :: [--server.port=8383, foo]
2020-06-03 22:24:20.928  INFO 4480 --- [           main] c.g.s.h.command.CustApplicationRunner    : getOptionNames() :: [server.port]
2020-06-03 22:24:20.929  INFO 4480 --- [           main] c.g.s.h.command.CustApplicationRunner    : containsOption(-) :: true
2020-06-03 22:24:20.929  INFO 4480 --- [           main] c.g.s.h.command.CustApplicationRunner    : getOptionValues(-) :: [8383]
2020-06-03 22:24:20.929  INFO 4480 --- [           main] c.g.s.h.command.CustApplicationRunner    : getNonOptionArgs() :: [foo]

Ordering CommandLineRunner Interface

we can use multiple CommandLineRunner or ApplicationRunner beans in a single application. Spring automatically picks them up, in case of if we want to Order them, we can use the following two ways.

  • Using  @Order annotation
  • implementing Ordered interface

Using  @Order annotation

@Order annotation defines the sort order for an annotated component.we can provide the priority for a component.

 Let’s see the example code for more clarity.

package com.gyanideveloper.springboot.hook.command;

import java.util.Arrays;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

@Component
@Order(1)
public class CustApplicationRunner implements ApplicationRunner {

	private static final Logger logger = LoggerFactory.getLogger(CustApplicationRunner.class);

	@Override
	public void run(ApplicationArguments args) throws Exception {
		logger.info("Application started with CustApplicationRunner::run(-)");
		logger.info("Row Arguments :: " + Arrays.toString(args.getSourceArgs()));
		logger.info("getOptionNames() :: " + args.getOptionNames());
		logger.info("containsOption(-) :: " + args.containsOption("server.port"));
		logger.info("getOptionValues(-) :: " + args.getOptionValues("server.port"));
		logger.info("getNonOptionArgs() :: " + args.getNonOptionArgs());

	}

}

implementing Ordered interface

we need to implement Ordered interface and provide the implementation for getOrder() method

Let’s see the example code for more clarity.

package com.gyanideveloper.springboot.hook.command;

import java.util.Arrays;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;

@Component
public class CustApplicationRunnerSecond implements ApplicationRunner,Ordered {

	private static final Logger logger = LoggerFactory.getLogger(CustApplicationRunnerSecond.class);

	@Override
	public void run(ApplicationArguments args) throws Exception {
		logger.info("Application started with CustApplicationRunnerSecond::run(-) :: " + Arrays.toString(args.getSourceArgs()));
	}

	@Override
	public int getOrder() {
		return 2;
	}

}

if you run the application, you can see application console log as follows, we have provides --server.port=8383 foo arguments while starting the application.

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.3.0.RELEASE)

2020-06-03 22:51:08.191  INFO 9832 --- [           main] c.g.s.hook.SpringBootHookApplication     : Starting SpringBootHookApplication on DESKTOP-R5VMSGQ with PID 9832 (F:\workspace-spring-tool-suite-4-4.6.1.RELEASE\spring-boot-hook\target\classes started by Sada in F:\workspace-spring-tool-suite-4-4.6.1.RELEASE\spring-boot-hook)
2020-06-03 22:51:08.194  INFO 9832 --- [           main] c.g.s.hook.SpringBootHookApplication     : No active profile set, falling back to default profiles: default
2020-06-03 22:51:08.769  INFO 9832 --- [           main] c.g.s.hook.SpringBootHookApplication     : Started SpringBootHookApplication in 0.946 seconds (JVM running for 1.458)
2020-06-03 22:51:08.772  INFO 9832 --- [           main] c.g.s.h.command.CustApplicationRunner    : Application started with CustApplicationRunner::run(-)
2020-06-03 22:51:08.772  INFO 9832 --- [           main] c.g.s.h.command.CustApplicationRunner    : Row Arguments :: [--server.port=8383, foo]
2020-06-03 22:51:08.773  INFO 9832 --- [           main] c.g.s.h.command.CustApplicationRunner    : getOptionNames() :: [server.port]
2020-06-03 22:51:08.773  INFO 9832 --- [           main] c.g.s.h.command.CustApplicationRunner    : containsOption(-) :: true
2020-06-03 22:51:08.773  INFO 9832 --- [           main] c.g.s.h.command.CustApplicationRunner    : getOptionValues(-) :: [8383]
2020-06-03 22:51:08.773  INFO 9832 --- [           main] c.g.s.h.command.CustApplicationRunner    : getNonOptionArgs() :: [foo]
2020-06-03 22:51:08.773  INFO 9832 --- [           main] c.g.s.h.c.CustApplicationRunnerSecond    : Application started with CustApplicationRunnerSecond::run(-) :: [--server.port=8383, foo]

ApplicationRunner as @Bean

Example implementation of ApplicationRunner as @Bean follow.

package com.gyanideveloper.springboot.hook;

import java.util.Arrays;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.ApplicationRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;

@SpringBootApplication
public class SpringBootHookApplication {

	private static final Logger logger = LoggerFactory.getLogger(SpringBootHookApplication.class);

	@Bean
	public ApplicationRunner getApplicationRunner() {
		return args -> {
			logger.info("Application started with @Bean ApplicationRunner::run(-) ::"
					+ Arrays.toString(args.getSourceArgs()));
		};
	}

	public static void main(String[] args) {
		SpringApplication.run(SpringBootHookApplication.class, args);
	}

}

if you run the application, you can see application console log as follows, we have provides --server.port=8383 foo arguments while starting the application.

2020-06-03 23:01:39.821  INFO 2820 --- [           main] c.g.s.hook.SpringBootHookApplication     : Application started with @Bean ApplicationRunner::run(-) ::[--server.port=8383, foo]

When to use it

When you want to execute some piece of code exactly before the application startup completes.

Final Note

we have learn ApplicationRunner interface in details. full example code is available on GitHub

2 thoughts on “ApplicationRunner Interface in Spring Boot”

Leave a Comment