<?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>DEV Community: Eduardo Candido</title>
    <description>The latest articles on DEV Community by Eduardo Candido (@eduardocandido).</description>
    <link>https://dev.to/eduardocandido</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%2F661292%2F335d019b-12de-4aed-8b8e-5c1df8a3a6d9.png</url>
      <title>DEV Community: Eduardo Candido</title>
      <link>https://dev.to/eduardocandido</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/eduardocandido"/>
    <language>en</language>
    <item>
      <title>Processo de seleção de implementações de interfaces no Spring: Entendendo e gerenciando escolhas</title>
      <dc:creator>Eduardo Candido</dc:creator>
      <pubDate>Wed, 26 Apr 2023 20:03:48 +0000</pubDate>
      <link>https://dev.to/eduardocandido/3-maneiras-de-decidir-a-implementacao-a-ser-usada-no-spring-135o</link>
      <guid>https://dev.to/eduardocandido/3-maneiras-de-decidir-a-implementacao-a-ser-usada-no-spring-135o</guid>
      <description>&lt;p&gt;O Spring conta com a feature do IOC container que nos provê várias anotações para que possamos dizer a ele qual método ou classe ele irá gerenciar, essas anotações são importantes para que possamos aplicar conceitos de Design Patterns.&lt;/p&gt;

&lt;p&gt;Por exemplo, em alguns códigos usando Spring é comum encontrarmos uma classe em que se é instanciado uma interface e essa interface contém uma implementação. Como no exemplo abaixo onde a classe &lt;code&gt;CurriculoService&lt;/code&gt; instancia uma interface &lt;code&gt;GeraCurriculo&lt;/code&gt;&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Mas e se acontecesse dessa interface ter duas implementações como o caso abaixo, o que aconteceria? &lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;O Spring lançaria a exceção &lt;strong&gt;NoUniqueBeanDefinitionException&lt;/strong&gt;, por quê? Porque o Spring não seria capaz de determinar qual classe utilizar, não basta dizer ao Spring o que gerenciar, em alguns cenários será necessário dizer a ele qual implementação usar. Para isso separei três maneiras das quais podemos dizer ao Spring qual implementação utilizar.&lt;/p&gt;

&lt;h2&gt;
  
  
  Através da anotação Primary
&lt;/h2&gt;

&lt;p&gt;O simples ato de anotar uma classe com &lt;code&gt;@Primary&lt;/code&gt; irá dar prioridade aquela classe em caso de haver múltiplas implementações ou Beans, por exemplo caso eu queira que a classe &lt;code&gt;GeraCurriculoWordService&lt;/code&gt; fosse chamada toda vez que eu proveja a interface &lt;code&gt;GeraCurriculo&lt;/code&gt; basta apenas isso: &lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h2&gt;
  
  
  Através da anotação @Qualifier
&lt;/h2&gt;

&lt;p&gt;Com essa anotação podemos "nomear" as classes e ao prover uma interface fazer referencia a ela, ainda usando nosso exemplo poderíamos dar prioridade para nossa classe &lt;code&gt;GeraCurriculoPdfService&lt;/code&gt; da seguinte maneira.&lt;/p&gt;

&lt;p&gt;Primeiramente anotamos nossa classe com o &lt;code&gt;@Qualifier&lt;/code&gt; e passamos como parâmetro um identificador, no caso aqui selecionei o próprio nome da classe:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;E por fim, ao provermos nossa interface podemos dizer para usar a implementação em especifico também com a anotação &lt;code&gt;@Qualifier&lt;/code&gt; como no exemplo abaixo:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Note que desta maneira não ficamos preso a uma implementação como na anotação &lt;code&gt;@Primary&lt;/code&gt; com o &lt;code&gt;@Qualifier&lt;/code&gt; podemos ter mais dinamismo ao prover nossa interface e decidir a implementação. Isso não anula a &lt;code&gt;@Primary&lt;/code&gt; mesmo usando qualifiers ainda poderíamos deixar uma implementação como default em caso de não especificarmos nenhuma classe ao provermos a interface.&lt;/p&gt;

&lt;h2&gt;
  
  
  Selecionando a implementação dinamicamente
&lt;/h2&gt;

&lt;p&gt;Vamos supor agora que o usuário que está usando o sistema selecionará o formato de seu currículo, eu preciso ter uma maneira de selecionar a implementação em runtime.&lt;/p&gt;

&lt;p&gt;Para isso podemos usar um dos recursos menos conhecidos do Spring. Como vimos no início do artigo quando temos apenas uma implementação de uma interface o Spring sabe injetar automaticamente essa implementação quando necessário. Mas o Spring também nos dá a capacidade de coletar todos os beans que são implementações de uma interface específica. Assim podemos mapear as implementações para usá-las posteriormente como no exemplo abaixo:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Veja que no construtor da classe passamos como parâmetro uma lista da interface, o Spring no entanto coleta todas as implementações existentes e popula automaticamente essa lista para nós, tornando fácil mapear da maneira como queremos, como foi feito na linha 8 do exemplo acima onde mapeamos o tipo do arquivo que a implementação ligado a própria implementação.&lt;/p&gt;

&lt;p&gt;Para resolvermos o problema citado sobre gerar um currículo dinamicamente poderíamos fazer assim:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Veja que agora a classe &lt;code&gt;CurriculoService&lt;/code&gt; está injetando a classe onde mapeamos a lista de implementações da interface &lt;code&gt;GeraCurriculo&lt;/code&gt;. Então no método da linha 8 &lt;code&gt;getCurriculo&lt;/code&gt; podemos nos preocupar em passar apenas o tipo do arquivo que queremos em vez de termos métodos para cada implementação, na linha 9 selecionamos a implementação que bate com o parâmetro informado e por fim temos acesso a nossa implementação e seus métodos.&lt;/p&gt;

&lt;p&gt;Em resumo as anotações &lt;code&gt;@Primary&lt;/code&gt; e &lt;code&gt;@Qualifier&lt;/code&gt; são úteis quando temos várias implementações e precisamos selecionar uma em específico tendo a anotação &lt;code&gt;@Qualifier&lt;/code&gt; nos permitindo maior especificidade. Vimos também que o Spring oferece uma abordagem mais dinâmica através da coleta de todas as implementações de uma interface, permitindo que você escolha qual implementação usar em tempo de execução. Isso é útil quando você precisa selecionar a implementação com base em informações do usuário ou em condições variáveis.&lt;/p&gt;

&lt;p&gt;Caso queira ver a implementação do código para selecionar uma classe dinamicamente você pode acessar nesse link do &lt;a href="https://github.com/EduardoCandido/laboratorio-blog/tree/main/spring-injecao-dinamica"&gt;github&lt;/a&gt;&lt;/p&gt;

</description>
      <category>java</category>
      <category>spring</category>
      <category>solid</category>
    </item>
  </channel>
</rss>
