Physical Address
304 North Cardinal St.
Dorchester Center, MA 02124
Physical Address
304 North Cardinal St.
Dorchester Center, MA 02124
Criar eventos é uma forma bem interessante de desacoplar componentes dentro de uma aplicação, hoje em dia usamos várias ferramentas que acabam desacoplando aplicações inteiras que precisam se comunicar de forma assíncrona, mas e quando nós precisamos fazer isso em uma escala menor? Como desacoplamos componentes dentro de uma mesma aplicação?
Bom quando estamos usando um framework poderoso como o Spring temos isso dentro do próprio ecossistema, e não há a necessidade de instalar bibliotecas adicionais.
Nesse tutorial vamos ensinar de uma maneira bem prática, como fazer a implementação de maneira simples.
Para essa implementação vamos precisar criar basicamente 3 classes, uma classe que vai servir como nosso evento, uma para publicar o evento e outra que vai ser responsável por escutar os eventos publicados, o bom é que o spring já traz para nós interfaces que nos ajudam com essas implementações.
Vamos criar um classe que vai representar nosso evento propriamente dito, nela fique a vontade para colocar os atributos e métodos que desejar, assim como nomeá-la da forma que preferir, aqui nós vamos dar o nome de CustomEvent para ficar genérico e teremos apenas um atributo que será uma mensagem do tipo texto mesmo.
import org.springframework.context.ApplicationEvent;
public class CustomEvent extends ApplicationEvent {
private String message;
public CustomEvent(Object source, String message) {
super(source);
this.message = message;
}
public String getMessage() {
return message;
}
}
JavaVeja que a implementação é bem simples, só precisamos estender a classe abstrata AppllicationEvent presente no próprio framework, e sobrescrever o construtor padrão.
Criamos o atributo message, para trafegar a informação que desejamos, também criamos um método get para que seja possível recuperar essa informação.
Agora que já temos nosso evento precisamos criar o responsável por escultar esse quando o mesmo for publicado, para isso vamos criar uma classe que será anotada com @Component
e @EventListener
, essas são duas anotações padrões do Spring boot e elas que vão permitir com que o método da nossa classe receba a informação no momento em que ela for publicada.
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
@Component
public class CustomEventListener {
@EventListener
public void onMessage(CustomEvent event) {
System.out.println("Message received: " + event.getMessage());
}
}
JavaVeja que nomeamos a nossa classe como CustomEventListener, mas lembrando que isso não é obrigatório apenas seguimos um padrão para que outros desenvolvedores que venham a dar manutenção no código saiba associar facilmente a sua funcionalidade.
A implementação dessa classe é simples veja que criarmos um método com a assinatura que recebe o nosso evento, e anotamos ele com @EventListener
somente isso faz com que todas as publicações envolvendo nosso evento sejam escutadas por esse método.
Também é necessário anotar a classe com @Component
para que o Spring possa registrar esse bean no inicio da aplicação e ficar disponível.
Essa classe será a responsável por publicar o evento, e sua implementação também é bem simples, bastando apenas usar a implementação da classe ApplicationEventPublisher que o próprio spring boot nos entrega.
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;
@Service
public class CustomEventPublisher {
@Autowired
private ApplicationEventPublisher publisher;
public void publish(String message) {
CustomEvent event = new CustomEvent(this, message);
publisher.publishEvent(event);
}
}
JavaVeja que estamos utilizando uma instancia da ApplicationEventPublisher
que está sendo injetada pelo próprio Spring boot, através da anotação @Autowired
, se você não conhece as anotações do Spring temos um artigo explicando cada uma das principais anotações.
No método publish estamos recebendo a mensagem, construindo nosso evento, e utilizando o método publishEvent, tão simples quanto isso.
Para testar o correto funcionamento, se estamos conseguindo enviar e escutar o evento, vamos criar uma outra classe que nada mais é que um controller, para recebermos a informação que queremos repassar para o evento via endpoint.
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/event")
public class EventController {
@Autowired
private CustomEventPublisher publisher;
@PostMapping
public void onEvent(@RequestBody String message) {
publisher.publish(message);
}
}
JavaEssa implementação é bem simples, e só está servindo para gente conseguir testar o funcionamento de uma forma prática.
Agora para testar de fato levante a aplicação e tente enviar uma requisição post com alguma ferramenta de requisições rest (Ex. Postman, Insominia ou o Curl pelo terminal).
curl --request POST \
--url http://localhost:8080/event \
--header 'Content-Type: text/plain' \
--data 'Aprendi no Artefato X'
Terminalwget --quiet \
--method POST \
--header 'Content-Type: text/plain' \
--body-data 'Aprendi no Artefato X' \
--output-document \
- http://localhost:8080/event
TerminalComo demonstrado o próprio Spring já nos entrega a maior parte da implementação, ficando a nosso cargo apenas personalizar o que queremos e adequar a ferramenta a nossa regra de negócio.
Essa é uma excelente oportunidade para desacoplar a comunicação entre componentes internos da sua aplicação, tornando as responsabilidades segregadas, e facilitando a implementação de testes unitários, assim como a manutenção e a evolução do próprio sistema.