l a s
l a s

Reputation: 3923

SpringBoot CommandLineRunner

In what circumstances is CommandLineRunner preferred over writing additional code in the main method of a Spring Boot application?

I understand that CommandLineRunner is executed before main is completed.

Upvotes: 3

Views: 4604

Answers (9)

lewis machilika
lewis machilika

Reputation: 897

I mostly use CommandLineRunner to:

  1. Apply initial migrations
  2. Run a code that is independent of REST/SOAP calls.

Upvotes: 0

Hilal Aissani
Hilal Aissani

Reputation: 735

public class Phone {

    @Autowired
    BeanExample beanExample;

    public void print(){
        beanExample.fn();
    }

}



           public class BeansCreatorClass {
    
          @Bean
          public  BeanExample getBeanExample(){
              return new BeanExample();
          }
    
    
          @Bean
        public Phone  getPhone(){
              return new Phone();
          }
    
    }
        
        
         @SpringBootApplication
            public class SpringBootRunnerConfigurationPropertiesApplication  implements CommandLineRunner, ApplicationRunner {
            
                
                public static void main(String[] args){
                    SpringApplication.run(SpringBootRunnerConfigurationPropertiesApplication.class, args);
                    System.out.println("==== spring boot commandLine is running === ");
            
                   // beans creator class is the class contains all beans needed 
                    ApplicationContext applicationContext = new AnnotationConfigApplicationContext(BeansCreatorClass.class);
            
                      Phone phone = applicationContext.getBean(Phone.class);
                      phone.print();
            
                      
            
                }
            
                // commandLineRunner
                public void run(String... args) throws Exception {
                    System.out.println("===  commandLine Runner is here  ==== ");
                }
            
            
                // application runner
                @Override
                public void run(ApplicationArguments args) throws Exception {
                    System.out.println("=== application runner is here ====");
                }
            }

Upvotes: 0

Cunzhi Li
Cunzhi Li

Reputation: 1

ApplicationRunner and CommandLineRunner: two of them can execute some custom code before your application finished starting up.

ComandLineRunner:

@Component
    public class CommandLineAppStartupRunner implements CommandLineRunner {
    private static final Logger logger = LoggerFactory.getLogger(CommandLineAppStartupRunner.class);
    @Override
    public void run(String...args) throws Exception {
    logger.info(Arrays.toString(args));
    }
}

you can get the args directly

ApplicationRunner

@Component
public class AppStartupRunner implements ApplicationRunner {
    private static final Logger logger = LoggerFactory.getLogger(AppStartupRunner.class);
    @Override
    public void run(ApplicationArguments args) throws Exception {
        logger.info(args.getOptionNames());
    }
}

ApplicationRunner has many methods to get params ComandLineRunner can get params directly

if you custom two runner class, you can use annotation @Order to Specify the order of execution

Upvotes: 0

hakimkal
hakimkal

Reputation: 90

I use this to populate my Default Data. I usually create ApplicationInitializer class that extends CommandLineRunner. I have methods like createDefaultUser(), createDefaultSytemData() etc. This way I do not rely on sql files to populate database for me. :)

Upvotes: 0

I would suggest all time time. It adds a lot of flexibility to your "bootstrapping code".

1) For example, command line runners are spring @Beans, so you can activate/deactivate them at run-time.

2) You can use them in an ordered fashion by appending the @Order annotation

3) You can unit test them just like regular classes

4) You can inject dependencies into them. Each runner can then have its own dependencies.

All of the above are more difficult, if not impossible to achieve if you add all your bootstrapping logic in the main() method of the Spring Application class.

Hope my answer helps, Cheers

Upvotes: 1

Pedro Galvao
Pedro Galvao

Reputation: 31

In simple cases, there is no difference.

But if the code need to access features provided by spring, such as ioc or only interface repositories/services, you need to wait for the complete application startup. And the call of the overrided run method after completion is garanteed.

Besides, CommandLineRunner has other advantages:

  • Can be implemented multiple times
  • The capability to start any scheduler or log any message before application starts to run

Upvotes: 3

Arambh Gaur
Arambh Gaur

Reputation: 26

I encountered a scenario where i had to keep a certain data from the db loaded into the cache before the method was hit from the controller end point the first time. In this scenario it was desirable to hit the method for populating the cache using the run method after extending CommandLineRunner class so that before the application even starts up the data is already available in the cache.

Upvotes: 0

Magnus
Magnus

Reputation: 8300

I haven't found any good reason for using it over just writing code after starting the application.
The only thing I can think of is that the command line runners are called before any SpringApplicationRunListeners have #finished called.

I have seen people use them to perform main application logic, but I think this is an antipattern.
One of the annoying things about doing so is that the application start timer is still running and when the task completes you will see a log entry like Started DemoApplication in 5.626 seconds (JVM running for 0.968).
It's confusing to see a message about your application starting despite, in reality it having just finished.

Upvotes: 0

yxre
yxre

Reputation: 3704

I have used it to decouple code. Instead of placing a bunch of code into main method, the CommandLineRunner lets you distribute it more evenly around the codebase. It really depends on what kind of flags you are passing in and why you need to pass them in. Spring offers a lot of flexibility for you to get the job done in the easiest way.

For a full on command line tool, you can decouple initialization and config a little bit by dividing your code between init and core behavior.

A spring boot server can overwrite configuration based on args passed in from the command line.

Upvotes: 1

Related Questions