2009-12-21 22 views

Respuesta

11

Spring tiene un marco integral de ejecución de tareas. Vea el relevant part of the docs.

Sugiero tener un Spring Bean en su contexto, que, cuando se inicializa, envía su fondo Runnable a un SimpleAsyncTaskExecutor bean. Ese es el enfoque más simple, que puede hacer más complejo y capaz como mejor le parezca.

7

Me gustaría seguir adelante y mirar la documentación de programación de tareas vinculada por skaffman, pero también hay una manera más simple si todo lo que realmente desea hacer es iniciar una cadena de fondo en el momento de inicialización del contexto.

<bean id="myRunnableThingy"> 
    ... 
</bean> 

<bean id="thingyThread" class="java.lang.Thread" init-method="start"> 
    <constructor-arg ref="myRunnableThingy"/> 
</bean> 
+1

¿Funciona bien con el apagado del contexto, etc.? –

+1

Esa es una buena pregunta, el cierre puede ser complicado. Lo ideal es que quieras hacer un 'interrupt()' seguido de un 'join()'. Desafortunadamente, no creo que puedas tener dos 'destroy-method's, así que lo mejor que puedes hacer es' destroy-method = "interrupt" '. Para un comportamiento correcto de apagado, recomendaría implementar [Lifecycle] (http://docs.spring.io/spring/docs/4.1.0.BUILD-SNAPSHOT/javadoc-api/org/springframework/context/Lifecycle.html) o [SmartLifecycle] (http://docs.spring.io/spring/docs/4.1.0.BUILD-SNAPSHOT/javadoc-api/org/springframework/context/SmartLifecycle.html) – washley

+0

Implementar una interfaz de resorte no está en el espíritu de mi respuesta original, por supuesto. – washley

2

Como otra opción, ahora se puede usar la capacidad de programación de Spring. Con Spring 3 o superior, tiene una anotación tipo cron que le permite programar tareas para ejecutar con una simple anotación de un método. También es amigable con el autocableado.

Este ejemplo programa una tarea por cada 2 minutos con una espera inicial (al inicio) de 30 segundos. ¡La próxima tarea se ejecutará 2 minutos después de que el método se complete! Si desea que se ejecute cada 2 minutos exactamente, utilice fixedInterval en su lugar.

@Service 
public class Cron { 
private static Logger log = LoggerFactory.getLogger(Cron.class); 

@Autowired 
private PageService pageService; 

@Scheduled(initialDelay = 30000, fixedDelay=120000) // 2 minutes 
public void cacheRefresh() { 
    log.info("Running cache invalidation task"); 
    try { 

     pageService.evict(); 
    } catch (Exception e) { 
     log.error("cacheRefresh failed: " + e.getMessage()); 
    } 
} 

} 

Asegúrese de añadir también @EnableAsync @EnableScheduling a su clase de aplicación para activar esta función.

Cuestiones relacionadas