Tasks anotadas. Rápidas y fáciles con Spring 3.1

Hola a todos. Aquí va un artículo píldora para aquellos que deseen crear tareas lanzadas en background (e.g. recalcular índices, borrar datos temporales, etcétera) usando anotaciones con Spring 3.1. Y para ello nada mejor que un ejemplo. Se presupone que el lector sabe configurar un proyecto con Spring 3.1.

Supongamos que queremos una tarea que imprima en los logs de nuestra aplicación «qué día más bonito hace hoy!» porque nos encontramos tremendamente felices y queremos alegrarle el día al administrador de sistemas. De hecho, queremos alegrárselo tanto que se lo queremos imprimir cada medio segundo (seguro que el encanta tener 120 líneas/minuto para revisar en el log). Para ello, crearemos una clase como la siguiente:

[sourcecode language=java]
@Component
public class MakeMyDayTask {
private static final Logger LOGGER = Logger.getLogger(MakeMyDayTask.class.getName());

@Scheduled(fixedDelay = 500)
public void run() {
// Nivel severe porque así seguro que se ven
LOGGER.severe("qué día más bonito hace hoy!");
}
}
[/sourcecode]

Y nada más. Así de fácil. Bueno, en realidad hay un detalle más, pero es tan tonto que casi no merece la pena indicarlo. Salvo para el que escribe, que nunca fue capaz de saber por qué las tareas no se lanzaban hasta que después de mucho tiempo descubrió que es necesario especificar que las anotaciones de las tareas necesitan ser escaneadas (pensaba que de eso se encargaba automágicamente el elemento «component-scan» de la configuración xml, pero evidentemente no). En fin, para que funcionen las anotaciones de las tareas en background es necesario que el fichero xml encargado de montar el contexto (aunque sólo sea para decir «oye, usa anotaciones») contenga el elemento «annotation-driven» de las tasks. A continuación se muestra un ejemplo del xml correspondiente a la configuración de un servlet de un proyecto que usa Spring MVC:

[sourcecode language=xml]
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:task="http://www.springframework.org/schema/task"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.1.xsd
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task.xsd">

<context:component-scan base-package="paquetería" />

<!– GRACIAS A ESTO BUSCA ANOTACIONES EN LAS TAREAS –>
<task:annotation-driven />

<mvc:annotation-driven />

<mvc:view-controller path="/" view-name="index"/>

<mvc:resources mapping="/resources/**" location="/resources/" />

<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basename" value="classpath:/i18n/messages" />
<property name="cacheSeconds" value="0" />
</bean>

<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/"/>
<property name="suffix" value=".jsp"/>
</bean>

</beans>
[/sourcecode]

Con ese elemento en la configuración y las tareas bajo la paquetería a escanear, las anotaciones funcionarán como la seda. Hay que destacar que a las anotaciones se les pueden inyectar otros objetos existentes en el contexto (con @Autowired o con @Inject, según el gusto).

Termino enlazando con la referencia a spring relativa a las tareas, donde se puede ver por ejemplo cómo configurar la tarea con sintaxis cron o cómo hacer uso de la anotación @Async. Un saludo a todos y que paséis un feliz día.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *