Start here. This is the direct spoken answer to practice first.
Overview
Different hooks run at different phases; the choice should match what must already exist and whether startup may proceed on failure.
CommandLineRunner and ApplicationRunner run after the application context has been refreshed and can perform application startup work before Boot considers the application ready. Application events expose more specific lifecycle points, while SmartLifecycle suits components that need coordinated start and stop behavior. @PostConstruct is earlier and belongs to initializing one bean, not orchestrating the whole application. I choose the hook from the readiness guarantee the task needs.