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.