Burlando o @Async do Spring

Igor Rudel - Sep 12 - - Dev Community

É comum na construção de aplicações utilizando Spring, utilizarmos a anotação de @EnableAsync para habilitar execuções assíncronas e com o auxílio da @Async sobre os métodos facilmente torná-los assíncronos.

A @Async possui basicamente duas regras de utilização:

  • o método anotado deve ser público
  • o invocador do método não pode ser da mesma classe

No exemplo abaixo, não haverá problemas de compilação, porém o método (apesar de anotado com @Async) não terá a execução como o desejado.

@Slf4j
@Service
@RequiredArgsConstructor
public class HelloService {

    public String get() {
        log.info("Chegou!");
        print();

        return "Ola!";
    }

    @Async
    @SneakyThrows
    public void print() {
        Thread.sleep(Duration.ofSeconds(5));

        log.info("Burlado!");
    }
}
Enter fullscreen mode Exit fullscreen mode

E é muito comum desejarmos que, por ser responsabilidade da classe, o bloco de código que deve ser executado assíncronamente se mantenha nela. Como resolver?

Simples!

Basta criarmos outra classe que auxilie, por exemplo:

@Service
public class AsyncService {

    @Async
    public void run(final Runnable runnable) {
        runnable.run();
    }
}
Enter fullscreen mode Exit fullscreen mode

Fazermos a injeção de dependência dessa bean onde é desejável a execução assíncrona e ainda por cima, poder tornar o método privado.

@Slf4j
@Service
@RequiredArgsConstructor
public class HelloService {

    private final AsyncService asyncService;

    public String get() {
        log.info("Chegou!");

        asyncService.run(this::print);

        return "Ola!";
    }

    @SneakyThrows
    private void print() {
        Thread.sleep(Duration.ofSeconds(5));

        log.info("Burlado!");
    }
}
Enter fullscreen mode Exit fullscreen mode

Esse pequeno exemplo, demonstra a aplicação de vários conceitos e recursos: Inversão de Controle, Injeção de Dependência, SOLID, Design Pattern, Interfaces Funcionais.

. . . . . . . . . . .
Terabox Video Player