I have a process which is an infinite loop:
public class MyProcess {
public void start() {
while (true) {
//process
}
}
}
When I started using Spring Boot, my first approach was to get the bean from the context after the application had started and manually start the process:
@SpringBootApplication
public class MyApplication {
public static void main(String[] args) {
ApplicationContext applicationContext = SpringApplication.run(MyApplication.class, args);
MyProcess myProcess = applicationContext.getBean(MyProcess.class);
myProcess.start();
}
}
This worked but did not seem like the right way of doing it, so I implemented a CommandLineRunner
:
@Component
public class MyRunner implements CommandLineRunner {
@Autowired
private MyProcess myProcess;
@Override
public void run(String... args) {
this.myProcess.start();
}
}
This is almost the same as before, but here the SpringApplication#run
call never actually finishes, which seems also wrong. Am I correct to think that?
I then tried to manage this on my own with an Executor
, but in order to catch any Exception
I had to call Future#get
which resulted in the same blocking state.
Instead of this, I am now using an @Async
annotation on the CommandLineRunner#run
method.
This seems to be the best solution as the application finishes starting after the task has also been started. Any Exception
will be picked up and logged, but the backing Executor
created by Sprint prevents the application from shutting down.
I assume there is a way of asking Spring to terminate the Executor
so that the entire application can exit since I am managing it externally with Supervisor.
Is this the correct approach or am I missing a step? Should the application be independent and restart the process after a failure?