Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@danilobatistaqueiroz
Last active May 24, 2019 17:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save danilobatistaqueiroz/0f7a2ff66fcb7e047742a591ed43d0ff to your computer and use it in GitHub Desktop.
Save danilobatistaqueiroz/0f7a2ff66fcb7e047742a591ed43d0ff to your computer and use it in GitHub Desktop.
Tutorial Spring JMS ActiveMQ

Tutorial Spring 4 MVC + JMS + ActiveMQ annotation based

Teremos dois aplicativos java baseados em Spring.
O primeiro é um aplicativo Spring MVC (chamaremos de Web-Shop) onde você pode comprar um produto on-line.
O outro será o aplicativo de Inventário (chamaremos de Order-Inventory), baseado no Spring MVC, implantado como war.

Depois de ter feito seu pedido (significa que o status do pedido é 'criado'),
O aplicativo de loja virtual (Web-Shop) envia este pedido para o aplicativo de Inventário
Ele envia via ActiveMQ Message Broker usando a fila JMS (nomeada como 'order-queue'),

Configuramos um Listener na fila de resposta (nomeado como 'order-response-queue')
para obter a confirmação do pedido a partir do aplicativo de inventário.
O aplicativo de inventário, que estará escutando a fila de pedidos ("order-queue"),
obtém o pedido e o processa.
Em seguida, envia a confirmação na fila de resposta ("order-response-queue").
Ao receber a resposta do pedido, o Web-shop atualiza o status do pedido no repositório.

Em Resumo:
Web-Shop envia pedido -> usando 'order-queue'
Order-Inventory <- escuta 'order-queue'
Order-Inventory recebe o pedido, processa, retorna
Order-Inventory envia a confirmação -> usando 'order-response-queue'
Web-Shop escuta <- 'order-response-queue'
Web-Shop recebe a confirmação e atualiza o status do pedido

Fazendo os downloads:

Baixe o ActiveMQ Classic em [https://activemq.apache.org/components/classic/download/]
Baixe o JDK 8 em [https://www.oracle.com/technetwork/java/javase/downloads/java-archive-downloads-javase7-521261.html]

Configurando o ambiente:

Descompacte o ActiveMQ numa pasta.

Vamos configurar as variáveis de ambiente para linux, ou para git bash para windows

Irei fazer de um modo portável, crie um arquivo de configuração: (setenv.sh)
e coloque o conteúdo:

export JAVA_HOME=/f/java/jdk8
export TOMCAT_HOME=/f/java/apache/tomcat
export ACTIVEMQ_HOME=/f/java/apache/activemq
export PATH=$PATH;$JAVA_HOME/bin;$ACTIVEMQ_HOME/bin;$TOMCAT_HOME/bin

Agora executamos o arquivo com o comando: $ . ./setenv.sh

Vamos iniciar o ActiveMQ: $ ./activemq start

Entre no browser em: http://localhost:8161/admin/
Entre com o usuário e senha: admin e admin

Obs: eu tive problema com a porta 5672, então mudei a porta amqp de 5672 para 5676.
isso aconteceu por que o meu ERLang Server estava rodando nessa porta também.
se for necessário, entre em %activemq_home%\conf\activemq.xml

tela admin do activemq

1. ConnectionFactory:
Para conectar-se a um Message Broker (e enviar e receber mensagens), precisamos configurar um ConnectionFactory.
ActiveMQConnectionFactory é a implementação do ConnectionFactory do Apache.

2. Destino:
Cada mensagem JMS enviada por um aplicativo é endereçada com um Destino.
Os destinos no JMS são como caixas postais em que as mensagens são colocadas até que alguém venha buscá-las.
Existem dois tipos de destino no JMS: fila e tópico. em inglês: queue e topic.

Filas "point-to-point":
As filas são baseadas no modelo de mensagens ponto-a-ponto, no qual as mensagens são enviadas para uma fila.
Cada mensagem tem exatamente um remetente e um receptor.
A mensagem é garantida para ser entregue a apenas um receptor.

Tópicos "publish-subscribe":
Os tópicos são baseados no modelo de publicação-assinatura, no qual as mensagens são enviadas para um tópico.
N assinantes podem ser inscritos em um tópico e, quando uma mensagem chegar, cada um receberá uma cópia dessa mensagem.

3. JmsTemplate:
Configuramos um JmsTemplate que fornece uma abstração, ocultando todas as complexidades da comunicação JMS.
Sem o JmsTemplate, você será forçado a criar conexões/sessões/MessageProducers/MessageConsumers e capturar todas as exceções desagradáveis que puderem ser lançadas.
Com o JmsTemplate, você obtém APIs simples para trabalhar e, por trás dos bastidores ele cuida de todas as complexidades do JMS.
Ele cuida de criar a conexão, obter a sessão e, finalmente, enviar (assim como a recepção síncrona) da mensagem.
Nós estaremos usando o JmsTemplate para enviar a mensagem.
Observe que o JmsTemplate também oferece possibilidades de recebimento de mensagens, mas é síncrono (ele bloqueia o aplicativo de escuta) e geralmente não é preferido quando a comunicação assíncrona é possível.

4. Listeners de mensagens:
Ainda precisamos fazer a configuração para a escuta de mensagens no destino.
Poderíamos ter usado a interface padrão javax.jms.MessageListener, mas o Spring fornece a possibilidade de configurar listeners usando POJOs simples, sem implementar uma interface.
Para usar isso:

    1. Anote um método POJO com @JmsListener do Spring.
    1. Configure um message-listener-container (usando JmsListenerContainerFactory):
      Que escuta em um destino (pode ser aquele usado com @JmsListener) e quando qualquer mensagem chega nesse destino, ele recupera essa mensagem e passa para o bean anotado com @JmsListener para esse destino.
    1. Use @EnableJms, que permite a detecção de anotações JmsListener em qualquer bean gerenciado pelo Spring no container.

DefaultJmsListenerContainerFactory é uma implementação de JmsListenerContainerFactory para construir um DefaultMessageListenerContainer habitual.
Você pode configurar diversas propriedades.
No mínimo, precisa de uma fábrica de conexões.
Além disso, especificamos a simultaneidade (número máximo de usuários / consumidores simultâneos) usando setConcurrency (“lower-upper”).
Você também pode usar setConcurrency (“upper”), o que significa que o menor será 1.

Nota: A Configuração de Mensagens para a Inventory Application é exatamente igual a esta, com a fila sendo invertida:
o pedido será recebido na fila de pedidos e a resposta será enviada para a file pedido-resposta.

Abaixo está um passo-a-passo das configurações cruciais para a configuração da mensageria:

configure as duas bibliotecas, uma para o spring tratar jms: spring-jms e a outra para o active-mq: activemq-spring
springmq-1-pom

Configure o Spring para entender as classes de configuração: MessagingConfiguration e MessagingListnerConfiguration
springmq-2

Configure os Beans para depois serem injetados, a connectionFactory, e o jmsTemplate
A connectionFactory basicamente informa o endereço do servidor activemq.
Já o jmsTemplate vem configurando a fila.
springmq-3

Na classe MessagingListenerConfiguration usa-se a annotation @EnableJms e injeta a connectionFactory.
E também cria-se um Bean com o jmsListenerContainerFactory informando a quantidade de usuário concorrentes.
springmq-4

Configura-se um @JmsListener com a fila que irá escutar.
Nesse método receiveMessage chama-se dentro do serviço o MessageSender.
springmq-5

O MessageSender executa o sendMessage para enviar para o servidor ActiveMQ
springmq-6

Na classe MessageSender injeta-se o jmsTemplate que tem o método send.
Ele cria a mensagem com o objeto CreateMessage, executa o método createMessage, e utiliza a session do activeMQ.
springmq-7

Foi utilizado o método createObjectMessage da session do jms, visto que estamos serializando um objeto java.
Não fiz usando Json por falta de tempo, mas prefiro serializar em json em texto, e gravar com createTextMessage.
Assim, a mensagem fica independente de linguagem (usando o protocolo AMQP) e fica mais fácil gerenciar também, é possível ver as mensagem e ler nos consoles dos MQ servers.
Outros métodos são: c reateTextMessage para enviar um texto,
createStreamMessage para enviar stream de tipos primitivos do java,
createMapMessage para enviar pares de nomes-valores,
createBytesMessage para enviar uma mensagem contendo bytes.

tela

tela1

Vamos simular primeiro o envio da mensagem, deixar pendente, e depois subir o projeto Order-Inventory para consumir a mensagem:

visite: http://localhost:8080/Spring4MVCJmsActiveMQExample/

Primeiro, sem o deploy do projeto Order-Inventory:
deploys1

Entramos no sistema e criamos uma mensagem (um pedido):
tela2

tela3

Agora o "Café" está pendente, vamos fazer o deploy da aplicação Order-Iventory para que o pedido seja processado:
antesdodeploy

depoisdodeploy

depoisdodeploy2

No admin do ActiveMQ, veremos os pedidos que foram enviados para a fila (queue) e processados:
queues_admin


código fonte no meu repositório:
https://github.com/danilobatistaqueiroz/ActiveMQ_SpringMVC_JMS

referência:
http://websystique.com/springmvc/spring-4-mvc-jms-activemq-annotation-based-example/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment