Currently, I am trying to use the CommandLineRunner
along with the ConfigurableApplicationContext
to run a spring boot application both as a web application by default and as a standalone command line application on demand (via command line parameters of some sort). I am struggling figuring out how to solely run this as a console application when program arguments are supplied. Please any suggestions would help.
I had the same requirement. This is how I was able to achieve it:
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplicationBuilder app = new SpringApplicationBuilder(Application.class);
if (args.length == 0) { // This can be any condition you want
app.web(WebApplicationType.SERVLET);
} else {
app.web(WebApplicationType.NONE);
}
app.run(args);
}
}
And this is a console application runner.
@Component
@ConditionalOnNotWebApplication
public class ConsoleApplication implements CommandLineRunner {
@Override
public void run(String... args) {
System.out.println("************************** CONSOLE APP *********************************");
}
}
When you build your bootJar
, you can run application as Web app using
java -jar app.jar
and as a command line app using java -jar app.jar anything #based on the condition you specified
.
Hope this helps.
EDIT:
A better way to achieve this is changing Application.java as following and keeping ConsoleApplication.java as shown above.
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
and then running your bootJar
with java -jar -Dspring.main.web-application-type=NONE app.jar
will run the application as console application. And not passing any spring.main.web-application-type
will run as a web application.
The CommandLineRunner
interface provides a useful way of picking up command line arguments once the application has started, but it won’t help change the nature of the application. As you’ve probably discovered, the application will probably not exit since it thinks it needs to handle incoming web requests.
The approach you’ve taken in your main method looks sensible to me. You need to tell Spring Boot that it isn’t a web application, and therefor shouldn’t hang around listening for incoming requests once it’s been started.
I’d do something like this:
public static void main(String[] args) {
SpringApplication application = new SpringApplication(AutoDbServiceApplication.class);
application.setWeb(ObjectUtils.isEmpty(args);
application.run(args);
}
That should start the application in the correct mode. Then you can use a CommandLineRunner
bean in the same way as you currently do. You might also want to look at ApplicationRunner
which has a slightly better API:
@Component
public class AutoDbApplicationRunner implements ApplicationRunner {
public void run(ApplicationArguments args) {
if (ObjectUtils.isEmpty(args.getSourceArgs)) {
return; // Regular web application
}
// Do something with the args.
if (args.containsOption(“foo”)) {
// …
}
}
}
If you really don’t want the AutoDbApplicationRunner
bean to even be created you could look at setting a profile in the main method that you could use later (see SpringApplication.setAdditionalProfiles
).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With