There are multiple ways this can be done.
First, simple one-liner solution is to create and start a new thread;
@PostConstruct
public void performStateChecks() {
new Thread(() -> { throw new RuntimeException("test"); }).start();
}
The thrown exception only interrupts the separate thread and doesn't block or prevent the application startup. This is useful if you are not interested in result or outcome of the task. Note this is not recommended as it starts separate thread outside spring managed context.
Second is to use executor service and submit a task to it. Spring provides a default ThreadPoolTaskExecutor
which can be used to submit the tasks. This will allow you to have access to the future object of the task and do something with it later on;
private final ThreadPoolTaskExecutor executor; // inject via constructor
@PostConstruct
public void performStateChecks() {
Future<?> future = executor.submit(() -> {
throw new RuntimeException("test");
});
// do something with the future later on
}
If you have multiple such methods and requirements for various services/classes etc then create a new AsyncService class to do the actual work and annotate those methods with @Async
. inject the AsyncService
wherever you need via constructor and then call the required method;
@EnableAsync
@Component
public class AsyncService {
@Async
public void doActualTest() {
throw new RuntimeException("test");
}
}
Then use it like this;
private final AsyncService asyncService; // make sure to inject this via constructor
@PostConstruct
public void performStateChecks() {
asyncService.doActualTest();
}