Saltar al contenido

El método Spring Boot @Async en el controlador se está ejecutando sincrónicamente

Te recomendamos que revises esta resolución en un entorno controlado antes de pasarlo a producción, saludos.

Solución:

estas llamando al @Async método de otro método en la misma clase. A menos que habilite el modo proxy AspectJ para el @EnableAsync (y proporcione un tejedor, por supuesto) que no funcionará (google “autoinvocación de proxy”). La solución más fácil es poner el @Async método en otro @Bean.

Para todos aquellos que todavía están buscando todos los pasos en @Asnyc explicados de forma sencilla, aquí está la respuesta:

Aquí hay un ejemplo simple con @Async. Siga estos pasos para que @Async funcione en su aplicación Spring Boot:

Paso 1: agregue la anotación @EnableAsync y agregue el bean TaskExecutor a la clase de aplicación.

Ejemplo:

@SpringBootApplication
@EnableAsync
public class AsynchronousSpringBootApplication 

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

    @Bean(name="processExecutor")
    public TaskExecutor workExecutor() 
        ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor();
        threadPoolTaskExecutor.setThreadNamePrefix("Async-");
        threadPoolTaskExecutor.setCorePoolSize(3);
        threadPoolTaskExecutor.setMaxPoolSize(3);
        threadPoolTaskExecutor.setQueueCapacity(600);
        threadPoolTaskExecutor.afterPropertiesSet();
        logger.info("ThreadPoolTaskExecutor set");
        return threadPoolTaskExecutor;
    

    public static void main(String[] args) throws Exception 
  SpringApplication.run(AsynchronousSpringBootApplication.class,args);
 

Paso 2: Agregar método que ejecuta un proceso asíncrono

@Service
public class ProcessServiceImpl implements ProcessService 

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

    @Async("processExecutor")
    @Override
    public void process() 
        logger.info("Received request to process in ProcessServiceImpl.process()");
        try 
            Thread.sleep(15 * 1000);
            logger.info("Processing complete");
        
        catch (InterruptedException ie) 
            logger.error("Error in ProcessServiceImpl.process(): ", ie.getMessage());
        
    

Paso 3: agregue una API en el controlador para ejecutar el procesamiento asíncrono

@Autowired
private ProcessService processService;

@RequestMapping(value = "ping/async", method = RequestMethod.GET)
    public ResponseEntity> async() 
        processService.process();
        Map response = new HashMap<>();
        response.put("message", "Request is under process");
        return new ResponseEntity<>(response, HttpStatus.OK);
    

También he escrito un blog y una aplicación funcional en GitHub con estos pasos. Consulte: http://softwaredevelopercentral.blogspot.com/2017/07/asynchronous-processing-async-in-spring.html

Tuve un problema similar y tenía las anotaciones @Async y @EnableAsync en los beans correctos y aún así el método se ejecutaba sincrónicamente. Después de verificar los registros, apareció una advertencia que decía que tenía más de un bean del tipo ThreadPoolTaskExecutor y ninguno de ellos llamó taskExecutor Asi que…

@Bean(name="taskExecutor")
public ThreadPoolTaskExecutor defaultTaskExecutor() 
     ThreadPoolTaskExecutor pool = new ThreadPoolTaskExecutor();
     //Thread pool configuration
     //...
     return pool;

Consulte http://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/scheduling/concurrent/ThreadPoolTaskExecutor.html para ver la configuración disponible para el grupo de subprocesos.

valoraciones y reseñas

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

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