How to execute a piece of logic immediately after the Spring Boot application starts

1. Preface I don't know if you've received this requirement, so just execute some logic when the project starts.For exam...
1. Preface
2. CommandLineRunner
3. ApplicationRunner
4. Pass-through parameters
5. Summary

1. Preface

I don't know if you've received this requirement, so just execute some logic when the project starts.For example, simple cache preheating, or broadcasting after going online, and so on.If you use the Spring Boot framework, you can do so with its interfaces CommandLineRunner and ApplicationRunner.

2. CommandLineRunner

org.springframework.boot.CommandLineRunner is an interface provided by Spring Boot, and when you implement it and inject it into the Spring IoC container, the Spring Boot application will execute its run method when it starts.A Spring Boot can have multiple implementations of CommandLineRunner, and when there are multiple implementations, you can implement the Ordered interface to control the order in which these implementations execute (the higher the Order value, the lower the priority).Next, let's declare the two implementations and specify the order:

Priority implementation:

package cn.felord; import lombok.extern.slf4j.Slf4j; import org.springframework.boot.CommandLineRunner; import org.springframework.core.Ordered; import org.springframework.stereotype.Component; /** * Highest priority * This class expects the first sequential execution after springboot starts * @author felord.cn * @since 12:57 **/ @Slf4j @Component public class HighOrderCommandLineRunner implements CommandLineRunner, Ordered { @Override public void run(String... args) throws Exception { for (String arg : args) { log.info("arg = " + arg); } log.info("i am highOrderRunner"); } @Override public int getOrder() { return Integer.MIN_VALUE+1; } }

Execute in the second order:

package cn.felord; import lombok.extern.slf4j.Slf4j; import org.springframework.boot.CommandLineRunner; import org.springframework.core.Ordered; import org.springframework.stereotype.Component; /** * Priority is lower than {@code HighOrderCommandLineRunner} * @author felord.cn * @since 12:59 **/ @Slf4j @Component public class LowOrderCommandLineRunner implements CommandLineRunner, Ordered { @Override public void run(String... args) throws Exception { log.info("i am lowOrderRunner"); } @Override public int getOrder() { return Integer.MIN_VALUE+1; } }

After the Spring Boot application is started, the console prints the results in a predetermined order:

2020-05-30 23:11:03.685 INFO 11976 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path '' 2020-05-30 23:11:03.701 INFO 11976 --- [ main] c.f.Application : Started SpringBootApplication in 4.272 seconds (JVM running for 6.316) 2020-05-30 23:11:03.706 INFO 11976 --- [ main] c.f.HighOrderCommandLineRunner : i am highOrderRunner 2020-05-30 23:11:03.706 INFO 11976 --- [ main] c.f.LowOrderCommandLineRunner : i am lowOrderRunner

3. ApplicationRunner

In Spring Boot 1.3.0, another interface, ApplicationRunner, was introduced, which has the same functionality as CommandLineRunner.CommandLineRunner receives a variable parameter String... args, while ApplicationRunner receives an encapsulated object parameter ApplicationArguments.In addition, they function exactly the same, even the method name.Declare an ApplicationRunner with the lowest priority:

package cn.felord; import lombok.extern.slf4j.Slf4j; import org.springframework.boot.ApplicationArguments; import org.springframework.boot.ApplicationRunner; import org.springframework.core.Ordered; import org.springframework.stereotype.Component; import java.util.Arrays; import java.util.List; import java.util.Set; /** * Lowest priority * @author felord.cn * @since 13:00 **/ @Slf4j @Component public class DefaultApplicationRunner implements ApplicationRunner, Ordered { @Override public void run(ApplicationArguments args) throws Exception { log.info("i am applicationRunner"); Set<String> optionNames = args.getOptionNames(); log.info("optionNames = " + optionNames); String[] sourceArgs = args.getSourceArgs(); log.info("sourceArgs = " + Arrays.toString(sourceArgs)); List<String> nonOptionArgs = args.getNonOptionArgs(); log.info("nonOptionArgs = " + nonOptionArgs); List<String> optionValues = args.getOptionValues("foo"); log.info("optionValues = " + optionValues); } @Override public int getOrder() { return Integer.MIN_VALUE+2; } }

The execution results of three classes are printed in sequence:

2020-06-01 13:02:39.420 INFO 19032 --- [ main] c.f.MybatisResultmapApplication : Started MybatisResultmapApplication in 1.801 seconds (JVM running for 2.266) 2020-06-01 13:02:39.423 INFO 19032 --- [ main] c.f.HighOrderCommandLineRunner : i am highOrderRunner 2020-06-01 13:02:39.423 INFO 19032 --- [ main] c.f.LowOrderCommandLineRunner : i am lowOrderRunner 2020-06-01 13:02:39.423 INFO 19032 --- [ main] c.f.DefaultApplicationRunner : i am applicationRunner 2020-06-01 13:02:39.423 INFO 19032 --- [ main] c.f.DefaultApplicationRunner : optionNames = [] 2020-06-01 13:02:39.423 INFO 19032 --- [ main] c.f.DefaultApplicationRunner : sourceArgs = [] 2020-06-01 13:02:39.423 INFO 19032 --- [ main] c.f.DefaultApplicationRunner : nonOptionArgs = [] 2020-06-01 13:02:39.423 INFO 19032 --- [ main] c.f.DefaultApplicationRunner : optionValues = null

The Ordered interface cannot be replaced by the @Order comment.

4. Pass-through parameters

I believe that many students are beginning to be interested in these two methods.Spring Boot applications can accept parameters when they start, in other words, the main method of Spring Boot can accept parameters.These parameters are passed through the command line java-jarYourapp.jar<param>to pass.The CommandLineRunner receives these interfaces as is, and these parameters can also be encapsulated in the ApplicationArguments object for calls by the ApplicationRunner.Let's take a look at how ApplicationArguments works:

  • getSourceArgs() is passed to the application's original parameters, returning an array of strings for those parameters.

  • getOptionNames() Gets the set of Set strings for the option name.For example--Spring.profiles.active=dev--debug will return ["spring.profiles.active","debug"].

  • getOptionValues(String name) gets the option value corresponding to that name by name.For example, --foo=bar --foo=baz will return ["bar","baz"].

  • containsOption(String name) is used to determine if an option's name is included.

  • getNonOptionArgs() is used to get all the no-option parameters.

    Next let's try a wave where you can run a Spring Boot app, Jar

java -jar yourapp.jar --foo=bar --foo=baz --dev.name=Small Fatty Man java felordcn

Or open the configuration item for Spring Boot to apply the main method in the IDEA development tool and configure it as follows, as with other IDE tools.

Run the Spring Boot application and it will print out:

2020-06-01 15:04:31.490 INFO 13208 --- [ main] c.f.HighOrderCommandLineRunner : arg = --foo=bar 2020-06-01 15:04:31.490 INFO 13208 --- [ main] c.f.HighOrderCommandLineRunner : arg = --foo=baz 2020-06-01 15:04:31.490 INFO 13208 --- [ main] c.f.HighOrderCommandLineRunner : arg = --dev.name=Small Fatty Man 2020-06-01 15:04:31.490 INFO 13208 --- [ main] c.f.HighOrderCommandLineRunner : arg = java 2020-06-01 15:04:31.490 INFO 13208 --- [ main] c.f.HighOrderCommandLineRunner : arg = felordcn 2020-06-01 15:04:31.491 INFO 13208 --- [ main] c.f.HighOrderCommandLineRunner : i am highOrderRunner 2020-06-01 15:04:31.491 INFO 13208 --- [ main] c.f.LowOrderCommandLineRunner : i am lowOrderRunner 2020-06-01 15:04:31.491 INFO 13208 --- [ main] c.f.DefaultApplicationRunner : i am applicationRunner 2020-06-01 15:04:31.491 INFO 13208 --- [ main] c.f.DefaultApplicationRunner : optionNames = [dev.name, foo] 2020-06-01 15:04:31.491 INFO 13208 --- [ main] c.f.DefaultApplicationRunner : sourceArgs = [--foo=bar, --foo=baz, --dev.name=Small Fatty Man, java, felordcn] 2020-06-01 15:04:31.491 INFO 13208 --- [ main] c.f.DefaultApplicationRunner : nonOptionArgs = [java, felordcn] 2020-06-01 15:04:31.491 INFO 13208 --- [ main] c.f.DefaultApplicationRunner : optionValues = [bar, baz]

Then you can execute some logic dynamically according to your actual needs.

5. Summary

Today we have explained CommandLineRunner and ApplicationRunner, from usage to sequential execution, and introduced and demonstrated Spring Boot pass parameters, which we hope will help you.More attention: Small Fatty Man, more programming dry goods to share with you.

Focus on Public Number: Felordcn for more information

Personal blog:https://felord.cn

1 June 2020, 22:56 | Views: 8996

Add new comment

For adding a comment, please log in
or create account

0 comments