preface
After learning about the all-important Refresh method and Bean instantiation, the next step is to learn to start the loader based on the run method.
public ConfigurableApplicationContext run(String... args) {... callRunners(context, applicationArguments); . }Copy the code
The callRunners(Context, applicationArguments) method calls the boot loader.
After what we’ve learned, the source code for this section should look effortless.
Boot loader
The boot loader is usually used when something needs to be done immediately after the application starts.
practice
The boot loader can be implemented in two ways: CommandLineRunner and ApplicationRunner interfaces.
Implements the CommandLineRunner interface
@Component
public class MyOneRunner implements CommandLineRunner {
@Override
public void run(String... args) throws Exception {
System.out.println("My first boot loader."); }}Copy the code
Implement the ApplicationRunner interface
@Component
public class MyTwoRunner implements ApplicationRunner {
@Override
public void run(ApplicationArguments args) throws Exception {
System.out.println("My second boot loader"); }}Copy the code
Print the result
Now, why did MyTwoRunner print before MyOneRunner?
Then we use @order () annotations: @oder (11)MyTwoRunner, @Order(10)MyOneRunner:
This time the order of execution has changed, we take these problems, to learn about the relevant source code.
Start loader principle
private void callRunners(ApplicationContext context, ApplicationArguments args) {
List<Object> runners = new ArrayList<>();
// Get the Bean of type ApplicationRunner in the container
runners.addAll(context.getBeansOfType(ApplicationRunner.class).values());
// Get the CommandLineRunner type Bean in the container
runners.addAll(context.getBeansOfType(CommandLineRunner.class).values());
/ / sorting
AnnotationAwareOrderComparator.sort(runners);
// Execute the run body of ApplicationRunner and CommandLineRunner respectively
for (Object runner : new LinkedHashSet<>(runners)) {
if (runner instanceof ApplicationRunner) {
callRunner((ApplicationRunner) runner, args);
}
if (runner instanceofCommandLineRunner) { callRunner((CommandLineRunner) runner, args); }}}Copy the code
Hey, hey, after the previous study, these logical bodies, we can see what is going on.
Although it is a relatively simple functional logic, but also a little sense of achievement.
In the absence of the @Order annotation, ApplicationRunner is added and CommandLineRunner is added, so in the absence of the @Order annotation, ApplicationRunner is executed first.
And because the runners are added to the runners collection, the sorting method is performed, so the @order method we added takes effect.
conclusion
This section of things is relatively simple, the main understanding of Spring Boot has such a thing, a simple look at the source.