Ejecutando código después de que se inicie Spring Boot

Quiero ejecutar el código después de que mi aplicación Spring-boot comience a monitorear un directorio para ver los cambios.

He intentado ejecutar un nuevo hilo, pero los servicios de @Autowired no se han establecido en ese momento.

He podido encontrar ApplicationPreparedEvent , que se dispara antes de que se @Autowired anotaciones @Autowired . Idealmente, me gustaría que el evento se active una vez que la aplicación esté lista para procesar solicitudes http.

¿Hay un mejor evento para usar, o una mejor forma de ejecutar el código después de que la aplicación esté activa en Spring-boot ?

Tratar:

 @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 } } 

Es tan simple como esto:

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

Probado en la versión 1.5.1.RELEASE

¿Por qué no simplemente crear un bean que inicie su monitor en la inicialización, algo así como:

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

no se llamará al método init hasta que se realice cualquier autoenvío para el bean.

¿Has probado 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; } } 

Código de: http://blog.netgloo.com/2014/11/13/run-code-at-spring-boot-startup/

Esto es lo que la documentación menciona sobre los eventos de inicio:

Los eventos de la aplicación se envían en el siguiente orden, a medida que se ejecuta su aplicación:

Un evento ApplicationStartedEvent se envía al inicio de una ejecución, pero antes de cualquier procesamiento, excepto el registro de oyentes e inicializadores.

Un evento ApplicationEnvironmentPreparedEvent se envía cuando se conoce el entorno que se utilizará en el contexto, pero antes de que se cree el contexto.

Un evento ApplicationPreparedEvent se envía justo antes de que se inicie la actualización, pero después de que se hayan cargado las definiciones de bean.

Se envía un ApplicationReadyEvent después de la actualización y las devoluciones de llamada relacionadas se han procesado para indicar que la aplicación está lista para atender las solicitudes.

Se envía un evento ApplicationFailedEvent si hay una excepción al inicio.

El modo “Spring Boot” es usar un CommandLineRunner . Simplemente agregue frijoles de ese tipo y estará listo para comenzar. En Spring 4.1 (Boot 1.2) también hay un SmartInitializingBean que recibe una callback después de que todo se haya inicializado. Y está SmartLifecycle (desde Spring 3).

Puedes extender una clase usando ApplicationRunner , anular el método run() y agregar el código allí.

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

Con la configuración de spring:

 @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 realmente solo es útil si la tarea que desea realizar no es un requisito para la operación correcta del servidor. Iniciar una tarea asíncrona para monitorear algo en busca de cambios es un buen ejemplo.

Si, sin embargo, su servidor está en un estado ‘no listo’ hasta que la tarea se complete, entonces es mejor implementar SmartInitializingSingleton porque obtendrá la callback antes de que se abra su puerto REST y su servidor esté abierto para los negocios.

No se @PostConstruct tentado de utilizar @PostConstruct para tareas que solo deberían ocurrir una vez. Recibirás una sorpresa grosera cuando notes que se la llama varias veces …

Use un SmartInitializingSingleton bean en la spring> 4.1

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

Como alternativa, se puede implementar un bean CommandLineRunner o anotar un método de bean con @PostConstruct .

Proporcionando un ejemplo para la respuesta de Dave Syer, que funcionó a las mil maravillas:

 @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)); } }