How to use ApplicationRunner in Spring Boot application?
The Application Runner interface provided by Spring Boot is a little advance than the CommandLineRunner Interface. In simple words, we can say that CommandLineRunner Interface does not do more than executing the run() method before the completion of the Spring Boot Application Life Cycle and putting all the program arguments in an array of String.
So, the question comes what is special about “ApplicationRunner”, well It allows you to define the following arguments –
- Optional Arguments
- Non-Optional Arguments
In this post, we will take a deep dive into the Spring Boot application runner along with an example. You can find the same code which I have used in this post onto my GitHub repo-Clone Repo
Note:- With the new release of Spring Boot v2.6 there are nothing changes in terms of application runner
Table of Content
- Why do we need ApplicationRunner
- How to define the “Optional” and “Non-Optional” arguments?
- Let’s Jump to Code
- Console Output
- When to use ApplicationRunner?
- ApplicationRunner vs CommandLineRunner
- Conclusion
1. Why do we need ApplicationRunner?
Let’s say you have need to run a Scheduled batch Job, set some system environment properties, or need to perform some DB operation just before the Spring Boot run() method is finished, so in this kind of scenario ApplicationRunner Interface comes handy. It allows you to do such operations before the Spring Boot’s run() method finishes its execution.
On top of that, we have control over the arguments to make them optional and non-optional.
Here are some of the use cases where you will need Spring Boot Application Runner -
- Batch Job - Trigger a batch job before Spring Boot application startup is complete
- Initializing Cache/Loading addition config - There are a couple of state check which Spring Boot provide (Readiness and Liveness). Liveness is something when your application is up and running while Readiness is a state where your Spring Boot started accepting traffic. So using Liveness and Readiness we can delegate the other tasks such as initializing cache, loading addition data, loading config files to Application Runner.
- Log Command Line Arguments - A Developer can also log some additional command line argument during the application startup using Spring Boot Application Runner.
2. How to define the “Optional” and “Non-Optional” arguments?
Example (Running the spring boot from terminal)-
1Java -jar spring-boot-application-runner.jar nonoptionarg --optionalArg1=Jhooq --optionalArg2=ApplicationRunner
3. Let’s Jump to Code
As per API documentation, ApplicationRunner is an Interface, so we cannot create an instance of it, but we can implement it.
1/**
2 * @author Rahul Wagh
3 */
4public class SpringBootApplicationRunner implements ApplicationRunner {
5
6 private static Logger LOG = LoggerFactory
7 .getLogger(SpringBootApplicationRunner.class);
8
9 public static void main(String] args) {
10 LOG.info("STARTING : Spring boot application starting");
11 SpringApplication.run(SpringBootApplicationRunner.class, args);
12 LOG.info("STOPPED : Spring boot application stopped");
13 }
14
15 @Override
16 public void run(ApplicationArguments args) {
17 LOG.info("EXECUTING : Run method of Application Runner");
18 final List nonOptionArgs = args.getNonOptionArgs();
19 final String] sourceArgs = args.getSourceArgs();
20 final Set optionNames = args.getOptionNames();
21
22 nonOptionArgs.forEach(nonOption -> LOG.info("## Non Option Args : "+nonOption));
23 optionNames.forEach(option -> LOG.info("## Option Names : "+option));
24 Arrays.stream(sourceArgs).forEach(srcArgs ->LOG.info("## Source Args : "+srcArgs));
25 LOG.info("## Option Value of --optionalArg1 : "+args.getOptionValues("optionalArg1"));
26 LOG.info("## Option Value of --optionalArg2 : "+args.getOptionValues("optionalArg2"));
27
28 }
29}
Example (Running the spring from IntelliJ)-
1Java -jar spring-boot-application-runner.jar nonoptionarg --optionalArg1=Jhooq --optionalArg2=ApplicationRunner
4.Console Output
1 main]: Starting SpringBootApplicationRunner on Rahul-PC with PID 11032
2 main]: No active profile set, falling back to default profiles: default
3 main]: Started SpringBootApplicationRunner in 0.705 seconds (JVM running for 1.413)
4 main]: EXECUTING : Run method of Application Runner
5 main]: ## Non Option Args : nonoptionarg
6 main]: ## Option Names : optionalArg2
7 main]: ## Option Names : optionalArg1
8 main]: ## Source Args : nonoptionarg
9 main]: ## Source Args : --optionalArg1=Jhooq
10 main]: ## Source Args : --optionalArg2=ApplicationRunner
11 main]: ## Option Value of --optionalArg1 : Jhooq]
12 main]: ## Option Value of --optionalArg2 : ApplicationRunner]
13 main]: STOPPED : Spring boot application stopped
5. When to use ApplicationRunner?
ApplicationRunner can be used in the following scenarios: –
- Need to add some additional logger information
- Schedule a batch job
- Database operation i.e. cleanup script, status update
6. ApplicationRunner vs CommandLineRunner
- ApplicationRunner and CommandLineRunner both are functional interfaces provided by the spring boot
- Both ApplicationRunner and CommandLineRunner have run() method which needs to be implemented by the implementor class.
- Method signature for run() is different in ApplicationRunner and in CommandLineRunner. ApplicationRunner – run(ApplicationArguments args) ,CommandLineRunner – run(String… args)
- In CommandLineRunner the runtime arguments can be accessed as an Array of strings e.g. Arrays.toString(args).
- While in ApplicationRunner the runtime arguments can be accessed as optionNames e.g. – args.getNonOptionArgs() and nonOptionArgs e.g. – args.getNonOptionArgs()
7. Conclusion
I hope this little tutorial might have helped you to get a better understanding of “How to use ApplicationRunner Interface”. If you have any questions or queries please put your comments below and I will be happy to answer you.
References - When and why we need Spring Boot Application Runner
Want to learn more about deploying Spring Boot on Kubernetes - Click Here