Esecuzione del codice dopo l’avvio di Spring Boot

Voglio eseguire il codice dopo che la mia app di avvio a molla inizia a monitorare una directory per le modifiche.

Ho provato a eseguire un nuovo thread ma i servizi @Autowired non sono stati impostati in quel punto.

Sono stato in grado di trovare ApplicationPreparedEvent , che si @Autowired prima che vengano impostate le annotazioni @Autowired . Idealmente, mi piacerebbe che l’evento si accendesse una volta che l’applicazione è pronta per elaborare le richieste http.

C’è un evento migliore da usare, o un modo migliore di eseguire il codice dopo che l’applicazione è in diretta in spring-boot ?

Provare:

 @Configuration @EnableAutoConfiguration @ComponentScan public class Application extends SpringBootServletInitializer { @SuppressWarnings("resource") public static void main(final String[] args) { ConfigurableApplicationContext context = SpringApplication.run(Application.class, args); context.getBean(Table.class).fillWithTestdata(); // <-- here } } 

È così semplice:

 @EventListener(ApplicationReadyEvent.class) public void doSomethingAfterStartup() { System.out.println("hello world, I have just started up"); } 

Testato sulla versione 1.5.1.RELEASE

Perché non creare semplicemente un bean che avvia il monitor durante l’inizializzazione, qualcosa del tipo:

 @Component public class Monitor { @Autowired private SomeService service @PostConstruct public void init(){ // start your monitoring in here } } 

il metodo init non verrà chiamato fino a quando non viene eseguito alcun autowiring per il bean.

Hai provato ApplicationReadyEvent?

 @Component public class ApplicationStartup implements ApplicationListener { /** * This event is executed as late as conceivably possible to indicate that * the application is ready to service requests. */ @Override public void onApplicationEvent(final ApplicationReadyEvent event) { // here your code ... return; } } 

Codice da: http://blog.netgloo.com/2014/11/13/run-code-at-spring-boot-startup/

Questo è ciò che la documentazione menziona sugli eventi di avvio:

Gli eventi delle applicazioni vengono inviati nell’ordine seguente, mentre l’applicazione viene eseguita:

Un ApplicationStartedEvent viene inviato all’inizio di una corsa, ma prima di qualsiasi elaborazione tranne la registrazione di listener e inizializzatori.

Un ApplicationEnvironmentPreparedEvent viene inviato quando l’ambiente da utilizzare nel contesto è noto, ma prima che venga creato il contesto.

Un ApplicationPreparedEvent viene inviato appena prima dell’avvio dell’aggiornamento, ma dopo che le definizioni del bean sono state caricate.

Un ApplicationReadyEvent viene inviato dopo l’aggiornamento e tutte le richiamate correlate sono state elaborate per indicare che l’applicazione è pronta per le richieste di assistenza.

Un ApplicationFailedEvent viene inviato se c’è un’eccezione all’avvio.

Il modo “Spring Boot” è usare CommandLineRunner . Basta aggiungere fagioli di quel tipo e sei a posto. In Spring 4.1 (Boot 1.2) c’è anche una SmartInitializingBean che ottiene una richiamata dopo che tutto è stato inizializzato. E c’è SmartLifecycle (dalla spring 3).

È ansible estendere una class utilizzando ApplicationRunner , sovrascrivere il metodo run() e aggiungere il codice lì.

 import org.springframework.boot.ApplicationRunner; @Component public class ServerInitializer implements ApplicationRunner { @Override public void run(ApplicationArguments applicationArguments) throws Exception { //code goes here } } 

Con la configurazione della molla:

 @Configuration public class ProjectConfiguration { private static final Logger log = LoggerFactory.getLogger(ProjectConfiguration.class); @EventListener(ApplicationReadyEvent.class) public void doSomethingAfterStartup() { log.info("hello world, I have just started up"); } } 

ApplicationReadyEvent è davvero utile solo se l’attività che si desidera eseguire non è un requisito per il corretto funzionamento del server. L’avvio di un’attività asincrona per monitorare qualcosa per le modifiche è un buon esempio.

Se, tuttavia, il server si trova in uno stato “non pronto” fino a quando l’attività non è completata, è meglio implementare SmartInitializingSingleton perché si riceverà la richiamata prima che la porta REST sia stata aperta e il server sia aperto per la propria attività.

Non essere tentato di usare @PostConstruct per compiti che dovrebbero accadere solo una volta. Avrai una scortese sorpresa quando ti accorgi di essere chiamata più volte …

Utilizzare un bean SmartInitializingSingleton in spring> 4.1

 @Bean public SmartInitializingSingleton importProcessor() { return () -> { doStuff(); }; } 

In alternativa, un bean CommandLineRunner può essere implementato o annotando un metodo bean con @PostConstruct .

Fornire un esempio per la risposta di Dave Syer, che ha funzionato come un fascino:

 @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("Application started with command-line arguments: {} . \n To kill this application, press Ctrl + C.", Arrays.toString(args)); } }