tutorial springframework framework java spring

java - springframework - Ejecutar el método al inicio en la primavera



spring framework 5 (10)

Atención, esto solo se recomienda si su método runOnceOnStartup depende de un contexto de primavera completamente inicializado. Por ejemplo: desea llamar a un dao con demarcación de transacción

También puede usar un método programado con fixedDelay establecido muy alto

@Scheduled(fixedDelay = Long.MAX_VALUE) public void runOnceOnStartup() { dosomething(); }

Esto tiene la ventaja de que toda la aplicación está conectada (Transactions, Dao, ...)

visto en Tareas de programación para ejecutarse una vez, utilizando el espacio de nombres de la tarea de primavera

¿Hay alguna característica de Spring 3 para ejecutar algunos métodos cuando la aplicación se inicia por primera vez? Sé que puedo hacer el truco de establecer un método con @Scheduled Annotation y se ejecuta justo después del inicio, pero luego se ejecutará periódicamente.

Gracias.


En Spring 4.2+ ahora puedes simplemente hacer:

@Component class StartupHousekeeper { @EventListener(ContextRefreshedEvent.class) void contextRefreshedEvent() { //do whatever } }


Esto se hace fácilmente con un ApplicationListener . Lo hice funcionar escuchando el ContextRefreshedEvent de Spring:

import org.springframework.context.ApplicationListener; import org.springframework.context.event.ContextRefreshedEvent; import org.springframework.stereotype.Component; @Component public class StartupHousekeeper implements ApplicationListener<ContextRefreshedEvent> { @Override public void onApplicationEvent(final ContextRefreshedEvent event) { // do whatever you need here } }

Los oyentes de aplicaciones se ejecutan sincrónicamente en primavera. Si quiere asegurarse de que su código se ejecuta solo una vez, simplemente mantenga un estado en su componente.

ACTUALIZAR

A partir de Spring 4.2+ también puede usar la anotación @EventListener para observar el ContextRefreshedEvent (gracias a @bphilipnyc para señalar esto):

import org.springframework.context.ApplicationListener; import org.springframework.context.event.ContextRefreshedEvent; import org.springframework.stereotype.Component; @Component public class StartupHousekeeper { @EventListener(ContextRefreshedEvent.class) public void contextRefreshedEvent() { // do whatever you need here } }


Lo que hemos hecho fue extender org.springframework.web.context.ContextLoaderListener para imprimir algo cuando se inicia el contexto.

public class ContextLoaderListener extends org.springframework.web.context.ContextLoaderListener { private static final Logger logger = LoggerFactory.getLogger( ContextLoaderListener.class ); public ContextLoaderListener() { logger.info( "Starting application..." ); } }

Configure la subclase y luego en web.xml :

<listener> <listener-class> com.mycomp.myapp.web.context.ContextLoaderListener </listener-class> </listener>


Para los usuarios de Java 1.8 que reciben una advertencia cuando intentan hacer referencia a la anotación @PostConstruct, terminé utilizando la anotación @Scheduled que puede hacer si ya tiene un trabajo @Scheduled con fixedRate o fixedDelay.

import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; @EnableScheduling @Component public class ScheduledTasks { private static final Logger LOGGER = LoggerFactory.getLogger(ScheduledTasks.class); private static boolean needToRunStartupMethod = true; @Scheduled(fixedRate = 3600000) public void keepAlive() { //log "alive" every hour for sanity checks LOGGER.debug("alive"); if (needToRunStartupMethod) { runOnceOnlyOnStartup(); needToRunStartupMethod = false; } } public void runOnceOnlyOnStartup() { LOGGER.debug("running startup job"); } }



Si desea configurar un bean antes de que su aplicación se ejecute completamente, puede usar @Autowired :

@Autowired private void configureBean(MyBean: bean) { bean.setConfiguration(myConfiguration); }


Si está utilizando Spring-boot, esta es la mejor respuesta.

Siento que @PostConstruct y otras varias interjecciones del ciclo de vida son formas redondas. Esto puede conducir directamente a problemas de tiempo de ejecución o causar defectos menos que obvios debido a eventos inesperados de ciclo de vida de bean / context. ¿Por qué no invocar directamente su bean utilizando Java simple? Todavía invocas al frijol como el ''camino de primavera'' (p. Ej .: a través del proxy AoP de primavera). Y lo mejor de todo, es simple Java, no puede ser más simple que eso. No hay necesidad de escuchas de contexto o programadores extraños.

@SpringBootApplication public class DemoApplication { public static void main(String[] args) { ConfigurableApplicationContext app = SpringApplication.run(DemoApplication.class, args); MyBean myBean = (MyBean)app.getBean("myBean"); myBean.invokeMyEntryPoint(); } }


Si por "inicio de la aplicación" quiere decir "inicio del contexto de la aplicación", entonces sí, hay muchas maneras de hacerlo , la más fácil (para los beans singleton, de todos modos) es anotar su método con @PostConstruct . Eche un vistazo al enlace para ver las otras opciones, pero en resumen son:

  • Métodos anotados con @PostConstruct
  • afterPropertiesSet() según lo definido por la interfaz de devolución de llamada InitializingBean
  • Un método init () configurado personalizado

Técnicamente, estos son ganchos en el ciclo de vida del frijol , en lugar del ciclo de vida del contexto, pero en el 99% de los casos, los dos son equivalentes.

Si necesita enganchar específicamente en el inicio / apagado del contexto, entonces puede implementar la interfaz del Lifecycle en su lugar, pero eso probablemente sea innecesario.


AppStartListener implements ApplicationListener { @Override public void onApplicationEvent(ApplicationEvent event) { if(event instanceof ApplicationReadyEvent){ System.out.print("ciao"); } } }