“O objetivo da Aspect Oriented Programming (AOP), é retirar o código conhecido como: emaranhado, intrusivo e muitas vezes, replicado em diversos locais do sistema, centralizando-os, tornando os interesses transversais modularizados na aplicação. O código no qual a AOP propõe-se a manter, não faz parte do domínio do sistema. Portanto, é considerado um requisito sistêmico, como: Auditoria, Controle de Falhas, etc. Assim, a AOP visa consequentemente reforçar o conceito de coesão da Orientação a Objetos (OO). Ao conseguirmos extrair a porção de código não inerente ao domínio do sistema, teremos códigos legíveis, de fácil manutenção, podendo ser reutilizado, e por fim coeso.” – Introdução a AOP em DevMedia
Recentemente tive a necessidade de adicionar logs para capturar exceptions não tratadas em todos endpoints de um projeto, porém, como desenvolvedor, inserir manualmente tratativas de exceptions e logs em diversas classes me pareceu muito custoso e de certa forma ‘errado’, pois a necessidade em sí era apenas capturar em log as exceptions, não deveria realizar nenhum tipo de tratativa específica para elas.
O AOP me atendeu perfeitamente, pude criar uma classe totalmente desacoplada dos endpoints e inserir as configurações corretas para conseguir interceptar essas exceptions e logar com precisão o erro e a entrada da requisição.
Para isso usei a notação @Aspect
em uma aplicação utilizando o Spring Boot, essa notação em uma classe a torna apta a interceptar e tratar recursos do aspectj. O segredo para capturar as exceptions por AOP é a notação AfterThrowing
que intercepta de fato os métodos que disparam quaisquer Throwable de acordo com a expressão configurada na notação, no caso, configurei para ler todos os métodos do package de meus controllers. A idéia não é mostrar como o AOP funciona aqui, porém, através do JoinPoint, conseguimos recuperar a requisição de fato, convertê-la para String e realizar o log tão desejado em quaisquer endpoint que dispare um Throwable. Veja:
Nota: utilizei a ConditionalOnExpression
para que possa habilitar/desabilitar a trataiva por profiles ou envs definidas na application.properties
Referências:
- https://stackoverflow.com/questions/33744875/spring-boot-how-to-log-all-requests-and-responses-with-exceptions-in-single-pl
- https://www.devmedia.com.br/introducao-a-aop/15596
- https://gist.github.com/gbzarelli/629288f1b8fa60861df373197149e497#file-endpointaspectloggerconfiguration-java