Tips Spring : [CORE] Ejecución asíncrona de métodos

logo springSpring permite la ejecución asíncrona de métodos de los beans de tal modo que estos métodos se ejecutan en su propio hilo y no bloquean al código que realiza la llamada hasta que finalice la ejecución del método invocado, el cual debe estar en un bean distinto.

Para ejecutar un método en un hilo propio basta con utilizar la anotación @Async disponible desde Spring 3.0

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

@Service
public class AsyncService {

    private static final Logger logger = LoggerFactory.getLogger(AsyncService.class);

    @Async
    public void execute(String msg) throws InterruptedException {
        logger.info("executed: " + msg);
    }
}

También es imprescindible activar la ejecución de los métodos @Async utilizando la anotación @EnableAsync en una clase de configuración.

@EnableAsync
@Configuration
public class DemoApp {

La equivalencia en XML es

<task:annotation-driven />

No es necesario hacer nada más y ahora los métodos @Async se ejecutarán en su propio hilo cuando se invoquen desde otro bean, en nuestro ejemplo cualquiera que no sea AsyncService.

La ejecución es realizada dentro de un Runnable a través de una implementación de TaskExecutor. Spring crea una de forma automática pero generalmente vamos a querer definir y configurar un TaskExecutor según las necesidades de nuestro código. Lo que haremos es instanciar un ThreadPoolTaskExecutor y configurarlo si fuera necesario siguiendo la convención de denominarlo taskExecutor.

@EnableAsync
@Configuration
public class DemoApp {

    @Bean
    public Executor taskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(2);
        executor.setMaxPoolSize(10);
        executor.setQueueCapacity(20);
        executor.initialize();
        return executor;
    }

El anterior bean configura un pool de hilos con un tamaño comprendido entre 2 y 10, y una cola de peticiones de tamaño 20. Es recomendable definir estos parámetros de configuración fuera del código siguiendo el tutorial Ficheros de propiedades en Spring. La configuración equivalente en XML es la siguiente

<bean id="taskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
    <property name="corePoolSize" value="2"/>
    <property name="maxPoolSize" value="10"/>
    <property name="queueCapacity" value="20"/>
</bean>

Se pueden definir varios taskExecutor si fuera necesario y decidir cual utilizar en la propia anotación @Async

    @Bean
    public Executor taskExecutor1() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(1);
        executor.setMaxPoolSize(5);
        executor.initialize();
        return executor;
    }
@Async("taskExecutor1")
public void execute(String msg) throws InterruptedException {
    logger.info("executed: " + msg);
}  

Otros tutoriales relacionados con Spring

Introducción a Spring Boot: Aplicación Web con servicios REST y Spring Data JPA

Spring Boot: Gestión de errores en aplicaciones web y REST

Testing en Spring Boot con JUnit 45. Mockito, MockMvc, REST Assured, bases de datos embebidas

Spring JDBC Template: simplificando el uso de SQL

Persistencia en BD con Spring Data JPA

Ficheros .properties en Spring IoC

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión /  Cambiar )

Google photo

Estás comentando usando tu cuenta de Google. Cerrar sesión /  Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión /  Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión /  Cambiar )

Conectando a %s

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios .