<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Marcelo Mendes</title>
    <description>The latest articles on Forem by Marcelo Mendes (@marcelovmendes).</description>
    <link>https://forem.com/marcelovmendes</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1291404%2Fda84842a-04fa-41df-b4db-9e5b1e6fec09.jpeg</url>
      <title>Forem: Marcelo Mendes</title>
      <link>https://forem.com/marcelovmendes</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/marcelovmendes"/>
    <language>en</language>
    <item>
      <title>Criando service discovery com spring cloud gateway e eureka</title>
      <dc:creator>Marcelo Mendes</dc:creator>
      <pubDate>Mon, 10 Feb 2025 16:31:15 +0000</pubDate>
      <link>https://forem.com/marcelovmendes/criando-service-discovery-com-spring-cloud-gateway-e-eureka-363f</link>
      <guid>https://forem.com/marcelovmendes/criando-service-discovery-com-spring-cloud-gateway-e-eureka-363f</guid>
      <description></description>
      <category>spring</category>
      <category>microservices</category>
    </item>
    <item>
      <title>Criando Service Discovery com Spring Cloud Gateway e Netflix Eureka</title>
      <dc:creator>Marcelo Mendes</dc:creator>
      <pubDate>Mon, 10 Feb 2025 00:41:04 +0000</pubDate>
      <link>https://forem.com/marcelovmendes/criando-service-discovery-com-spring-cloud-gateway-e-eureka-158h</link>
      <guid>https://forem.com/marcelovmendes/criando-service-discovery-com-spring-cloud-gateway-e-eureka-158h</guid>
      <description>&lt;h2&gt;
  
  
  Introdução
&lt;/h2&gt;

&lt;p&gt;Nesse artigo, vamos explorar dois patterns amplamente utilizados em arquiteturas de microsserviços: &lt;strong&gt;Service Discovery&lt;/strong&gt; e &lt;strong&gt;API Gateway&lt;/strong&gt;. Veremos suas utilidades, benefícios e como implementá-los utilizando &lt;strong&gt;Spring Cloud Gateway&lt;/strong&gt; e &lt;strong&gt;Eureka Server&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  O que é um Service Discovery?
&lt;/h2&gt;

&lt;p&gt;Em um ambiente de microsserviços, um cliente pode precisar se comunicar com diversas APIs que rodam em diferentes portas e servidores. Mas o cliente geralmente não sabe os endereços exatos dessas APIs.&lt;/p&gt;

&lt;p&gt;Imagine o seguinte cenário:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0u27ncncrxmm1kzrmycr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0u27ncncrxmm1kzrmycr.png" alt="Diagrama ilustrando um cliente tentando acessar várias APIs sem um Service Discovery" width="800" height="501"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Se não houver alguma forma para descobrir automaticamente os serviços disponíveis, precisaríamos gerenciar manualmente os endereços de cada API. Isso torna a manutenção do sistema mais complexa e suscetível a erros.&lt;/p&gt;

&lt;p&gt;É aí que entra o &lt;strong&gt;Service Discovery&lt;/strong&gt;. Ele age como uma espécie de banco de registro, onde as aplicações ao subirem, se registram nele permitindo que os clientes descubram automaticamente onde eles estão rodando. No ecossistema do Spring, utilizamos o &lt;strong&gt;Eureka Server&lt;/strong&gt; para essa funcionalidade.&lt;/p&gt;

&lt;p&gt;Quando as aplicações são iniciadas, elas se registram no Eureka Server. Assim, qualquer cliente pode consultar o Eureka e descobrir quais serviços estão disponíveis e onde eles estão rodando.&lt;/p&gt;

&lt;p&gt;Com essa abordagem, o &lt;strong&gt;API Gateway&lt;/strong&gt; pode atuar apenas como um roteador, passando para o Eureka a responsabilidade de gerenciar os registros dos serviços:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2b8l2j64s0nunkhpt10h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2b8l2j64s0nunkhpt10h.png" alt="Diagrama mostrando como o Service Discovery facilita a comunicação entre serviços" width="800" height="629"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Implementação
&lt;/h2&gt;

&lt;p&gt;Agora, vamos implementar um Gateway que busca os serviços registrados no Eureka Server. O código completo deste projeto está disponível no repositório no final do artigo.&lt;/p&gt;

&lt;h3&gt;
  
  
  Criando o Eureka Server
&lt;/h3&gt;

&lt;p&gt;O primeiro passo é criar um projeto Spring Boot. Eu utilizei o &lt;strong&gt;Spring Initializr&lt;/strong&gt; mas faça como preferir. Selecionando a dependência &lt;strong&gt;Eureka Server&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7squxkbh2numvf56gt48.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7squxkbh2numvf56gt48.png" alt="Imagem do Spring Initializr configurado para Eureka Server" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Após criar o projeto, abra-o na sua IDE e adicione as seguintes configurações no arquivo &lt;code&gt;application.properties&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight properties"&gt;&lt;code&gt;&lt;span class="py"&gt;server.port&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;8761&lt;/span&gt;
&lt;span class="py"&gt;eureka.client.register-with-eureka&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;false&lt;/span&gt;
&lt;span class="py"&gt;eureka.client.fetch-registry&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;server.port=8761&lt;/code&gt;: Define a porta padrão do Eureka Server.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;eureka.client.register-with-eureka=false&lt;/code&gt;: Como este é o servidor do Eureka, ele não precisa se registrar nele mesmo.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;eureka.client.fetch-registry=false&lt;/code&gt;: Ele não precisa buscar registros, apenas fornecer informações aos clientes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Agora, no arquivo &lt;code&gt;ServiceDiscoveryApplication&lt;/code&gt;, adicionamos a anotação &lt;code&gt;@EnableEurekaServer&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@SpringBootApplication&lt;/span&gt;
&lt;span class="nd"&gt;@EnableEurekaServer&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ServiceDiscoveryApplication&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;SpringApplication&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;ServiceDiscoveryApplication&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agora, ao rodar o projeto, conseguimos visualizar a interface do Eureka Server acessando &lt;code&gt;http://localhost:8761&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsrp0gqe6smww91gkex5m.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsrp0gqe6smww91gkex5m.png" alt="Imagem da interface do Eureka Server" width="800" height="470"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Por enquanto não temos nenhum serviço no registro porque não subimos nenhuma API no Eureka Server.&lt;/p&gt;

&lt;h3&gt;
  
  
  Criando Serviços Cliente (API-01 e API-02)
&lt;/h3&gt;

&lt;p&gt;Vamos criar duas APIs simples (&lt;code&gt;api-01&lt;/code&gt; e &lt;code&gt;api-02&lt;/code&gt;) que serão registradas no Eureka. Para isso, utilizamos o &lt;strong&gt;Spring Initializr&lt;/strong&gt;, adicionando as dependências:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgefx5lcxqgk7v7m7gjm6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgefx5lcxqgk7v7m7gjm6.png" alt="Imagem do Spring Initializr configurado web e Eureka Client" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Eureka Client&lt;/strong&gt; (para registro no Eureka Server)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Spring Web&lt;/strong&gt; (para expor endpoints)&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Configurações
&lt;/h4&gt;

&lt;p&gt;No &lt;code&gt;application.properties&lt;/code&gt; de cada API, adicionamos:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight properties"&gt;&lt;code&gt;&lt;span class="py"&gt;server.port&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;8181  # Ou outra porta para a segunda API&lt;/span&gt;
&lt;span class="py"&gt;eureka.client.service-url.default-zone&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;http://localhost:8761/eureka/&lt;/span&gt;
&lt;span class="py"&gt;eureka.client.register-with-eureka&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;true&lt;/span&gt;
&lt;span class="py"&gt;eureka.client.fetch-registry&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Criando um endpoint de teste
&lt;/h4&gt;

&lt;p&gt;Agora, criamos um controlador simples para expor um endpoint:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@RestController&lt;/span&gt;
&lt;span class="nd"&gt;@RequestMapping&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/api"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;HealthCheckController&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nd"&gt;@GetMapping&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/health"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;healthCheck&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"API-01 está saudável!"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Com isso, ao rodarmos as APIs, elas se registrarão automaticamente no Eureka Server.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj8xewbaujqp5j6kykukw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj8xewbaujqp5j6kykukw.png" alt="Image description" width="800" height="445"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Note que na imagem temos o gateway exposto também, ele será implementado no próximo passo.&lt;/p&gt;

&lt;p&gt;Bom, já criamos o Eureka Server, a api-01 e a api-02. Elas já estão rodando, registradas e podem buscar informações no nosso serviço de descoberta. Agora temos algo parecido com um livro de endereços, onde conseguimos acessar as informações das APIs sem precisar lembrar de cada endereço e porta manualmente.&lt;br&gt;
Mas ainda falta algo. A gente não quer que o cliente precise saber os endereços específicos de cada API, certo? Para resolver isso, usamos um gateway. Ele vai consultar o registro de serviços e passar um único ponto de acesso para os clientes, garantindo que todas as requisições entre microsserviços sejam roteadas de forma transparente.&lt;/p&gt;
&lt;h3&gt;
  
  
  Criando o API Gateway
&lt;/h3&gt;

&lt;p&gt;O próximo passo é criar o &lt;strong&gt;Spring Cloud Gateway&lt;/strong&gt;, que será responsável por rotear as requisições para os serviços registrados no Eureka.&lt;/p&gt;

&lt;p&gt;No &lt;strong&gt;Spring Initializr&lt;/strong&gt;, adicionamos as dependências:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Spring Cloud Gateway&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Eureka Client&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;
  
  
  Configurações do Gateway
&lt;/h4&gt;

&lt;p&gt;No &lt;code&gt;application.properties&lt;/code&gt;, adicionamos:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight properties"&gt;&lt;code&gt;&lt;span class="py"&gt;eureka.client.service-url.default-zone&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;http://localhost:8761/eureka/&lt;/span&gt;
&lt;span class="py"&gt;eureka.client.register-with-eureka&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;true&lt;/span&gt;
&lt;span class="py"&gt;eureka.client.fetch-registry&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;true&lt;/span&gt;

&lt;span class="py"&gt;spring.cloud.gateway.discovery.locator.enabled&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;true&lt;/span&gt;
&lt;span class="py"&gt;spring.cloud.gateway.discovery.locator.lower-case-service-id&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;spring.cloud.gateway.discovery.locator.enabled=true&lt;/code&gt;: Permite que o Gateway descubra automaticamente os serviços registrados no Eureka.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;spring.cloud.gateway.discovery.locator.lower-case-service-id=true&lt;/code&gt;: Garante que os nomes das aplicações sejam tratados em letras minúsculas, tornando as requisições mais legíveis.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Testando a Comunicação
&lt;/h3&gt;

&lt;p&gt;Agora que o Gateway e os serviços estão configurados, podemos testar a comunicação.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Rodamos o Eureka Server&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Rodamos as APIs (&lt;code&gt;api-01&lt;/code&gt; e &lt;code&gt;api-02&lt;/code&gt;)&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Rodamos o API Gateway&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Verificamos o Eureka Server&lt;/strong&gt; (&lt;code&gt;http://localhost:8761&lt;/code&gt;)

&lt;ul&gt;
&lt;li&gt;As APIs devem aparecer como registradas.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Testamos o roteamento&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;http://localhost:8080/api-01/api/health&lt;/code&gt; → Deve retornar: &lt;code&gt;API-01 está saudável!&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;http://localhost:8080/api-02/api/health&lt;/code&gt; → Deve retornar: &lt;code&gt;API-02 está saudável!&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;O Gateway está funcionando corretamente, roteando as requisições para os serviços automaticamente!&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;Com essa implementação, conseguimos:&lt;/p&gt;

&lt;p&gt;✅ Criar um &lt;strong&gt;Eureka Server&lt;/strong&gt; para gerenciar o registro de serviços.&lt;br&gt;
✅ Criar &lt;strong&gt;APIs clientes&lt;/strong&gt; que se registram automaticamente no Eureka.&lt;br&gt;
✅ Configurar um &lt;strong&gt;API Gateway&lt;/strong&gt; que roteia as requisições sem necessidade de mapear manualmente os endpoints.&lt;br&gt;
✅ Facilitar a escalabilidade e manutenção dos serviços.&lt;/p&gt;

&lt;p&gt;Essa abordagem reduz o acoplamento entre os serviços e facilita a comunicação dinâmica entre microsserviços.&lt;/p&gt;

&lt;p&gt;📌 O código completo do projeto pode ser acessado aqui (&lt;a href="https://github.com/Marcelovmendes/service-discovery" rel="noopener noreferrer"&gt;https://github.com/Marcelovmendes/service-discovery&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;Gostou do artigo? Compartilhe e deixe seu comentário! 🚀&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Reflections em Java: Uma Ferramenta Poderosa</title>
      <dc:creator>Marcelo Mendes</dc:creator>
      <pubDate>Fri, 20 Dec 2024 23:41:05 +0000</pubDate>
      <link>https://forem.com/marcelovmendes/reflections-em-java-uma-ferramenta-poderosa-e-seus-cuidados-4m3m</link>
      <guid>https://forem.com/marcelovmendes/reflections-em-java-uma-ferramenta-poderosa-e-seus-cuidados-4m3m</guid>
      <description>&lt;p&gt;Vamos explorar o que é Reflections, seus usos e riscos, e como aplicá-lo na prática.&lt;/p&gt;

&lt;h2&gt;
  
  
  O que é Reflection?
&lt;/h2&gt;

&lt;p&gt;Reflection é uma funcionalidade do Java que permite que o código inspecione e manipule classes, campos, métodos e construtores de objetos, mesmo que sejam privados ou desconhecidos em tempo de compilação.&lt;/p&gt;

&lt;p&gt;Essa habilidade é muito boa para cenários dinâmicos, como ferramentas que interagem com classes desconhecidas ou que dependem de comportamento fora do default. Porém, Reflection deve ser usada com cuidado devido a seus impactos em desempenho e segurança.&lt;/p&gt;




&lt;h2&gt;
  
  
  Quando usar Reflection?
&lt;/h2&gt;

&lt;h4&gt;
  
  
  Frameworks e libs
&lt;/h4&gt;

&lt;p&gt;Muitas libs utilizam Reflection para automatizar tarefas. Por exemplo, o JUnit usa Reflection para localizar e executar métodos de teste automaticamente.&lt;/p&gt;

&lt;h4&gt;
  
  
  Interoperabilidade e extensibilidade
&lt;/h4&gt;

&lt;p&gt;Quando você precisa trabalhar com tipos desconhecidos em tempo de compilação. Um exemplo comum é carregar dinamicamente classes em um sistema modular.&lt;/p&gt;

&lt;h4&gt;
  
  
  Manipulação de objetos externos ou desconhecidos
&lt;/h4&gt;

&lt;p&gt;É útil para acessar métodos ou campos de classes de terceiros que não possuem uma API pública.&lt;/p&gt;

&lt;h4&gt;
  
  
  Criação de ferramentas e depuração
&lt;/h4&gt;

&lt;p&gt;Reflection é frequentemente usada em ferramentas como depuradores, analisadores de código e geradores de código dinâmico.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cuidados ao usar Reflection
&lt;/h2&gt;

&lt;p&gt;Reflection é poderosa, mas traz riscos porque pode quebrar algumas garantias fornecidas pelo compilador e pelo runtime no uso default. Aqui estão os principais riscos:&lt;/p&gt;

&lt;h4&gt;
  
  
  Quebra de encapsulamento
&lt;/h4&gt;

&lt;p&gt;Reflection permite acessar campos e métodos private ou protected, ignorando os modificadores de acesso.&lt;/p&gt;

&lt;h4&gt;
  
  
  Erros em tempo de execução
&lt;/h4&gt;

&lt;p&gt;Ao contrário do uso tradicional, erros de tipos ou métodos inexistentes só aparecem em tempo de execução, isso dificulta a depuração e os testes.&lt;/p&gt;

&lt;h4&gt;
  
  
  Impacto no desempenho
&lt;/h4&gt;

&lt;p&gt;Métodos refletivos, como Method.invoke, têm um overhead maior porque bypassam as ações do compilador. Esse impacto pode ser significativo em aplicações com chamadas frequentes ou alta performance.&lt;/p&gt;




&lt;h2&gt;
  
  
  Ferramentas principais da classe Reflection
&lt;/h2&gt;

&lt;p&gt;O pacote java.lang.reflect oferece várias classes e métodos que tornam possível manipular dinamicamente os elementos de uma classe. Aqui estão algumas das ferramentas mais importantes:&lt;/p&gt;

&lt;h3&gt;
  
  
  Class: O ponto de partida
&lt;/h3&gt;

&lt;p&gt;A classe Class é usada para obter informações e manipular classes. É frequentemente a porta de entrada para outras operações de Reflection.&lt;/p&gt;

&lt;h4&gt;
  
  
  Métodos úteis:
&lt;/h4&gt;

&lt;p&gt;&lt;code&gt;getDeclaredFields()&lt;/code&gt;: Retorna todos os campos declarados na classe.&lt;br&gt;
&lt;code&gt;getDeclaredMethods()&lt;/code&gt;: Retorna todos os métodos declarados na classe.&lt;br&gt;
&lt;code&gt;getDeclaredConstructors()&lt;/code&gt;: Retorna todos os construtores declarados na classe.&lt;br&gt;
&lt;code&gt;getSuperclass()&lt;/code&gt;: Obtém a superclasse da classe.&lt;br&gt;
&lt;code&gt;getInterfaces()&lt;/code&gt;: Retorna as interfaces implementadas pela classe.&lt;/p&gt;




&lt;h2&gt;
  
  
  Na prática
&lt;/h2&gt;

&lt;p&gt;Suponha que você tenha a seguinte entidade Weather (faltou os getters rs):&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpo63vt8xxnp6hgvyrpqd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpo63vt8xxnp6hgvyrpqd.png" alt="Entidade weather que tem varias cidades, um construtor vazio, um construtor com todos args os getters dessas cidades" width="800" height="517"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Essa entidade é um cron atualizada que faz chamadas a uma API externa e salva as temperaturas. Seu objetivo é buscar dinamicamente a temperatura de uma cidade. Veja como fazer isso usando Reflection:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8o45m3p2bndwqjiba4t6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8o45m3p2bndwqjiba4t6.png" alt="o metodo currentTemperature que receb uma string city e utiliza reflections para acessar os getters dinamicamente e retornar o valor de acordo." width="800" height="735"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Fluxo
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Construção do Nome do Método:
&lt;/h4&gt;

&lt;p&gt;O nome do método é criado dinamicamente concatenando "get" com o nome da cidade e "Temperature".&lt;/p&gt;

&lt;h4&gt;
  
  
  Obtenção do Método:
&lt;/h4&gt;

&lt;p&gt;Usamos getDeclaredMethod para obter o método correspondente, que nesse caso são os getters.&lt;/p&gt;

&lt;h4&gt;
  
  
  Invocação do Método:
&lt;/h4&gt;

&lt;p&gt;O método é invocado dinamicamente com invoke, retornando a temperatura.&lt;/p&gt;




&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;Nesse artigo eu espero que vocês consigam entender de modo geral como essa ferramenta funcina no ecossistema Java, permitindo resolver problemas dinâmicos de maneira diferente. Porém, devido à quebra de encapsulamento, impacto no desempenho e dificuldade de depuração, deve ser usada com cuidado.&lt;br&gt;
Entender os cenários adequados para aplicá-la e conhecer seus riscos é essencial para tirar o melhor proveito dessa funcionalidade sem comprometer a manutenção e a segurança do código.&lt;/p&gt;

</description>
      <category>braziliandevs</category>
      <category>java</category>
    </item>
  </channel>
</rss>
