<?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: Thiago Lino</title>
    <description>The latest articles on Forem by Thiago Lino (@thiagolinoz).</description>
    <link>https://forem.com/thiagolinoz</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%2F359712%2Fadf2795c-87c9-40c1-af30-3b0b99a956d8.jpeg</url>
      <title>Forem: Thiago Lino</title>
      <link>https://forem.com/thiagolinoz</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/thiagolinoz"/>
    <language>en</language>
    <item>
      <title>Conhecendo o Kotlin</title>
      <dc:creator>Thiago Lino</dc:creator>
      <pubDate>Tue, 13 Sep 2022 11:18:44 +0000</pubDate>
      <link>https://forem.com/thiagolinoz/conhecendo-o-kotlin-288i</link>
      <guid>https://forem.com/thiagolinoz/conhecendo-o-kotlin-288i</guid>
      <description>&lt;p&gt;Se como eu lhe foi dado o desafio de aprender Kotlin e já trabalhar com a linguagem ou apenas por conhecimento próprio, espero que este post lhe ajude.&lt;/p&gt;

&lt;p&gt;Iniciando pela parte técnica o Kotlin se trata de uma linguagem de &lt;em&gt;tipagem estática&lt;/em&gt;, os tipos das variáveis são checados durante a &lt;strong&gt;compilação&lt;/strong&gt; gerando um erro se houver troca de tipo. Sua tipagem é forte, o que significa que &lt;strong&gt;não&lt;/strong&gt; possui flexibilidade nas operações entre variáveis de tipos diferentes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;val nomeOperario: String = "José"
val horasExtra: Int = 1000
println(nomeOperario + horasExtra) //gera um erro na compilacao
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A declaração de variáveis, como no exemplo acima, usa a palavra chave &lt;em&gt;val&lt;/em&gt; ou &lt;em&gt;var&lt;/em&gt;. A primeira &lt;strong&gt;não&lt;/strong&gt; permite alterar o valor que lhe foi atribuído, equivalente ao final em &lt;em&gt;java&lt;/em&gt;, a última permite que o valor seja alterado após declarado.&lt;/p&gt;

&lt;p&gt;O ponto e vírgula ';' no final da linha de trecho é opcional, porém para aproveitar a sintaxe enxuta da linguagem é &lt;a href="https://kotlinlang.org/docs/coding-conventions.html#semicolons"&gt;indicado não adicionar&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Um detalhe importante é que o Kotlin &lt;strong&gt;exige&lt;/strong&gt; que um valor seja atribuído a variável durante sua declaração.&lt;/p&gt;

&lt;p&gt;A visibilidade default das variáveis é &lt;em&gt;public&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;No Kotlin temos inferência de tipo, porém podemos deixar o valor explícito com dois pontos ':' seguido do tipo.&lt;/p&gt;

&lt;p&gt;E como resultado temos:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;val nomeOperario: String = "José"&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Já que estamos falando de variáveis uma opção interessante para a concatenação de variáveis a &lt;em&gt;String&lt;/em&gt; é a utilização do &lt;em&gt;String template&lt;/em&gt;, basta adicionar um cifrão '$' na frente do nome da variável para a concatenação:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;println("Senhor(a) $nomeOperario ...") // Senhor(a) José ...&lt;/code&gt; &lt;/p&gt;

&lt;p&gt;Para realizar a concatenação com a propriedade de um objeto é similar, porém com o objeto e propriedade entre chaves '{':&lt;/p&gt;

&lt;p&gt;&lt;code&gt;println("Tamanho nome: ${nomeOperario.length}") // Tamanho nome: 4&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Caso necessite escapar caracteres especiais podemos usar o &lt;em&gt;raw Strings&lt;/em&gt;, adicionamos a &lt;em&gt;string&lt;/em&gt; entre um par de 3 aspas duplas:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;val workspace = """/home/dev/workspace"""&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Inclusive podemos utilizar as 3 aspas duplas para ter uma quebra de linha:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;val cargaSemanal = """Fixadas 30 horas semanais com opções:
I. De segunda a sexta com 6(seis) horas diárias"""
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Após esta breve visão geral das variáveis, podemos falar sobre os métodos.&lt;/p&gt;

&lt;p&gt;Para a declaração do método se inicia com a visibilidade do método, quando omissa a default é &lt;em&gt;public&lt;/em&gt;, palavra reservada 'fun' seguido pelo nome do método acompanhado pela abertura e fechamento de parênteses '(', quando houverem parâmetros estes vão entres os parênteses. Caso possua um retorno, dois pontos ':' são adicionados após o parêntese de fechamento seguido pelo tipo do retorno. O retorno quando não especificado é do tipo &lt;em&gt;Unit&lt;/em&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;fun salvarReajusteSalarial(): Boolean {
    //realiza reajuste adequado ao operario
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Os parâmetros dos métodos necessitam terem seus tipos indicados, com o nome do parâmetro acompanhado por dois pontos e seguido pelo seu tipo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;fun logarNotificacao(emailOperario: String, log: Logger): String {
    //loga notificao c sucesso
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O Kotlin nos permite informar labels(named arguments) nos argumentos, e com isto ao passar para o método podemos alterar a ordem.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;logarNotificacao(log = logger, emailOperario = email)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;A &lt;a href="https://kotlinlang.org/docs/coding-conventions.html#named-arguments"&gt;convenção da linguagem&lt;/a&gt; inclusive recomenda o uso de named arguments quando houverem mais de um parâmetro do mesmo tipo ou para parâmetros Booleanos.&lt;/p&gt;

&lt;p&gt;Já que estamos falando de parâmetros, vamos falar dos construtores no Kotlin. A linguagem nos da a opção de dois tipos de construtores.&lt;br&gt;
O primário, que definimos ao lado do nome da classe, no header, onde as parâmetros são declaradas dentro dos parênteses. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;class Operario constructor(nome: String) {/*...*/}&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Caso o construtor não possua anotações ou modificador de visibilidade podemos omitir a palavra chave &lt;em&gt;constructor&lt;/em&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Beneficio(
    val nome: String, 
    val tipo: TipoBeneficio,
    val desconto: Boolean = false
) {
  /*...*/
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No exemplo acima, além do omissão da palavra chave &lt;em&gt;constructor&lt;/em&gt; os parâmetros recebidos pelo construtor já foram declarados como propriedade da classe ao adicionar a palavra chave &lt;em&gt;val&lt;/em&gt;, também é possível utilizar &lt;em&gt;var&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Um detalhe para que a &lt;a href="https://kotlinlang.org/docs/coding-conventions.html#class-headers"&gt;convenção da lingaguem&lt;/a&gt; recomenda uma quebra de linha nos parâmetros, quando houverem muitos, além do parênteses que fecha em uma nova linha. &lt;br&gt;
É possível declarar um valor default, como no exemplo, com a propriedade booleana &lt;em&gt;desconto&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Caso exista alguma lógica que precisa ser realizada no construtor podemos criar um bloco init dentro da classe.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Beneficio(
    val titulo: String, 
    val tipo: TipoBeneficio,
    val desconto: Boolean = false
) {

  init {
    //realiza alguma logica com alguma das propriedades
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Como segunda opção temos o construtor secundário, onde podemos implementar alguma lógica existente dentro de um bloco &lt;em&gt;constructor&lt;/em&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Beneficio() {

  var titulo: String = ""   

  constructor(tituloBeneficio: String) {
    // implementa alguma logica com a propriedade
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O mais comum que vamos ver no dia a dia irá ser o uso do construtor primário.&lt;/p&gt;

&lt;p&gt;E para finalizar, vamos abordar como o Kotlin trabalha com encapsulamento através dos &lt;em&gt;getters&lt;/em&gt; e &lt;em&gt;setters&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Por sua existência implícita não se costuma criar getters e setters no Kotlin. O &lt;em&gt;get&lt;/em&gt; e &lt;em&gt;set&lt;/em&gt; vão possuir as mesmas visibilidades das propriedades a que se referem. &lt;/p&gt;

&lt;p&gt;Porém as visibilidades do &lt;em&gt;get&lt;/em&gt; e &lt;em&gt;set&lt;/em&gt; podem ser customizadas.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; var titulo: String = ""
    private set
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No exemplo acima o &lt;em&gt;get&lt;/em&gt; para &lt;em&gt;titulo&lt;/em&gt;, assim como a propriedade, vão ter uma visibilidade pública, já o &lt;em&gt;set&lt;/em&gt; passou a ser &lt;em&gt;private&lt;/em&gt;. Logo pode ser lida por qualquer um, porém apenas modificada dentro da classe.&lt;/p&gt;

&lt;p&gt;E para os casos em que precisamos adicionar lógica aos &lt;em&gt;get&lt;/em&gt; e &lt;em&gt;set&lt;/em&gt;?&lt;br&gt;
O Kotlin nos permite customizar isto também:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var titulo: String = ""
  set(tituloBeneficio) {
    if(tituloBeneficio.length &amp;lt;= tamanhoMaximoPermitido) {
      field = tituloBeneficio
    }
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No exemplo temos a customização de uma lógica ao &lt;em&gt;set&lt;/em&gt; da propriedade &lt;em&gt;titulo&lt;/em&gt;. O interessante de notar aqui é a palavra chave &lt;em&gt;field&lt;/em&gt;, que se refere a propriedade em questão, &lt;em&gt;titulo&lt;/em&gt;.&lt;br&gt;
Portanto, no exemplo temos uma validação da quantidade de caracteres do valor recebido(&lt;em&gt;tituloBeneficio&lt;/em&gt;), para então a atribuição a propriedade &lt;em&gt;titulo&lt;/em&gt; representado pela palavra chave &lt;em&gt;field&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Concluo aqui este post onde me preocupei em trazer pontos do Kotlin diferentes da maioria das linguagens. A linguagem traz outros pontos interessantes e de destaque, porém creio ser melhor abordar em outras postagens.&lt;/p&gt;

&lt;p&gt;Obrigado pelo seu tempo e se pensa que ficou faltando algo, aceito sugestões. &lt;/p&gt;

</description>
      <category>programming</category>
      <category>kotlin</category>
    </item>
    <item>
      <title>Spring com MongoDB</title>
      <dc:creator>Thiago Lino</dc:creator>
      <pubDate>Mon, 22 Nov 2021 12:17:52 +0000</pubDate>
      <link>https://forem.com/thiagolinoz/spring-com-mongodb-5bfm</link>
      <guid>https://forem.com/thiagolinoz/spring-com-mongodb-5bfm</guid>
      <description>&lt;p&gt;Hoje em dia com tantas opções para armazenamento de informações para necessidades diferentes, saber como trabalhar com estas opções é importante.&lt;/p&gt;

&lt;p&gt;Por isso decidi escrever esse tutorial de como criar uma aplicação em java utilizando um banco de dados NoSQL. &lt;br&gt;
E para isto criei uma POC para ilustrar utilizando as tecnologias, java 8, spring(spring data mongodb) e o mongoDB.&lt;/p&gt;

&lt;p&gt;Decidi por dividir o tutorial e iniciar este com a integração da nossa aplicação com a base de dados.&lt;/p&gt;

&lt;p&gt;Vamos iniciar baixando o spring no &lt;a href="https://start.spring.io/"&gt;Spring Initializr&lt;/a&gt;. E lá já podemos especificar as dependências necessárias.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8No6-zaJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uk8y3x7p3g3wjwhoz5j6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8No6-zaJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uk8y3x7p3g3wjwhoz5j6.png" alt="fing. 1 - print com as dependências" width="880" height="687"&gt;&lt;/a&gt;&lt;br&gt;
fig. 1 - print com as dependências&lt;/p&gt;

&lt;p&gt;Aqui selecionei o &lt;strong&gt;Spring Web&lt;/strong&gt;, já que pretendo montar aqui uma aplicação web e ja vem com o &lt;em&gt;Spring MVC&lt;/em&gt; além do servidor web &lt;em&gt;Apache Tomcat&lt;/em&gt;, &lt;strong&gt;Thymeleaf&lt;/strong&gt; para ser nosso template e por último o &lt;strong&gt;Spring Data MongoDB&lt;/strong&gt; que vai nos auxiliar a guardar e recuperar nossa informação.&lt;/p&gt;

&lt;p&gt;Agora vamos ao MongoDB e aqui invés de subir em um docker container ou até instalar localmente eu optei por usar a versão &lt;a href="https://www.mongodb.com/cloud"&gt;cloud&lt;/a&gt; e lá podemos utilizar a versão trial. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--KnwlAj4d--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xmpf2v316mrxwenspebk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--KnwlAj4d--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xmpf2v316mrxwenspebk.png" alt="print mongodb cloud" width="880" height="301"&gt;&lt;/a&gt;&lt;br&gt;
 fig. 2 - print mongodb cloud&lt;/p&gt;

&lt;p&gt;Esse &lt;a href="https://docs.atlas.mongodb.com/getting-started/"&gt;doc&lt;/a&gt; da um passo a passo para: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;criação da conta grátis &lt;/li&gt;
&lt;li&gt;do cluster&lt;/li&gt;
&lt;li&gt;adicionar seu IP para acesso ao cluster&lt;/li&gt;
&lt;li&gt;criação de um usuário para o cluster&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;O doc é bem explicado e tranquilo de seguir, porém só encontrei a versão em inglês.&lt;/p&gt;

&lt;p&gt;Com os passos acima realizados é hora de testar conectando nossa aplicação ao cluster recém criado.&lt;/p&gt;

&lt;p&gt;Precisamos recuperar nossa string de conexão, para isto acesse seu cluster e no dash clique em &lt;em&gt;Connect&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--GtpS6x0i--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q7cc2mq0i22357jjhx5c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--GtpS6x0i--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q7cc2mq0i22357jjhx5c.png" alt="dash do cluster para pegar o host" width="880" height="276"&gt;&lt;/a&gt;&lt;br&gt;
 fig. 3 - dash do cluster para pegar o host&lt;/p&gt;

&lt;p&gt;E no box que vai abrir selecione &lt;em&gt;Connect your application&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--m4sZ0Gu3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1tq876kxactsaj8dpzb0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--m4sZ0Gu3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1tq876kxactsaj8dpzb0.png" alt="box com opções de conexão" width="799" height="614"&gt;&lt;/a&gt;&lt;br&gt;
 fig. 4 - box com opções de conexão&lt;/p&gt;

&lt;p&gt;E aqui vamos selecionar o driver para a conexão e neste caso &lt;em&gt;Java&lt;/em&gt; e a versão mais recente dele e logo abaixo já temos nossa string de conexão.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Mo3XfVc5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9eqyu05xq9dewueua2v4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Mo3XfVc5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9eqyu05xq9dewueua2v4.png" alt="box para seleção de driver e string de conexão" width="799" height="579"&gt;&lt;/a&gt;&lt;br&gt;
 fig. 5 - box para seleção de driver e string de conexão&lt;/p&gt;

&lt;p&gt;Na fig. 3 no dash do cluster podemos criar nosso database clicando em &lt;em&gt;Browse Data&lt;/em&gt; que irá abrir uma tela com nossas collections.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--fZbNRYYb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/o9lmornqnwnckvrnj2mn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--fZbNRYYb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/o9lmornqnwnckvrnj2mn.png" alt="box para criar database e collection" width="880" height="301"&gt;&lt;/a&gt;&lt;br&gt;
   fig. 6 - box para criar database e collection&lt;/p&gt;

&lt;p&gt;Clicando em &lt;em&gt;Create Database&lt;/em&gt; irá abrir um box para definirmos o nomes da database e collection.&lt;/p&gt;

&lt;p&gt;Certo agora podemos definir estar informações em nossa aplicação, no arquivo &lt;em&gt;application.properties&lt;/em&gt; dentro de resources.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--JplWJZ2x--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ny66dslczlx37m22ekgr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--JplWJZ2x--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ny66dslczlx37m22ekgr.png" alt="localização do arquivo application.properties" width="339" height="281"&gt;&lt;/a&gt;&lt;br&gt;
 fig. 7 - localização do arquivo application.properties&lt;/p&gt;

&lt;p&gt;Aqui vamos definir as properties necessárias para conectar a nossa database.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;spring.data.mongodb.uri={aqui nossa string de conexão}
spring.data.mongodb.database={aqui o nome da database criada}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;E ao iniciar nossa aplicação vamos receber uma mensagem similar a esta.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--aTYAfH3P--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/c3xgv8av9zutfvg3qw9h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--aTYAfH3P--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/c3xgv8av9zutfvg3qw9h.png" alt="mensagem de conexão criada com o mongodb" width="762" height="260"&gt;&lt;/a&gt;&lt;br&gt;
 fig.8 - mensagem de conexão criada com o mongodb&lt;/p&gt;

&lt;p&gt;Por último podemos já interagir com nossa database e collection recém-criadas, inciando com a criação de um repository.&lt;/p&gt;

&lt;p&gt;Dentro do nosso package podemos criar um diretório novo chamado &lt;em&gt;repository&lt;/em&gt; e dentro dele nossa &lt;em&gt;interface&lt;/em&gt; a &lt;em&gt;PetRepository&lt;/em&gt; esta por sua vez vai extender a MongoRepository que traz os métodos como &lt;em&gt;insert()&lt;/em&gt;, &lt;em&gt;findAll()&lt;/em&gt;, &lt;em&gt;saveAll()&lt;/em&gt; para o comunicação com nosso Mongo.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Repository
public interface PetRepository extends MongoRepository&amp;lt;Pet, String&amp;gt; {
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Adicionamos a anotação &lt;em&gt;@Repository&lt;/em&gt; para o spring saber do que se trata e além disso passamos para nosso MongoRepository a entity Pet que vamos criar agora.&lt;/p&gt;

&lt;p&gt;Aqui vamos fazer uma simples Entity com o identificador id(o MongoDB precisa deste) com a anotação &lt;em&gt;&lt;a class="mentioned-user" href="https://dev.to/id"&gt;@id&lt;/a&gt;&lt;/em&gt;, name, age e type do pet que vamos manipular. Anotamos a entidade com o nome da collection que vamos mapear.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Document(collection="pets")
public class Pet {

    @Id
    private String id;

    private String name;
    private int age;
    private String type;

// todos os getters e setters
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Só um detalhe para o atributo &lt;em&gt;type&lt;/em&gt; que aqui pretendo criar uma classe para ele, porém para agilizar o teste fiz com tipo String.&lt;br&gt;&lt;br&gt;
Com isso já podemos criar nosso service que vai chamar os métodos do nosso repository. Criamos um pacote chamado service e dentro dele nosso &lt;em&gt;PetService&lt;/em&gt; com um método para retornar todos os pets existentes. &lt;br&gt;
Anotamos a classe com a anotação &lt;em&gt;@Service&lt;/em&gt; e injetamos nossa dependência PetRepository com a anotação &lt;em&gt;@Autowired&lt;/em&gt; e criamos o nosso método &lt;em&gt;findAll()&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Service
public class PetService {

    @Autowired
    private PetRepository repository;

    public List&amp;lt;Pet&amp;gt; findAll() {
        return repository.findAll();
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;E agora para ver nossos pets cadastrados vamos criar uma controller para através da nossa service resgatar nossos pets. No código abaixo da para ver que algumas partes são similares a nossa service, mudando alguns detalhes como a injeção que desta vez é nossa &lt;em&gt;PetService&lt;/em&gt; e as anotações usadas, como a &lt;em&gt;@RequestMapping&lt;/em&gt; para mapear as requisições recebidas. E por último recebemos como parâmetro um Model para setar o atributo para nossa &lt;em&gt;view&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Controller
@RequestMapping("/pets")
public class PetController {

    @Autowired
    private PetService petService;

    @RequestMapping("/list")
    public String list(Model model) {
        final List&amp;lt;Pet&amp;gt; petList = petService.findAll();
        model.addAttribute("pets", petList);

        return "pets/list";
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Só precisamos criar nosso arquivo html em um diretório dentro de resources &amp;gt; templates chamados pets. Aqui fiz um html bem simples, apenas para listar o nome e idade dos nossos pets e neste html como estamos usando a biblioteca thymeleaf usei as propriedades da mesma para iterar e exibir os itens.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;body&amp;gt;
    &amp;lt;div id="listPets"&amp;gt;
        &amp;lt;h3&amp;gt;List all pets&amp;lt;/h3&amp;gt;
        &amp;lt;table&amp;gt;
            &amp;lt;thead&amp;gt;
            &amp;lt;tr&amp;gt;
                &amp;lt;td&amp;gt;Name: &amp;lt;/td&amp;gt;
                &amp;lt;td&amp;gt;Age: &amp;lt;/td&amp;gt;
            &amp;lt;/tr&amp;gt;
            &amp;lt;/thead&amp;gt;
            &amp;lt;tr th:each="pet : ${pets}"&amp;gt;
                &amp;lt;td&amp;gt;&amp;lt;span th:text="${pet.name}"&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/td&amp;gt;
                &amp;lt;td&amp;gt;&amp;lt;span th:text="${pet.age}"&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/td&amp;gt;
            &amp;lt;/tr&amp;gt;
        &amp;lt;/table&amp;gt;
    &amp;lt;/div&amp;gt;
&amp;lt;/body&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;E quando rodarmos temos uma página sem itens. E por quê? Porque não adicionamos nenhum item e agora é uma boa oportunidade para também testarmos o insert.&lt;/p&gt;

&lt;p&gt;Na nossa entity criei um construtor, para facilitar a atribuição da nossa entidade, passando o &lt;em&gt;name&lt;/em&gt;, &lt;em&gt;type&lt;/em&gt; e &lt;em&gt;age&lt;/em&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public Pet(String name, String type, int age) {
     this.name = name;
     this.type = type;
     this.age = age;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No service criamos um novo método chamado save que recebe a entidade Pet e chamamos nosso &lt;em&gt;PetRepository&lt;/em&gt; chamando o método &lt;em&gt;save()&lt;/em&gt; passando nosso pet.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public void save(Pet pet) {
     repository.save(pet);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nossa controller vai chamar o &lt;em&gt;save()&lt;/em&gt; da nossa &lt;em&gt;PetService&lt;/em&gt;&lt;br&gt;
passando um novo Pet e retornando uma string com o html que vamos criar&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@GetMapping("/populate")
public String populateWithPets() {
     petService.save(new Pet("nina", "cat", 7));
     return "pets/populate";
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;E por fim criamos um html, aqui pode ser vazio, em templates &amp;gt; pets, que já tinhamos criado anteriormente. &lt;/p&gt;

&lt;p&gt;E se tudo deu certo depois de acessar nossa url &lt;em&gt;pets/populate&lt;/em&gt; podemos conferir nosso pet recém salvo em &lt;em&gt;pets/list&lt;/em&gt; ou até mesmo dentro do nosso cluster la no mongodb atlas&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--yn7xmFS7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nkcnspkzqdkgo71pe5sk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--yn7xmFS7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nkcnspkzqdkgo71pe5sk.png" alt="pet salvo no mongodb" width="880" height="345"&gt;&lt;/a&gt;&lt;br&gt;
 fig. - 9 pet salvo no mongodb&lt;/p&gt;

&lt;p&gt;E para esta primeira parte do tutorial creio ser o suficiente, pretendo continuar com o tutorial utilizando esta app para nos auxiliar. Se tiverem alguma dúvida, dificuldade ou verem algum ponto que poderia ter feito de outra maneira só comentarem para interagirmos.     &lt;/p&gt;

&lt;p&gt;Obrigado e nos vemos na continuação =)&lt;/p&gt;

</description>
      <category>java</category>
      <category>spring</category>
      <category>mongodb</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Injeção de dependência através de atributos é o ideal?</title>
      <dc:creator>Thiago Lino</dc:creator>
      <pubDate>Tue, 23 Feb 2021 11:56:14 +0000</pubDate>
      <link>https://forem.com/thiagolinoz/injecao-de-dependencia-atraves-de-atributos-e-o-ideal-1467</link>
      <guid>https://forem.com/thiagolinoz/injecao-de-dependencia-atraves-de-atributos-e-o-ideal-1467</guid>
      <description>&lt;p&gt;No framework Spring quando queremos fazer alguma injeção de dependência (DI) é comum fazermos por atributos.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; @Autowired
 private InjectedDependency injectedDependency;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Porém este método tem suas desvantagens e vou dizer quais. &lt;br&gt;
Mas antes vamos escolher uma batida para acompanhar.&lt;/p&gt;

&lt;p&gt;&lt;iframe src="https://open.spotify.com/embed/track/04Z4xUSktqIO8tvf2U7OhY" width="100%" height="80px"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Agora sim.&lt;/p&gt;

&lt;p&gt;Existem 3 maneiras de se realizar a injeção de dependência no Spring, &lt;a href="https://docs.spring.io/spring-framework/docs/5.0.3.RELEASE/spring-framework-reference/core.html#beans-factory-collaborators"&gt;apesar da documentação, no momento que escrevo, citar apenas duas&lt;/a&gt;. A já citada e exemplificada por atributo, através do construtor da classe e por setters métodos.&lt;/p&gt;

&lt;p&gt;Pelo construtor:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;private InjectedDependency injectedDependency;

@Autowired
public MyDependencyInjection(InjectedDependency injectedDependency) {
  this.injectedDependency = injectedDependency;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;E por setters:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;private InjectedDependencyOne injectedDependencyOne;
private InjectedDependencyTwo injectedDependencyTwo;

@Autowired
private void setInjectedDependencyOne(InjectedDependencyOne injectedDependencyOne) {
  this.injectedDependencyOne = injectedDependencyOne;
}

@Autowired
private void setInjectedDependencyTwo(InjectedDependencyTwo injectedDependencyTwo) {
  this.injectedDependencyTwo = injectedDependencyTwo;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A primeira vista realizar a injeção de dependência por atributos parece ser, e é, mais simples e menos verbosa. Uma linha e direto ao ponto(tirando a anotação). Porém nem sempre o simples é o melhor, eis os pontos negativos.&lt;/p&gt;

&lt;h6&gt;
  
  
  Não permite imutabilidade dos nossos atributos
&lt;/h6&gt;

&lt;p&gt;Nossa injeção não funcionará com atributos da classe que forem declarados como &lt;code&gt;final&lt;/code&gt;, logo perdemos a imutabilidade destes atributos. Com a injeção através dos construtores não perderiamos a imutabilidade destes atributos.&lt;/p&gt;

&lt;h6&gt;
  
  
  Ferir o S do SOLID
&lt;/h6&gt;

&lt;p&gt;Adicionar dependências a nossa classe por atributos por ser menos verboso pode trazer o problema de nossa classe possuir várias dependências sem nos darmos conta que a classe esta fazendo mais do que deveria, tendo mais de uma responsabilidade ferindo o &lt;em&gt;Single responsibility principle&lt;/em&gt;. A injeção através dos construtores nos ajudaria tornando este construtor cheio e mais visível da quantidade de dependências e responsabilidades da classe . &lt;br&gt;
Aqui diria que é mais questão de dar visibilidade que uma refatoração pode ser necessária.&lt;/p&gt;

&lt;h6&gt;
  
  
  Esconde as dependências
&lt;/h6&gt;

&lt;p&gt;A classe perde a responsabilidade por obter e gerenciar as dependências, deixando a cargo dos containers de injenção de dependência. Neste cenário seria ideal deixar claro, além de ser recomendável quando se usa DI, quais as dependências utilizadas são obrigatórias e quais são opcionais. O que ficaria inviável através de atributos. Utilizando construtores para obrigatórios e setters para opcionais conseguimos.&lt;/p&gt;

&lt;h6&gt;
  
  
  Acoplamento do container de DI
&lt;/h6&gt;

&lt;p&gt;Como citado anteriormente a responsabilidade agora será dos containers de DI, neste caso containers Spring. O que deixa nosso desenvolvimento acoplado ao container.&lt;br&gt;
Fora do container da aplicação fica mais dificíl utilizar estas dependências. Em um cenário de testes unitários por exemplo, seria necessário instanciar este Spring container(o que alteraria nosso teste unitário para um de integração) e utilizar &lt;code&gt;reflexão&lt;/code&gt; para settar estes atributos.&lt;br&gt;
Utilizando a DI com construtores invés de por atributos, apenas instanciamos estas classes e passamos como nossas dependências.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conclusão&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Realizar a injeção de dependência por construtores ou através de setters apesar de ser mais verboso deixa nosso código mais legível, na minha opinião. &lt;br&gt;
Um dos exemplos seria quando temos um construtor com muito parâmetros, neste caso as dependências, indica que nossa classe faz mas do que deveria e pode caber uma refatoração. Ainda sobre ser tornar o código legível, podemos citar também sobre a obrigatoriedade de uma dependência quando passada através de construtores ou sua opcionalidade quando passada por setteres.&lt;/p&gt;

&lt;p&gt;Se você achou que tem um ponto ou vários que não faz sentido comenta ae pra gente debater sobre, uma discussão saúdavel é ótimo para aprender. &lt;/p&gt;

&lt;p&gt;&lt;em&gt;Referências que usei&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.vojtechruzicka.com/field-dependency-injection-considered-harmful/"&gt;https://www.vojtechruzicka.com/field-dependency-injection-considered-harmful/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.marcnuri.com/field-injection-is-not-recommended/"&gt;https://blog.marcnuri.com/field-injection-is-not-recommended/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

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