Reputation: 3923
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
Reputation: 897
I mostly use CommandLineRunner to:
Upvotes: 0
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
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
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
Reputation: 11
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
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:
Upvotes: 3
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
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 SpringApplicationRunListener
s 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
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