<?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: Fabiano Góes • e-Programar</title>
    <description>The latest articles on DEV Community by Fabiano Góes • e-Programar (@fabianogoes).</description>
    <link>https://dev.to/fabianogoes</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%2F456028%2Fa9d922bf-3531-4265-88a8-3d710e76af97.png</url>
      <title>DEV Community: Fabiano Góes • e-Programar</title>
      <link>https://dev.to/fabianogoes</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/fabianogoes"/>
    <language>en</language>
    <item>
      <title>Documentando uma API REST Spring Boot 3 usando OpenAPI 3.0</title>
      <dc:creator>Fabiano Góes • e-Programar</dc:creator>
      <pubDate>Tue, 09 Jan 2024 00:00:45 +0000</pubDate>
      <link>https://dev.to/fabianogoes/documentando-uma-api-rest-spring-boot-3-usando-openapi-30-k1c</link>
      <guid>https://dev.to/fabianogoes/documentando-uma-api-rest-spring-boot-3-usando-openapi-30-k1c</guid>
      <description>&lt;h2&gt;
  
  
  Visão Geral
&lt;/h2&gt;

&lt;p&gt;A documentação é uma parte essencial da construção de APIs REST. Neste tutorial, veremos &lt;strong&gt;SpringDoc&lt;/strong&gt;, que simplifica a geração e manutenção de documentos de &lt;strong&gt;API&lt;/strong&gt; com base na especificação &lt;strong&gt;OpenAPI&lt;/strong&gt; 3 para aplicativos &lt;strong&gt;Spring Boot&lt;/strong&gt; 3.x. &lt;/p&gt;

&lt;h3&gt;
  
  
  Configuração
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fesgv7qebh9hf7ygoxhbp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fesgv7qebh9hf7ygoxhbp.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Spring Boot 3.x requer o uso da versão 2 do &lt;a href="https://central.sonatype.com/artifact/org.springdoc/springdoc-openapi-starter-webmvc-ui" rel="noopener noreferrer"&gt;springdoc-openapi&lt;/a&gt;:&lt;/p&gt;

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

ext {
    springdocVersion = "2.3.0"
}

dependencies {
    implementation "org.springframework.boot:spring-boot-starter-web"
    // ...
    implementation "org.springframework.boot:spring-boot-starter-validation"
    implementation "org.springdoc:springdoc-openapi-starter-webmvc-ui:${springdocVersion}"
    implementation "org.springdoc:springdoc-openapi-starter-common:${springdocVersion}"
    // ...
    testImplementation "org.springframework.boot:spring-boot-starter-test"
}


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Depois de configurar a dependência corretamente, podemos executar nossa aplicação e encontrar as descrições da &lt;strong&gt;OpenAPI&lt;/strong&gt; em &lt;code&gt;/v3/api-docs&lt;/code&gt;, que é o caminho padrão:&lt;/p&gt;

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

http://localhost:8080/v3/api-docs


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Podemos personalizar o caminho em &lt;code&gt;application.properties&lt;/code&gt; usando a propriedade &lt;code&gt;springdoc.api-docs&lt;/code&gt;. Por exemplo, podemos definir o caminho para &lt;code&gt;/api-docs&lt;/code&gt;:&lt;/p&gt;

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

springdoc.api-docs.path=/api-docs


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Então, poderemos acessar a documentação na url:&lt;/p&gt;

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

http://localhost:8080/api-docs


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;As definições &lt;strong&gt;OpenAPI&lt;/strong&gt; estão no formato &lt;strong&gt;JSON&lt;/strong&gt; por padrão. Para o obter o formato &lt;code&gt;yaml&lt;/code&gt;, podemos podemos acessar a url:&lt;/p&gt;

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

http://localhost:8080/api-docs.yaml


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
  
  
  Integração com UI Swagger
&lt;/h2&gt;

&lt;p&gt;Além de gerar a especificação &lt;strong&gt;OpenAPI&lt;/strong&gt; 3, podemos integrar &lt;code&gt;springdoc-openapi&lt;/code&gt; com &lt;strong&gt;Swagger UI&lt;/strong&gt; para interagir com nossa especificação de &lt;strong&gt;API&lt;/strong&gt; e testar os endpoints. A dependência &lt;code&gt;springdoc-openapi&lt;/code&gt; já inclui a &lt;strong&gt;UI&lt;/strong&gt; do &lt;strong&gt;Swagger&lt;/strong&gt;, então neste ponto, já podemos acessar a &lt;strong&gt;Swagger UI&lt;/strong&gt; em:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

http://localhost:8080/swagger-ui/index.html


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
  
  
  Support for swagger-ui Properties
&lt;/h3&gt;

&lt;p&gt;A biblioteca &lt;code&gt;springdoc-openapi&lt;/code&gt; também suporta propriedades &lt;code&gt;swagger-ui&lt;/code&gt;. Elas podem ser usados ​​como propriedades &lt;strong&gt;Spring Boot&lt;/strong&gt; com o prefixo &lt;code&gt;springdoc.swagger-ui&lt;/code&gt;. Por exemplo, podemos personalizar o caminho da &lt;strong&gt;Swagger UI&lt;/strong&gt; alterando a propriedade &lt;code&gt;springdoc.swagger-ui.path&lt;/code&gt; dentro do nosso arquivo &lt;code&gt;application.properties&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

springdoc.swagger-ui.path=/documentation.html


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Então podemos acessar a &lt;strong&gt;Swagger UI&lt;/strong&gt; na url:&lt;/p&gt;

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

http://localhost:8080/documentation.html


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
  
  
  API de exemplo
&lt;/h2&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.http.HttpStatus&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.http.ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.web.bind.annotation.*&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.web.util.UriComponentsBuilder&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.util.Collection&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&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/books"&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;BookController&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;BookRepository&lt;/span&gt; &lt;span class="n"&gt;repository&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;BookController&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;BookRepository&lt;/span&gt; &lt;span class="n"&gt;repository&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;repository&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;repository&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@PostMapping&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;?&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;create&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;@RequestBody&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;Book&lt;/span&gt; &lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;UriComponentsBuilder&lt;/span&gt; &lt;span class="n"&gt;ucb&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;Book&lt;/span&gt; &lt;span class="n"&gt;book&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;repository&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;create&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;location&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ucb&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/movies/{id}"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;buildAndExpand&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;book&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getId&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toUri&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;created&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;location&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="o"&gt;();&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;"/{id}"&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;Book&lt;/span&gt; &lt;span class="nf"&gt;findById&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;@PathVariable&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;Long&lt;/span&gt; &lt;span class="n"&gt;id&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="n"&gt;repository&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;findById&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;orElseThrow&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;BookNotFoundException:&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="o"&gt;);&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;"/"&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;Collection&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Book&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;findBooks&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="n"&gt;repository&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getBooks&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@PutMapping&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/{id}"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="nd"&gt;@ResponseStatus&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;HttpStatus&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;OK&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;ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;?&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;update&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;@PathVariable&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"id"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;Long&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nd"&gt;@RequestBody&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;Book&lt;/span&gt; &lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;repository&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;findById&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;isEmpty&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;notFound&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;accepted&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;repository&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;update&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@DeleteMapping&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/{id}"&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;ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;?&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;delete&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;@PathVariable&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;Long&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;Book&lt;/span&gt; &lt;span class="n"&gt;book&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;repository&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;findById&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;orElseThrow&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;BookNotFoundException:&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;repository&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;delete&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;book&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;noContent&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;build&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;h3&gt;
  
  
  Repositório de exemplo
&lt;/h3&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.stereotype.Repository&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.util.*&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="nd"&gt;@Repository&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;BookRepository&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Long&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Book&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;books&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;HashMap&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;();&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;Optional&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Book&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;findById&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="kt"&gt;long&lt;/span&gt; &lt;span class="n"&gt;id&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="nc"&gt;Optional&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ofNullable&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;books&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;));&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;Book&lt;/span&gt; &lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Book&lt;/span&gt; &lt;span class="n"&gt;book&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;Long&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;long&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;books&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;book&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setId&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;books&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;put&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;book&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;books&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;);&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;Collection&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Book&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;getBooks&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="n"&gt;books&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;values&lt;/span&gt;&lt;span class="o"&gt;();&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;Book&lt;/span&gt; &lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="kt"&gt;long&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;Book&lt;/span&gt; &lt;span class="n"&gt;book&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;Book&lt;/span&gt; &lt;span class="n"&gt;bookUpdate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;books&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;bookUpdate&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setAuthor&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;book&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getAuthor&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
        &lt;span class="n"&gt;bookUpdate&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setTitle&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;book&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getTitle&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
        &lt;span class="n"&gt;books&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;put&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;bookUpdate&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;books&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;delete&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;Book&lt;/span&gt; &lt;span class="n"&gt;book&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;books&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;remove&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;book&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getId&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;h3&gt;
  
  
  Modelo de exemplo
&lt;/h3&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;jakarta.validation.constraints.NotBlank&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;jakarta.validation.constraints.Size&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;Book&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;long&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;author&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// Getters and Setters&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;BookNotFoundException&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;RuntimeException&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;h2&gt;
  
  
  Application Properties de exemplo
&lt;/h2&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;


# Open Api
springdoc.api-docs.path=/api-docs
springdoc.swagger-ui.operationsSorter=alpha
springdoc.api-docs.version=OPENAPI_3_0
spring.jpa.hibernate.ddl-auto=none

# Swagger
springdoc.swagger-ui.path=/documentation.html


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
  
  
  Testando
&lt;/h2&gt;

&lt;p&gt;Então, se executarmos nossa API agora, podemos visualizar a documentação em:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

http://localhost:8080/documentation.html


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fcju1dkdfwdqh5bwycwy3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fcju1dkdfwdqh5bwycwy3.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Aqui podemos usar a Swagger UI para testar nossa API fazendo:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;cadastro de novos livros&lt;/li&gt;
&lt;li&gt;obtendo todos os livros cadastrados&lt;/li&gt;
&lt;li&gt;obtendo um livro pelo id&lt;/li&gt;
&lt;li&gt;atualizando um livro cadastrado&lt;/li&gt;
&lt;li&gt;deletando um livro cadastrado&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Faça testes e explore a Documentação gerada automáticamente.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Geração automática de documentos usando validação de bean JSR-303
&lt;/h2&gt;

&lt;p&gt;Quando nosso modelo inclui anotações de validação de bean &lt;strong&gt;JSR-303&lt;/strong&gt;, como &lt;code&gt;@NotNull&lt;/code&gt;, &lt;code&gt;@NotBlank&lt;/code&gt;, &lt;code&gt;@Size&lt;/code&gt;, &lt;code&gt;@Min&lt;/code&gt; e &lt;code&gt;@Max&lt;/code&gt;, a biblioteca &lt;code&gt;springdoc-openapi&lt;/code&gt; utiliza essas anotações para gerar documentação de esquema adicional para as restrições correspondentes. Vejamos um exemplo usando nosso bean Book:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Book&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;long&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="nd"&gt;@NotBlank&lt;/span&gt;
    &lt;span class="nd"&gt;@Size&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;min&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;max&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="nd"&gt;@NotBlank&lt;/span&gt;
    &lt;span class="nd"&gt;@Size&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;min&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;max&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;author&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;Percebe agora como ficou a documentação do Schema de Book:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fa4c0kdq0qj9gdpdg5p73.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fa4c0kdq0qj9gdpdg5p73.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Gerando documentação adicional usando &lt;code&gt;@ControllerAdvice&lt;/code&gt; e &lt;code&gt;@ResponseStatus&lt;/code&gt;:
&lt;/h2&gt;

&lt;p&gt;Usar &lt;code&gt;@ResponseStatus&lt;/code&gt; em métodos em uma classe &lt;code&gt;@RestControllerAdvice&lt;/code&gt; o openapi vai gerar automaticamente documentação para os códigos de resposta. Nesta classe &lt;code&gt;@RestControllerAdvice&lt;/code&gt;, os dois métodos são anotados com &lt;code&gt;@ResponseStatus&lt;/code&gt;:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.core.convert.ConversionFailedException&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.http.HttpStatus&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.http.ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.web.bind.annotation.ExceptionHandler&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.web.bind.annotation.ResponseStatus&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.web.bind.annotation.RestControllerAdvice&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="nd"&gt;@RestControllerAdvice&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;GlobalControllerExceptionHandler&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nd"&gt;@ExceptionHandler&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;ConversionFailedException&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="nd"&gt;@ResponseStatus&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;HttpStatus&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;BAD_REQUEST&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;ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;handleConversion&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;RuntimeException&lt;/span&gt; &lt;span class="n"&gt;ex&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="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getMessage&lt;/span&gt;&lt;span class="o"&gt;(),&lt;/span&gt; &lt;span class="nc"&gt;HttpStatus&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;BAD_REQUEST&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@ExceptionHandler&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;BookNotFoundException&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="nd"&gt;@ResponseStatus&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;HttpStatus&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;NOT_FOUND&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;ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;handleBookNotFound&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;RuntimeException&lt;/span&gt; &lt;span class="n"&gt;ex&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="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getMessage&lt;/span&gt;&lt;span class="o"&gt;(),&lt;/span&gt; &lt;span class="nc"&gt;HttpStatus&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;NOT_FOUND&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;As a result, we can now see the documentation for the response codes &lt;code&gt;400&lt;/code&gt; and &lt;code&gt;404&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Feu7v7plukiggk58prih0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Feu7v7plukiggk58prih0.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Gerando documentação usando &lt;code&gt;@Operation&lt;/code&gt; e &lt;code&gt;@ApiResponses&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;A seguir, vamos ver como podemos adicionar alguma descrição à nossa API usando algumas anotações da especificação &lt;strong&gt;&lt;a href="https://javadoc.io/doc/io.swagger.core.v3/swagger-annotations/latest/index.html" rel="noopener noreferrer"&gt;OpenAPI&lt;/a&gt;&lt;/strong&gt;.   &lt;/p&gt;

&lt;p&gt;Para fazer isso, anotaremos o endpoint &lt;code&gt;/api/book/{id}&lt;/code&gt; do nosso controlador com &lt;code&gt;@Operation&lt;/code&gt; e &lt;code&gt;@ApiResponses&lt;/code&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;@Operation&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;summary&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Get a book by its id"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="nd"&gt;@ApiResponses&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; 
  &lt;span class="nd"&gt;@ApiResponse&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;responseCode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"200"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;description&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Found the book"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; 
    &lt;span class="n"&gt;content&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="nd"&gt;@Content&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;mediaType&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"application/json"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; 
      &lt;span class="n"&gt;schema&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nd"&gt;@Schema&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;implementation&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Book&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="o"&gt;}),&lt;/span&gt;
  &lt;span class="nd"&gt;@ApiResponse&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;responseCode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"400"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;description&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Invalid id supplied"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; 
    &lt;span class="n"&gt;content&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nd"&gt;@Content&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt; 
  &lt;span class="nd"&gt;@ApiResponse&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;responseCode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"404"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;description&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Book not found"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; 
    &lt;span class="n"&gt;content&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nd"&gt;@Content&lt;/span&gt;&lt;span class="o"&gt;)&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;"/{id}"&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;Book&lt;/span&gt; &lt;span class="nf"&gt;findById&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;@Parameter&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;description&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"id of book to be searched"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; 
  &lt;span class="nd"&gt;@PathVariable&lt;/span&gt; &lt;span class="kt"&gt;long&lt;/span&gt; &lt;span class="n"&gt;id&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="n"&gt;repository&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;findById&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;orElseThrow&lt;/span&gt;&lt;span class="o"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;BookNotFoundException&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 nosso endpoint &lt;code&gt;/api/book/{id}&lt;/code&gt; ficou documentado assim:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fkrvkyil46175iwvjoe5x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fkrvkyil46175iwvjoe5x.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;Neste artigo, aprendemos como configurar o &lt;code&gt;springdoc-openapi&lt;/code&gt; em nossos projetos. Em seguida, vimos como integrar &lt;code&gt;springdoc-openapi&lt;/code&gt; com a &lt;strong&gt;UI do Swagger&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;Depois disso, vimos como o &lt;code&gt;springdoc-openapi&lt;/code&gt; gera documentação automaticamente usando anotações de validação de bean JSR 303 e as anotações &lt;code&gt;@ResponseStatus&lt;/code&gt; na classe &lt;code&gt;@ControllerAdvice&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Também aprendemos como adicionar uma descrição à nossa API usando algumas anotações específicas da &lt;strong&gt;OpenAPI&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;O &lt;code&gt;springdoc-openapi&lt;/code&gt; gera documentação da API de acordo com as especificações do &lt;strong&gt;OpenAPI 3&lt;/strong&gt;. Além disso, ele também cuida da configuração da &lt;strong&gt;UI do Swagger&lt;/strong&gt; para nós, tornando a geração de documentos da API uma tarefa razoavelmente simples.&lt;/p&gt;

&lt;h3&gt;
  
  
  Referencias
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.baeldung.com/spring-rest-openapi-documentation" rel="noopener noreferrer"&gt;Documenting a Spring REST API Using OpenAPI 3.0 - Baeldung&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://docs.spring.io/spring-framework/reference/index.html" rel="noopener noreferrer"&gt;Spring Framework Documentation&lt;/a&gt;]&lt;/li&gt;
&lt;li&gt;&lt;a href="https://springdoc.org/#groovy-support" rel="noopener noreferrer"&gt;springdoc-openapi v2.3.0&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://spec.openapis.org/oas/latest.html" rel="noopener noreferrer"&gt;OpenAPI Specification v3.1.0&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://swagger.io/specification/" rel="noopener noreferrer"&gt;OpenAPI Specification&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>java</category>
      <category>springboot</category>
      <category>springweb</category>
      <category>openapi</category>
    </item>
    <item>
      <title>5 ótimos livros NÃO modinha que vai ALÉM de linguagem e que você DEVERIA ler em 2023</title>
      <dc:creator>Fabiano Góes • e-Programar</dc:creator>
      <pubDate>Wed, 11 Jan 2023 17:20:53 +0000</pubDate>
      <link>https://dev.to/fabianogoes/5-otimos-livros-nao-modinha-que-vai-alem-de-linguagem-e-que-voce-deveria-ler-em-2023-4208</link>
      <guid>https://dev.to/fabianogoes/5-otimos-livros-nao-modinha-que-vai-alem-de-linguagem-e-que-voce-deveria-ler-em-2023-4208</guid>
      <description>&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%2Fsdscps32ao6e8njunom1.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%2Fsdscps32ao6e8njunom1.png" alt="O projeto Fênix" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;O projeto Fênix – Edição comemorativa: um romance sobre TI, DevOps e sobre ajudar o seu negócio a vencer.&lt;/li&gt;
&lt;/ol&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%2Fiiyf9mlu40nukusawhbi.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%2Fiiyf9mlu40nukusawhbi.png" alt="Accelerate" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Accelerate: The Science of Lean Software and DevOps: Building and Scaling High Performing Technology Organizations.&lt;/li&gt;
&lt;/ol&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%2Fms7zreu47lede5lsa54b.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%2Fms7zreu47lede5lsa54b.png" alt="Engenharia de Software Moderna" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Engenharia de Software Moderna: Princípios e Práticas para Desenvolvimento de Software com Produtividade.&lt;/li&gt;
&lt;/ol&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%2F5qjmb7tp4odxm8nie3h6.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%2F5qjmb7tp4odxm8nie3h6.png" alt="The Programmer's Brain" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The Programmer's Brain: What Every Programmer Needs to Know about Cognition.&lt;/li&gt;
&lt;/ol&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%2Fsx5qw9vk6adlyat5kwxl.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%2Fsx5qw9vk6adlyat5kwxl.png" alt="A Philosophy of Software Design" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A Philosophy of Software Design.&lt;/li&gt;
&lt;/ol&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%2Fxw7rig27pie47vuugs9n.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%2Fxw7rig27pie47vuugs9n.png" alt="e-Programar" width="800" height="800"&gt;&lt;/a&gt;&lt;br&gt;
E ai, já leu algum desses livros ?&lt;br&gt;
Qual livro você indicaria pra entrar nessa lista ?&lt;/p&gt;

&lt;p&gt;diz ai nos comentários.&lt;/p&gt;

</description>
      <category>marketing</category>
      <category>offers</category>
    </item>
    <item>
      <title>Spring Rest Repositories para acelerar MVP e PoC</title>
      <dc:creator>Fabiano Góes • e-Programar</dc:creator>
      <pubDate>Tue, 09 Aug 2022 23:25:00 +0000</pubDate>
      <link>https://dev.to/fabianogoes/spring-rest-repositories-para-acelerar-mvp-e-poc-7lk</link>
      <guid>https://dev.to/fabianogoes/spring-rest-repositories-para-acelerar-mvp-e-poc-7lk</guid>
      <description>&lt;h2&gt;
  
  
  1. O Problema que queremos resolver
&lt;/h2&gt;

&lt;p&gt;As vezes precisamos criar um MVP e testar uma ideia rápido para ter feedback o quanto antes e é aqui que o Spring REST Repositories brilha acelerando muito o desenvolvimento de uma API REST.&lt;br&gt;
Neste artigo vamos criar um CRUD de uma API REST utilizando alguns recursos muito interessantes no ecosistema Spring.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;O que vamos usar:&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Spring Data/JPA para fazer o trabalho duro de ORM e manipular os dados no Banco.&lt;/li&gt;
&lt;li&gt;Spring REST Repositories para expor nosso CRUD através de uma API REST.&lt;/li&gt;
&lt;li&gt;H2 como Banco de Dados Relacional em memória.&lt;/li&gt;
&lt;li&gt;Lombok para automatizar nossos Getters, Setters, Constructors, ToString.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  2. A Solução
&lt;/h2&gt;

&lt;p&gt;Vamos usar o site &lt;code&gt;SPRING INITIALIZR&lt;/code&gt; para criação do projeto, acesse a URL: &lt;a href="https://start.spring.io/"&gt;https://start.spring.io/&lt;/a&gt; e configure conforme a imagem e ao final clique em “&lt;strong&gt;Generate Project&lt;/strong&gt;”&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--OisAwgcN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t81hjqg2k2kpucxbwq62.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--OisAwgcN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t81hjqg2k2kpucxbwq62.png" alt="SPRING INITIALIZR" width="800" height="594"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Na sessão de Dependences digite: &lt;code&gt;Web&lt;/code&gt;, &lt;code&gt;JPA&lt;/code&gt;, &lt;code&gt;H2&lt;/code&gt;, &lt;code&gt;Rest Repositories&lt;/code&gt;. Após clicar em “Generate Project” será feito o download do projeto em um arquivo .zip, descompacte e importe em sua IDE de preferencia.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Agora vamos criar nosso modelo “Person”, que neste caso será bem simple pois o Foco é o “Spring Rest Repositories”.&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="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;lombok.Data&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;javax.persistence.Entity&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;javax.persistence.GeneratedValue&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;javax.persistence.GenerationType&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;javax.persistence.Id&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="nd"&gt;@Data&lt;/span&gt;
&lt;span class="nd"&gt;@Entity&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;Person&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nd"&gt;@Id&lt;/span&gt;
    &lt;span class="nd"&gt;@GeneratedValue&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;strategy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;GenerationType&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;AUTO&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;long&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;firstName&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;lastName&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;Aqui usamos algumas annotations:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Entity&lt;/code&gt;: do conhecido JPA para tornar nosso modelo um ORM.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Id&lt;/code&gt;: do JPA para setar nosso id como Chave primária.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;GeneratedValue&lt;/code&gt;: do JPA para setar nosso id como AutoIncrement.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Data&lt;/code&gt;: do Lombok para criar nossos Getters and Setters.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Com nosso modelo &lt;strong&gt;ORM&lt;/strong&gt; criado podemos criar nossa Interface Repository, e aqui está o pulo do gato onde acontece toda a Magia do &lt;strong&gt;Spring&lt;/strong&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="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.util.List&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.data.repository.PagingAndSortingRepository&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.data.repository.query.Param&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.data.rest.core.annotation.RepositoryRestResource&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="nd"&gt;@RepositoryRestResource&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;collectionResourceRel&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"people"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"people"&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;interface&lt;/span&gt; &lt;span class="nc"&gt;PersonRepository&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;PagingAndSortingRepository&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Person&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Long&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

   &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Person&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;findByLastName&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;@Param&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"name"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;name&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;blockquote&gt;
&lt;p&gt;Aqui cabe alguns comentários:&lt;br&gt;
Quem já está familiarizado com Spring Data sabe que é comum anotar essa Interface com &lt;code&gt;@Repository&lt;/code&gt; e aqui estamos anotando com &lt;code&gt;@RepositoryRestResource&lt;/code&gt;.&lt;br&gt;
Com essa annotation o Spring irá fazer uma linda magia e apenas com essa interface ele já ira criar nossa camada de Repository que saberá receber nosso modelo Person e executar todas as tarefas de &lt;strong&gt;CRUD&lt;/strong&gt; em nosso Banco de Dados, além disso ele criar uma camada de Controller internamente e irá expor esse nosso CRUD através de uma &lt;strong&gt;API REST&lt;/strong&gt;.&lt;br&gt;
Isso mesmo, não teremos que criar nem a nossa camada Service nem a nossa camada Controller, Automágicamente o Spring fará esse trabalha para nós através do &lt;strong&gt;Spring Rest Repositories&lt;/strong&gt; =).&lt;br&gt;
E ainda herdamos nossa interface de “PagingAndSortingRepository” que irá gerar nossas listas paginada, mais uma vez Automágicamente =).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Neste momento se executarmos nossa aplicação já temos uma &lt;strong&gt;API REST&lt;/strong&gt; com todas as operações &lt;strong&gt;CRUD&lt;/strong&gt; de Person além de um endpoint de consulta por “&lt;strong&gt;LastName&lt;/strong&gt;”.&lt;/p&gt;

&lt;p&gt;Aqui a lista de endpoints disponíveis na nossa &lt;strong&gt;API REST&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GET http://localhost:8080
GET http://localhost:8080/people
GET http://localhost:8080/people/{id}
GET http://localhost:8080/people/search
POST http://localhost:8080/people
PUT http://localhost:8080/people/{id}
PATCH http://localhost:8080/people/{id}
DELETE http://localhost:8080/people/{id}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;PUT&lt;/strong&gt; substitui um registro inteiro. Campos não fornecidos serão substituídos por null. &lt;br&gt;
&lt;strong&gt;PATCH&lt;/strong&gt; pode ser usado para atualizar um subconjunto de itens.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Segue alguns exemplos de Teste utilizando o &lt;strong&gt;curl&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;POST&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ curl -i -X POST -H "Content-Type:application/json" -d '{"firstName": "Frodo", "lastName": "Baggins"}' 


http://localhost:8080/people
HTTP/1.1 201 
Location: http://localhost:8080/people/1
Content-Type: application/hal+json;charset=UTF-8
Transfer-Encoding: chunked
Date: Mon, 04 Feb 2019 21:03:47 GMT
{
  "firstName" : "Frodo",
  "lastName" : "Baggins",
  "_links" : {
    "self" : {
      "href" : "http://localhost:8080/people/1"
    },
    "person" : {
      "href" : "http://localhost:8080/people/1"
    }
  }
}%
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;GET All&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ curl http://localhost:8080/people  


{
  "_embedded" : {
    "people" : [ {
      "firstName" : "Frodo",
      "lastName" : "Baggins",
      "_links" : {
        "self" : {
          "href" : "http://localhost:8080/people/1"
        },
        "person" : {
          "href" : "http://localhost:8080/people/1"
        }
      }
    } ]
  },
  "_links" : {
    "self" : {
      "href" : "http://localhost:8080/people{?page,size,sort}",
      "templated" : true
    },
    "profile" : {
      "href" : "http://localhost:8080/profile/people"
    },
    "search" : {
      "href" : "http://localhost:8080/people/search"
    }
  },
  "page" : {
    "size" : 20,
    "totalElements" : 1,
    "totalPages" : 1,
    "number" : 0
  }
}%

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Perceba neste exemplo que o resultado é paginado com: size, totalElements, totalPages, number.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Adicionando Swagger
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Adicione as dependências no &lt;code&gt;pom.xml&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- Swagger --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;io.springfox&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;springfox-swagger2&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;3.0.0-SNAPSHOT&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;io.springfox&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;springfox-data-rest&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;3.0.0-SNAPSHOT&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;io.springfox&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;springfox-swagger-ui&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;3.0.0-SNAPSHOT&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Adicione também no &lt;code&gt;pom.xml&lt;/code&gt; o repositório da dependência:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;repositories&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;repository&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;id&amp;gt;&lt;/span&gt;jcenter-snapshots&lt;span class="nt"&gt;&amp;lt;/id&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;name&amp;gt;&lt;/span&gt;jcenter&lt;span class="nt"&gt;&amp;lt;/name&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;url&amp;gt;&lt;/span&gt;http://oss.jfrog.org/artifactory/oss-snapshot-local/&lt;span class="nt"&gt;&amp;lt;/url&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;/repository&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/repositories&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;É importante adicionar esse repository porque no repositório central ainda não tem essa versão do swagger, e é nela que estão implementando essa feature do Swagger para suportar o Spring Rest Repositories.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ol&gt;
&lt;li&gt;A classe &lt;code&gt;Configuration&lt;/code&gt; do &lt;strong&gt;Swagger&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.beans.factory.annotation.Value&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.context.annotation.Bean&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.context.annotation.Configuration&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.context.annotation.Import&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;springfox.documentation.builders.ApiInfoBuilder&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;springfox.documentation.builders.PathSelectors&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;springfox.documentation.builders.RequestHandlerSelectors&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;springfox.documentation.service.ApiInfo&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;springfox.documentation.spi.DocumentationType&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;springfox.documentation.spring.data.rest.configuration.SpringDataRestConfiguration&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;springfox.documentation.spring.web.plugins.Docket&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;springfox.documentation.swagger2.annotations.EnableSwagger2WebMvc&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="nd"&gt;@Configuration&lt;/span&gt;
&lt;span class="nd"&gt;@EnableSwagger2WebMvc&lt;/span&gt;
&lt;span class="nd"&gt;@Import&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;SpringDataRestConfiguration&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="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SwaggerConfiguration&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="no"&gt;PATH_MAPPING&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"/"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="no"&gt;PACKAGE_BASE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"com.eprogramar.demorepositoryrestresource"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="nd"&gt;@Value&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"${info.app.version}"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;projectVersion&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="nd"&gt;@Value&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"${info.app.name}"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;projectName&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="nd"&gt;@Value&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"${info.app.description}"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;projectDescription&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="nd"&gt;@Value&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"${spring.profiles.active}"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;activeProfile&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="nd"&gt;@Bean&lt;/span&gt;
    &lt;span class="nc"&gt;Docket&lt;/span&gt; &lt;span class="nf"&gt;rsApi&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="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Docket&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;DocumentationType&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;SWAGGER_12&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;apiInfo&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;apiInfo&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;select&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;apis&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;RequestHandlerSelectors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;any&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;paths&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;PathSelectors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;any&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;pathMapping&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="no"&gt;PATH_MAPPING&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;useDefaultResponseMessages&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;ApiInfo&lt;/span&gt; &lt;span class="nf"&gt;apiInfo&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="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;ApiInfoBuilder&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;projectName&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;projectDescription&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;" - Profile: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;activeProfile&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;projectVersion&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;build&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;Adicionei algumas properties no &lt;code&gt;application.properites&lt;/code&gt; só pra facilitar as coisas não seria uma coisa obrigatória.&lt;/p&gt;

&lt;p&gt;Ok, executando a aplicação agora podemos ver todos os endpoints documentados, acesse: &lt;code&gt;http://localhost:8080/swagger-ui.html&lt;/code&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--jKSDt_bf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/danovmjhy8p152keuefj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--jKSDt_bf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/danovmjhy8p152keuefj.png" alt="Swagger" width="800" height="418"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4ZHbKXun--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w7e9p5f5al1kuizz5awh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4ZHbKXun--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w7e9p5f5al1kuizz5awh.png" alt="Disclimer" width="150" height="150"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Veja Também meu video:&lt;br&gt;
“&lt;strong&gt;Como Criar uma API Rest Kotlin com Persistencia e Paginação em 6 minutos&lt;/strong&gt;”&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/iaOisrsTy48"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

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

&lt;p&gt;Neste artigo aprendemos utilizar algumas magias do Spring onde ele automatizou a criação de nosso &lt;strong&gt;ORM&lt;/strong&gt; e ainda criou nossa &lt;strong&gt;API REST&lt;/strong&gt; automágicamente.&lt;br&gt;
Com isso ganhamos muito tempo quando precisamos criar &lt;strong&gt;CRUD&lt;/strong&gt; e expor através de uma &lt;strong&gt;API REST&lt;/strong&gt;.&lt;br&gt;
Claro, em caso simples onde não precisamos de regras para nosso &lt;strong&gt;CRUD&lt;/strong&gt; isso pode ser uma boa opção, se combinar com Bean Validation para validar alguns campos e ainda utilizar de um Handle para interceptar os Erros e soltar uma mensagem mais amigável fica uma solução bem legal.&lt;br&gt;
Em casos onde tem muitas regras ai é aconselhável utilizar o modelo mais conceitual com a Camada &lt;strong&gt;Service&lt;/strong&gt; e &lt;strong&gt;Controller&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;O código pode ser visto no Github:&lt;br&gt;
&lt;a href="https://github.com/e-programar/demo-repository-rest-resource"&gt;https://github.com/e-programar/demo-repository-rest-resource&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Referencia: &lt;a href="https://spring.io/guides/gs/accessing-data-rest/"&gt;https://spring.io/guides/gs/accessing-data-rest/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>programming</category>
      <category>java</category>
      <category>mvp</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Desvendando o Spring Application Context</title>
      <dc:creator>Fabiano Góes • e-Programar</dc:creator>
      <pubDate>Sat, 05 Feb 2022 18:55:00 +0000</pubDate>
      <link>https://dev.to/fabianogoes/desvendando-o-spring-application-context-35c2</link>
      <guid>https://dev.to/fabianogoes/desvendando-o-spring-application-context-35c2</guid>
      <description>&lt;p&gt;&lt;a href="https://media.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%2F1v4ohxlcfva022dfz3ys.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F1v4ohxlcfva022dfz3ys.png" alt="Spring"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Este é um Post bem teórico, mas se você já trabalha ou está interessando em conhecer um pouco sobre &lt;strong&gt;Spring Framework&lt;/strong&gt; invista um tempinho para ler este conteúdo porque é extremamente importante.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;O &lt;strong&gt;Spring Framework&lt;/strong&gt; fornece um modelo abrangente de programação e configuração para aplicativos corporativos modernos baseados em &lt;strong&gt;Java&lt;/strong&gt; em qualquer tipo de plataforma de implantação.&lt;br&gt;
Um elemento chave do &lt;strong&gt;Spring&lt;/strong&gt; é o suporte de infra-estrutura no nível do aplicativo: o &lt;strong&gt;Spring&lt;/strong&gt; se concentra no “encanamento” dos aplicativos corporativos, para que as equipes possam se concentrar na lógica de negócios no nível do aplicativo, sem vínculos desnecessários a ambientes de implantação específicos.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fvftyo3r58dq7vlibgai3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fvftyo3r58dq7vlibgai3.png" alt="Disclamer"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;h2&gt;
  
  
  Um pouco de História
&lt;/h2&gt;

&lt;p&gt;Para quem está chegando no universo &lt;strong&gt;Java Web&lt;/strong&gt; agora e já chega aprendendo &lt;strong&gt;Spring Boot&lt;/strong&gt; não tem ideia de como era burocrático construir aplicações Web em &lt;strong&gt;Java&lt;/strong&gt; antes.&lt;br&gt;
Quando usávamos &lt;strong&gt;Java EE&lt;/strong&gt; e queríamos delegar responsabilidades para um contexto mais global do seu código tínhamos que fazer isso usando um Servidor de Aplicação, se queríamos por exemplo usar um pool de conexão ou uma mensageria, tínhamos que usar os tais Servidores de Aplicação por exemplo: JBoss(Red Hat), WebSphere(IBM), WebLogic(Oracle) e isso tornava tanto o desenvolvimento quanto o processo de implantação bem burocrático.&lt;br&gt;
Lógico que dependendo do Domínio que você estivesse desenvolvendo um Servidor de Aplicação era necessário, mas quando estava desenvolvendo uma aplicação simples isso era muito ruim, desde o setup de desenvolvimento até a implantação. Isso gerava uma curva de aprendizado bem grande quando as vezes queríamos apenas construir uma aplicação simples e implantar em um servidor simples também.&lt;br&gt;
Na época já tínhamos o &lt;em&gt;Tomcat&lt;/em&gt; que era bem simples de trabalhar, mas não era um &lt;em&gt;Servidor de Aplicação&lt;/em&gt; e sim um WebServer e não implementava as tais features de um Servidor de Aplicação.&lt;br&gt;
Ai nessa época veio o &lt;strong&gt;Spring Framework&lt;/strong&gt; com essa proposta de subir um Contexto(&lt;strong&gt;Application Context&lt;/strong&gt;) onde ele gerenciava objetos para sua aplicação, assim você poderia delegar tais responsabilidades para o Framework e se concentrar mais em suas Regras de Negócio, então conseguimos por exemplo usar as &lt;em&gt;Injeções de Dependências&lt;/em&gt; do &lt;strong&gt;Spring&lt;/strong&gt; e deixar a responsabilidade de gerenciar o ciclo de vida de Objetos em memoria para o Spring.&lt;br&gt;
E agora conseguíamos usando o &lt;strong&gt;Spring Framework&lt;/strong&gt; desfrutar de recursos de um Servidor de Aplicação usando apenas nosso querido Apache Tomcat. &lt;strong&gt;\o/&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2F2mlphfjtppaq5deh6c1r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F2mlphfjtppaq5deh6c1r.png" alt="Spring Projects"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  O tal de Aplication Context
&lt;/h2&gt;

&lt;p&gt;Todo aplicativo &lt;strong&gt;Spring&lt;/strong&gt; requer um &lt;em&gt;Contexto&lt;/em&gt;, um local onde todos os componentes são registrados. Poderíamos pensar nisso como um diretório central de instâncias de objetos criados e armazenados. Quando usamos o &lt;strong&gt;Spring Framework&lt;/strong&gt; e criamos algo, por exemplo, um conjunto de conexões, ele é registrado em nosso contexto ou quando criamos nossos próprios componentes(&lt;em&gt;Beans&lt;/em&gt;, veja meu artigo &lt;strong&gt;&lt;a href="https://dev.to/fabianogoes/desvendando-os-beans-do-spring-usando-kotlin-26c1"&gt;Desvendando os Beans&lt;/a&gt;&lt;/strong&gt; do &lt;em&gt;Spring&lt;/em&gt; usando Kotlin) eles também serão registrados neste Contexto. Portanto, se em outra parte do aplicativo precisamos de um desses componentes, em vez de criá-lo novamente, podemos usa-lo dentro da instancia do Contexto(&lt;strong&gt;IoC&lt;/strong&gt;).&lt;/p&gt;

&lt;p&gt;Toda essa troca de responsabilidade funciona basicamente com as Annotations, usamos uma &lt;em&gt;Annotation&lt;/em&gt; para dizer que o &lt;strong&gt;Spring&lt;/strong&gt; deve se Auto Configurar(&lt;code&gt;@EnableAutoConfiguration&lt;/code&gt;), uma outra Annotation para dizer onde o &lt;strong&gt;Spring&lt;/strong&gt; deve procurar por possíveis Componentes(&lt;code&gt;@ComponentScan&lt;/code&gt;), outras Annotations para dizer que o Spring deve se responsabilizar pela gerencia de estado deste Componente(&lt;code&gt;@Component&lt;/code&gt;, &lt;code&gt;@Service&lt;/code&gt;, &lt;code&gt;@Repository&lt;/code&gt;, &lt;code&gt;@Controller&lt;/code&gt;), e por fim quando queremos usar algum Componente desses que estão no tal Contexto usamos a Annotation &lt;code&gt;@Autowired&lt;/code&gt; e com ela dizemos para o Spring que ele deve procurar em seu Contexto algum Componente equivalente ao que precisamos e Injetar na variável onde estamos usando essa Annotation, e essa foi uma das primeiras features que justificava o uso do &lt;strong&gt;Spring Framework&lt;/strong&gt; que é: &lt;strong&gt;Spring IoC&lt;/strong&gt; que está dentro do pacote &lt;em&gt;Core&lt;/em&gt; Technologies do &lt;strong&gt;Spring&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fzld2075eqtsm4i3fk163.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fzld2075eqtsm4i3fk163.png" alt="Team"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Mas e a Configuração disso tudo ?
&lt;/h2&gt;

&lt;p&gt;Bom, aqui tocamos em um ponto de muita discussão desde sempre no mundo Java, Os tais XML de configuração. Nessa época, mesmo com o surgimento do tão amado Spring Framework ainda existia muitas XMLs de configuração, o que ainda deixava tudo muito burocrático.&lt;br&gt;
Tínhamos um servlet-context.xml onde precisávamos configurar um bocado de coisas e perdíamos muito tempo com isso.&lt;br&gt;
Se tiver curiosidade, segue um exemplo bem resumido de um xml desse:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?xml version="1.0" encoding="UTF-8"?&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;beans:beans&lt;/span&gt; &lt;span class="na"&gt;xmlns=&lt;/span&gt;&lt;span class="s"&gt;"http://www.springframework.org/schema/mvc"&lt;/span&gt;
    &lt;span class="na"&gt;xmlns:xsi=&lt;/span&gt;&lt;span class="s"&gt;"http://www.w3.org/2001/XMLSchema-instance"&lt;/span&gt;
    &lt;span class="na"&gt;xmlns:beans=&lt;/span&gt;&lt;span class="s"&gt;"http://www.springframework.org/schema/beans"&lt;/span&gt;
    &lt;span class="na"&gt;xmlns:context=&lt;/span&gt;&lt;span class="s"&gt;"http://www.springframework.org/schema/context"&lt;/span&gt;
    &lt;span class="na"&gt;xmlns:tx=&lt;/span&gt;&lt;span class="s"&gt;"http://www.springframework.org/schema/tx"&lt;/span&gt;
    &lt;span class="na"&gt;xsi:schemaLocation=&lt;/span&gt;&lt;span class="s"&gt;"http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;annotation-driven&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;resources&lt;/span&gt; &lt;span class="na"&gt;mapping=&lt;/span&gt;&lt;span class="s"&gt;"/resources/**"&lt;/span&gt; &lt;span class="na"&gt;location=&lt;/span&gt;&lt;span class="s"&gt;"/resources/"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;beans:bean&lt;/span&gt;
        &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"org.springframework.web.servlet.view.InternalResourceViewResolver"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;beans:property&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"prefix"&lt;/span&gt; &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;"/WEB-INF/views/"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;beans:property&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"suffix"&lt;/span&gt; &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;".jsp"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/beans:bean&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;context:component-scan&lt;/span&gt; &lt;span class="na"&gt;base-package=&lt;/span&gt;&lt;span class="s"&gt;"com.eprogramar.springjpa com.eprogramar.springjpa.dao"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;beans:bean&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/beans:bean&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;beans:bean&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"entityManagerFactory"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;beans:property&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"dataSource"&lt;/span&gt; &lt;span class="na"&gt;ref=&lt;/span&gt;&lt;span class="s"&gt;"dsSpringJPA"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;beans:property&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"jpaVendorAdapter"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;beans:bean&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/beans:property&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/beans:bean&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;beans:bean&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"dsSpringJPA"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"org.apache.commons.dbcp.BasicDataSource"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;beans:property&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"driverClassName"&lt;/span&gt; &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;"com.mysql.jdbc.Driver"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;beans:property&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"url"&lt;/span&gt; &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;"jdbc:mysql://localhost:3306/test"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;beans:property&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"username"&lt;/span&gt; &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;"root"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;beans:property&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"password"&lt;/span&gt; &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;"123"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/beans:bean&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;tx:annotation-driven&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;beans:bean&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"transactionManager"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"org.springframework.orm.jpa.JpaTransactionManager"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;beans:property&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"entityManagerFactory"&lt;/span&gt; &lt;span class="na"&gt;ref=&lt;/span&gt;&lt;span class="s"&gt;"entityManagerFactory"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/beans:bean&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/beans:beans&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Então tínhamos que configurar &lt;strong&gt;XML&lt;/strong&gt; para o &lt;strong&gt;Contexto do Spring&lt;/strong&gt;, &lt;em&gt;XML&lt;/em&gt; para configuração de &lt;em&gt;JPA/Hibernate&lt;/em&gt;, e isso era de fato muito burocrático, até a chegada do &lt;strong&gt;Spring Boot&lt;/strong&gt;(Deus abençoe o &lt;strong&gt;Spring Boot&lt;/strong&gt;) ai sim as coisas começaram a ficar produtivas e divertidas no desenvolvimento Java principalmente para a Aplicações Web.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Spring Boot&lt;/strong&gt; merece um artigo dedicado a ele e vou tentar fazer isso em breve, por hora quero apenas trazer minha humilde opinião sobre quem viveu essa evolução e pode desfrutar dos ganhos de verdade. Isso é bem diferente de quem chega hoje e pega a coisa toda pronta.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Dito isso, quero finalizar ilustrando a configuração necessário hoje com o &lt;strong&gt;Spring Boot&lt;/strong&gt;, esse é um exemplo utilizando Spring em uma aplicação &lt;em&gt;Kotlin&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2F6bptehbd5vrftb11s294.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F6bptehbd5vrftb11s294.png" alt="Spring Application"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Se olharmos essa Annotation &lt;code&gt;@SpringBootApplication&lt;/code&gt; por dentro veremos que ela tem outras Annotations bem interessantes por exemplo a &lt;code&gt;@ComponentScan&lt;/code&gt; que é responsável por dizer para o Spring, onde ele deve procurar por Classes que devem ser gerenciadas como um Bean e devem ser registradas no &lt;strong&gt;Application Context&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2F64yi93c7rwdm0sjytafc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F64yi93c7rwdm0sjytafc.png" alt="Spring Component"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Uma vez que temos o &lt;strong&gt;Entrypoint&lt;/strong&gt; de nossa aplicação anotada com @SpringBootApplication, o Spring usará como ponto de partida para fazer o &lt;strong&gt;Scan&lt;/strong&gt;, e todas os pacotes desse nível para dentro serão escaneados em busca de possíveis Beans, e você pode usar a Annotation @ComponentScan para customizar e ensinar o Spring à procurar por Beans em outros pacotes, por exemplo em libs que você possa estar usando dentro de sua empresa.&lt;/p&gt;
&lt;/blockquote&gt;

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

&lt;p&gt;O &lt;strong&gt;Spring Application Context&lt;/strong&gt; é uma peça fundamental dentro do ecossistema do &lt;em&gt;Framework&lt;/em&gt; e é muito importante o desenvolvedor entender como ele funciona uma vez que decide usar esse fantástico framework que o &lt;strong&gt;Spring&lt;/strong&gt;.&lt;br&gt;
Esse foi um artigo bem teórico mas muito necessário, espero que gostem e que seja útil no seu desenvolvimento como Programador.&lt;br&gt;
um forte abraço e até a próxima.&lt;/p&gt;

&lt;h2&gt;
  
  
  Referências
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://spring.io/projects/spring-framework#overview" rel="noopener noreferrer"&gt;https://spring.io/projects/spring-framework#overview&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.spring.io/spring/docs/current/spring-framework-reference/core.html" rel="noopener noreferrer"&gt;https://docs.spring.io/spring/docs/current/spring-framework-reference/core.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/@fabiano_goes/desvendando-os-beans-do-spring-usando-kotlin-59dc55934caa" rel="noopener noreferrer"&gt;https://medium.com/@fabiano_goes/desvendando-os-beans-do-spring-usando-kotlin-59dc55934caa&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>java</category>
      <category>kotlin</category>
      <category>programming</category>
      <category>springframework</category>
    </item>
    <item>
      <title>API REST ?</title>
      <dc:creator>Fabiano Góes • e-Programar</dc:creator>
      <pubDate>Sat, 31 Jul 2021 23:35:01 +0000</pubDate>
      <link>https://dev.to/fabianogoes/api-rest-37ba</link>
      <guid>https://dev.to/fabianogoes/api-rest-37ba</guid>
      <description>&lt;h2&gt;
  
  
  Mas e o protocolo HTTP que é a base para a API REST você conhece ?
&lt;/h2&gt;

&lt;h3&gt;
  
  
  O Protocolo
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;API&lt;/strong&gt; = Application Programming Interface&lt;br&gt;
&lt;strong&gt;REST&lt;/strong&gt; = Representational State Transfer&lt;/p&gt;

&lt;p&gt;Basicamente a API REST foi criada para possibilitar a comunicação entre sistemas, e para que seja possível essa comunicação precisamos de um Protocolo, e é ai que entra o HTTP.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--DvF0Firh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/i0ws60dpbl0xf7ol57sw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--DvF0Firh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/i0ws60dpbl0xf7ol57sw.png" alt="image" width="689" height="397"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Funcionamento
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;HTTP&lt;/strong&gt; utiliza o modelo Cliente-Servidor, como a maioria dos protocolos de rede, baseando-se no paradigma de &lt;strong&gt;Requisição&lt;/strong&gt; e &lt;strong&gt;Resposta&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;Um programa requisitante (Cliente) estabelece uma conexão com um outro programa receptor (Servidor) e envia-lhe uma requisição, contendo a &lt;strong&gt;URI&lt;/strong&gt;, a versão do protocolo, uma mensagem &lt;strong&gt;MIME&lt;/strong&gt; contendo os modificadores da requisição, informações sobre o cliente e, possivelmente, o conteúdo no corpo da mensagem.&lt;/p&gt;

&lt;p&gt;O Servidor processa a Requisição(Request) e Responde(Responnse) com um &lt;strong&gt;Status&lt;/strong&gt; incluindo sua versão de protocolo e com os códigos de erro informando se a operação foi bem sucedida ou não.&lt;br&gt;
Após o envio da resposta pelo servidor, encerra-se a conexão estabelecida.&lt;/p&gt;

&lt;h3&gt;
  
  
  A Mensagem
&lt;/h3&gt;

&lt;p&gt;Uma &lt;strong&gt;Mensagem&lt;/strong&gt;, tanto de Requisição(Request) quanto de Resposta(Response), é composta por: Cabeçalhos(&lt;strong&gt;header&lt;/strong&gt;) e Corpo(&lt;strong&gt;body&lt;/strong&gt;). &lt;/p&gt;

&lt;p&gt;Toda Requisição(&lt;strong&gt;Request&lt;/strong&gt;) é enviada através de um Comando ou Métodos HTTP e os mais comum são:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;POST&lt;/li&gt;
&lt;li&gt;GET&lt;/li&gt;
&lt;li&gt;PUT&lt;/li&gt;
&lt;li&gt;PATCH&lt;/li&gt;
&lt;li&gt;DELETE&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Toda Resposta(&lt;strong&gt;Response&lt;/strong&gt;) segue com um Código de Estado(HTTP &lt;strong&gt;Status&lt;/strong&gt;) exemplos: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;200(OK)&lt;/li&gt;
&lt;li&gt;404(Not Found)&lt;/li&gt;
&lt;li&gt;500(Internal Server Error) &lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Content-Type
&lt;/h3&gt;

&lt;p&gt;Quando uma mensagem HTTP tiver um corpo, poderão ser incluídos cabeçalhos de entidades que descrevem suas características, como por exemplo, o &lt;strong&gt;Content-Type&lt;/strong&gt; que informa o tipo &lt;strong&gt;MIME&lt;/strong&gt; dos dados no corpo da mensagem. &lt;br&gt;
Alguns tipos MIME:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;text/plain(Arquivo no formato &lt;strong&gt;Texto&lt;/strong&gt; ASCII)&lt;/li&gt;
&lt;li&gt;text/html(Arquivo no formato &lt;strong&gt;HTML&lt;/strong&gt;, utilizado como padrão para documentos Web)&lt;/li&gt;
&lt;li&gt;image/gif(Imagem no formato &lt;strong&gt;GIF&lt;/strong&gt;)&lt;/li&gt;
&lt;li&gt;image/jpeg(Imagem no formato &lt;strong&gt;JPEG&lt;/strong&gt;)&lt;/li&gt;
&lt;li&gt;application/zip(Arquivo compactado)&lt;/li&gt;
&lt;li&gt;application/json(Arquivo no formato &lt;strong&gt;JSON&lt;/strong&gt;)&lt;/li&gt;
&lt;li&gt;application/xml(Arquivo no formato &lt;strong&gt;XML&lt;/strong&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;O formato &lt;strong&gt;application/json&lt;/strong&gt; é um formato muito utilizado em &lt;strong&gt;API REST&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Conceitos
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--05MfpR0Z--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ft4hlwqvk88qbltnz8un.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--05MfpR0Z--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ft4hlwqvk88qbltnz8un.png" alt="dev1" width="389" height="308"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;A intenção aqui foi fazer apenas uma breve abordagem sobre os &lt;strong&gt;Conceitos&lt;/strong&gt; por traz de &lt;strong&gt;API REST&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Entendendo a base &lt;strong&gt;HTTP&lt;/strong&gt; e o problema que a &lt;strong&gt;API REST&lt;/strong&gt; se propõe a resolver, conseguimos utilizar as &lt;em&gt;Linguagens&lt;/em&gt; de &lt;em&gt;Programação&lt;/em&gt; e Frameworks de fato como ferramentas para resolvermos um problema.&lt;/p&gt;

&lt;p&gt;E a base sempre será a mesma independente de &lt;em&gt;Linguagem&lt;/em&gt; ou &lt;em&gt;Framework&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Deixei seu comentário sobre o que achou do Post, compartilhe em suas redes e ajude a fortalecer uma comunidade onde &lt;strong&gt;juntos somos mais fortes&lt;/strong&gt;! &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--33u_ywWK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gm5rca7b8z58f2wr8d1s.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--33u_ywWK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gm5rca7b8z58f2wr8d1s.png" alt="person3" width="693" height="693"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>api</category>
      <category>rest</category>
      <category>http</category>
      <category>web</category>
    </item>
    <item>
      <title>Desvendando os Beans do Spring usando Kotlin</title>
      <dc:creator>Fabiano Góes • e-Programar</dc:creator>
      <pubDate>Thu, 17 Jun 2021 18:18:00 +0000</pubDate>
      <link>https://dev.to/fabianogoes/desvendando-os-beans-do-spring-usando-kotlin-26c1</link>
      <guid>https://dev.to/fabianogoes/desvendando-os-beans-do-spring-usando-kotlin-26c1</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Tenho visto pessoas usando o Spring Framework de forma totalmente mecânica, sem saber &lt;strong&gt;O QUE&lt;/strong&gt; e &lt;strong&gt;O POR QUÊ&lt;/strong&gt; decoram as classes com as Annotations: @Controller, @RestController, @Service, @Repository, @Component e etc.&lt;br&gt;
Hoje vamos entender um pouco sobre o que acontece por traz dessas Annotations.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;O que acontece na prática, é que decoramos que devemos estruturar nosso projeto com os seguintes packages: controller, service, repository.&lt;br&gt;
&lt;a href="https://media.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%2F9pejc8pse9au99fa6x8g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F9pejc8pse9au99fa6x8g.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;E que toda classe no package &lt;strong&gt;controller&lt;/strong&gt; deve ser anotada com &lt;code&gt;@Controller&lt;/code&gt; ou &lt;code&gt;@RestController&lt;/code&gt;.&lt;br&gt;
Toda classe no package &lt;strong&gt;service&lt;/strong&gt; deve ser anotada com &lt;code&gt;@Service&lt;/code&gt;.&lt;br&gt;
Toda classe no package &lt;strong&gt;repository&lt;/strong&gt; deve ser anotada com &lt;code&gt;@Repository&lt;/code&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;E as classes de modelo que ficam no package &lt;strong&gt;model&lt;/strong&gt; não precisam ser anotadas&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Então, quando precisamos usar algumas dessas classes anotadas, usamos o mágico &lt;code&gt;@Autowired&lt;/code&gt;.&lt;br&gt;
Com isso em mente, usamos uma IDE ou o site Spring Initializr para criar nossos projetos, aplicamos a ideia acima de packages e Annotations e voilà, tudo funciona magicamente, bola pra frente, check no LinkedIn que manjo tudo de &lt;strong&gt;Spring Framework&lt;/strong&gt; ;)&lt;br&gt;
&lt;a href="https://media.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%2Fmtxjdwukwl7r6hw0hg0d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fmtxjdwukwl7r6hw0hg0d.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;E de verdade, não vejo problema em começar assim, acho legal começar simplesmente codando e vendo as coisas funcionarem, mas acho que na sequencia, é preciso se esforçar um pouquinho para entender o que aconteceu e o que exatamente o &lt;strong&gt;Framework&lt;/strong&gt; resolveu para nós.&lt;/p&gt;
&lt;h2&gt;
  
  
  Component Scan
&lt;/h2&gt;

&lt;p&gt;Bom, dado o problema, vamos tentar esclarecer um pouco as coisas.&lt;br&gt;
Quando criamos um projeto usando &lt;strong&gt;Spring&lt;/strong&gt; como &lt;strong&gt;Framework Web&lt;/strong&gt;, durante o Boot da aplicação existem alguns processos que o &lt;strong&gt;Spring&lt;/strong&gt; executa para preparar esse ambiente, e um desses processo se chama "&lt;strong&gt;Component Scan&lt;/strong&gt;".&lt;br&gt;
Na prática, o &lt;strong&gt;Spring&lt;/strong&gt; Escaneia nossos pacotes em busca de classes Anotadas com Estereótipos: &lt;code&gt;@Component&lt;/code&gt; e suas especializações como &lt;code&gt;@Controller&lt;/code&gt;, &lt;code&gt;@RestController&lt;/code&gt;, &lt;code&gt;@Service&lt;/code&gt;, &lt;code&gt;@Repository&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Podemos usar a Annotation &lt;code&gt;@ComponentScan&lt;/code&gt; para customizar onde queremos que o &lt;strong&gt;Spring&lt;/strong&gt; procure classes &lt;strong&gt;Beans&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="nd"&gt;@ComponentScan&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"com.example.demo"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyCustomScan&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Cada classe que o &lt;strong&gt;Spring&lt;/strong&gt; encontrar, ele vai registrar em um Container chamado "&lt;strong&gt;ApplicationContext&lt;/strong&gt;", a partir daí essa classe virou um &lt;strong&gt;Bean&lt;/strong&gt;.&lt;br&gt;
O que ele faz é tentar instanciar essas classes e adicioná-las em uma lista de &lt;strong&gt;Bean&lt;/strong&gt; (Spring-managed).&lt;br&gt;
Então ele passa por todos os &lt;code&gt;@Autowired&lt;/code&gt; e procura em sua lista de &lt;strong&gt;Beans&lt;/strong&gt; algum &lt;strong&gt;Bean&lt;/strong&gt; que equivalente. &lt;br&gt;
Assim sua aplicação sobe com as classes magicamente instanciadas e Injetadas.&lt;/p&gt;
&lt;h2&gt;
  
  
  The IoC container
&lt;/h2&gt;

&lt;p&gt;O &lt;strong&gt;Spring Framework&lt;/strong&gt; aplica o princípio de Inversão de Controle IoC (&lt;strong&gt;I&lt;/strong&gt;nversion &lt;strong&gt;O&lt;/strong&gt;f &lt;strong&gt;C&lt;/strong&gt;ontrol). IoC também é conhecido como injeção de dependência (DI). É um processo pelo qual os objetos definem suas dependências, ou seja, os outros objetos com os quais trabalham, apenas por meio de argumentos do construtor, argumentos para um método de fábrica ou propriedades que são definidas na instância do objeto após serem construídas ou retornadas a partir de um método de fábrica. O contêiner injeta essas dependências quando criar o &lt;strong&gt;Bean&lt;/strong&gt;. Esse processo é fundamentalmente o inverso, daí o nome Inversion of Control (IoC), do próprio &lt;strong&gt;Bean&lt;/strong&gt; que controla a instanciação ou localização de suas dependências, usando a construção direta de classes ou um mecanismo como o padrão Service Locator.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Aqui vale uma observação importante: é uma boa prática programar para Interface e não para Implementações, assim mantendo suas classes com baixo acoplamento. &lt;br&gt;
Então, onde queremos Injetar nossas classes com &lt;code&gt;@Autowired&lt;/code&gt; criamos as variáveis ou parâmetros do tipo da Interface e não da Implementação, ai o Spring tem o trabalho de encontrar algum &lt;strong&gt;Bean&lt;/strong&gt; que implemente aquela Interface para então injetar.&lt;/p&gt;
&lt;/blockquote&gt;


&lt;h2&gt;
  
  
  Exemplo prático
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;PersonService&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;findAll&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nd"&gt;@Service&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PersonServiceImpl&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;PersonService&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;findAll&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Returning all people"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nd"&gt;@RestController&lt;/span&gt;
&lt;span class="nd"&gt;@RequestMapping&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/people"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PersonController&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="nd"&gt;@Autowired&lt;/span&gt;
    &lt;span class="k"&gt;lateinit&lt;/span&gt; &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="py"&gt;personService&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;PersonService&lt;/span&gt;

    &lt;span class="nd"&gt;@GetMapping&lt;/span&gt;
    &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;findAll&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;personService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findAll&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Neste exemplo criamos uma interface &lt;strong&gt;PersonInterface&lt;/strong&gt; e implementamos essa interface através da classe &lt;strong&gt;PersonServiceImpl&lt;/strong&gt; e anotamos a classe com &lt;code&gt;@Service&lt;/code&gt;.&lt;br&gt;
Então no controller &lt;strong&gt;PersonController&lt;/strong&gt; pedimos para o Spring Injetar uma &lt;strong&gt;PersonService&lt;/strong&gt; por meio do &lt;code&gt;@Autowired&lt;/code&gt;.&lt;br&gt;
Perceba que criamos a variável do tipo da Interface e não da classe e deixamos a critério do Spring encontrar em sua lista de &lt;strong&gt;Beans&lt;/strong&gt; uma implementação equivalente.&lt;br&gt;
Uma outra maneira de fazer essa Injeção de Dependência é usando o &lt;em&gt;construtor&lt;/em&gt; invés de um atributo da classe, vamos ver como ficaria:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="nd"&gt;@RestControllerSpring-managed&lt;/span&gt;
&lt;span class="nd"&gt;@RequestMapping&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/people"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PersonController&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;personService&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;PersonService&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="nd"&gt;@GetMapping&lt;/span&gt;
    &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;findAll&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;personService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findAll&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  O QUE aconteceu até aqui ?
&lt;/h2&gt;

&lt;p&gt;Quando executarmos nossa aplicação o &lt;strong&gt;Spring&lt;/strong&gt; começará a fazer sua magia.&lt;br&gt;
Passando pelo processo de &lt;strong&gt;Component Scan&lt;/strong&gt;, ele perceberá que temos nossa classe &lt;strong&gt;PersonService&lt;/strong&gt; anotada com &lt;code&gt;@Service&lt;/code&gt;, irá instanciar essa classe e registrá-la em seu &lt;strong&gt;ApplicationContext&lt;/strong&gt;, tornando nossa classe um &lt;strong&gt;Bean&lt;/strong&gt; &lt;em&gt;Spring-managed&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Então ele continua o processo e encontra na classe &lt;strong&gt;PersonController&lt;/strong&gt; anotada com &lt;code&gt;@RestController&lt;/code&gt;, logo ele sabe que precisa Instanciar essa classe e registrá-la no &lt;strong&gt;ApplicationContext&lt;/strong&gt;. Porém, essa classe tem uma dependência em seu Construtor e ele percebe que essa dependência é uma Interface, então ele percorre sua lista de &lt;strong&gt;Beans&lt;/strong&gt;, em busca de alguém que implemente essa Interface. Encontra nossa implementação &lt;strong&gt;PersonServiceImpl&lt;/strong&gt; e aplica a &lt;em&gt;IoC | DI&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Perceba que não precisamos usar o &lt;code&gt;@Autowired&lt;/code&gt; no construtor, e não teria problema em usar, funcionaria do mesmo jeito, mas o &lt;strong&gt;Spring&lt;/strong&gt; é inteligente o suficiente para saber que para instanciar o &lt;strong&gt;PersonController&lt;/strong&gt; ele precisa Injetar o &lt;strong&gt;PersonService&lt;/strong&gt; que é uma dependência do construtor, até porque usamos val que irá criar um atributo da classe somente leitura e imutável, então é obrigatório a passagem do valor neste momento.&lt;br&gt;
A partir daí o Contexto do &lt;strong&gt;Spring&lt;/strong&gt; é carregado com nossas classes instanciadas e quem está controlando o ciclo de vida desses objetos é o próprio &lt;strong&gt;Spring&lt;/strong&gt;.&lt;br&gt;
Se você está atento a tudo o que aconteceu você deve ter se perguntado:&lt;br&gt;
Mas e se eu tiver duas implementações da Interface &lt;strong&gt;PersonService&lt;/strong&gt;, como o Spring saberia qual Injetar ???? :(&lt;/p&gt;

&lt;p&gt;Vamos criar mais uma implementação e testar esse comportamento do Spring:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Service&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CustomPersonServiceImpl&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;PersonService&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;findAll&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"CustomPersonServiceImpl - Returning all people"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Se executarmos nossa aplicação, veja o comportamento do Spring:&lt;br&gt;
&lt;a href="https://media.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%2Ftoiotik1d4t264wgcq8u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Ftoiotik1d4t264wgcq8u.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Veja que foi lançado um &lt;em&gt;Erro&lt;/em&gt; ao iniciar o &lt;strong&gt;ApplicationContext&lt;/strong&gt;, ele encontrou nossas duas implementações e não soube o que fazer. Neste caso precisamos dizer para ele o que queremos, e perceba que ele até sugeriu uma solução que é anotar uma de nossas implementações com &lt;code&gt;@Primary&lt;/code&gt;. Vamos fazer isso anotando nossa primeira implementação com &lt;code&gt;@Primary&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Primary&lt;/span&gt;
&lt;span class="nd"&gt;@Service&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PersonServiceImpl&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;PersonService&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;findAll&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Returning all people"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agora se executarmos novamente nossa aplicação tudo estará funcionando.&lt;br&gt;
Mas e quando precisarmos que ele Injete nossa segunda implementação??&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&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="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/custom-people"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CustomPersonController&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nd"&gt;@Qualifier&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"customPersonServiceImpl"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;personService&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;PersonService&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nd"&gt;@GetMapping&lt;/span&gt;
    &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;findAll&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;personService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findAll&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Criei um novo controller &lt;strong&gt;CustomPersonController&lt;/strong&gt; e nele quero que seja injetado nossa segunda implementação de &lt;strong&gt;PersonService&lt;/strong&gt; - &lt;strong&gt;CustomPersonServiceImpl&lt;/strong&gt;. &lt;br&gt;
Para isso usei a Annotation &lt;code&gt;@Qualifier&lt;/code&gt;, passando como value o nome da implementação começando com &lt;em&gt;LowerCase&lt;/em&gt; &lt;code&gt;@Qualifier(“customPersonServiceImpl”)&lt;/code&gt;. &lt;br&gt;
Isso é possível porque quando o Spring está registrando os &lt;strong&gt;Beans&lt;/strong&gt; no &lt;strong&gt;ApplicationContext&lt;/strong&gt;, ele usa o próprio nome da classe começando com LowerCase, uma prática muito comum utilizado por qualquer programador que vem de &lt;strong&gt;Java&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Se quisermos customizar o nome de nossos &lt;strong&gt;Beans&lt;/strong&gt; podemos passar como value da Annotation &lt;code&gt;@Service(“myCustomPersonServiceImpl”)&lt;/code&gt; e depois usamos este mesmo nome no &lt;code&gt;@Qualifier(“myCustomPersonServiceImpl”)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Poderíamos ir um pouco além do convencional, imagine que vc tem classes de domínio que você gostaria que o Spring usasse como um &lt;strong&gt;Bean&lt;/strong&gt; Spring-managed, porém, você não quer acoplar seu domínio a nenhum Framework, então não quer anotar nenhum de suas classes de domínio com &lt;code&gt;@Service&lt;/code&gt; ou &lt;code&gt;@Component&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;Vamos resolver isso:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;PersonService&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;findAll&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PersonServiceImpl&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;PersonService&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;findAll&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"PersonServiceImpl Returning all people"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CustomPersonServiceImpl&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;PersonService&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;findAll&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"CustomPersonServiceImpl - Returning all people"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Tiramos as Annotations &lt;code&gt;@Service&lt;/code&gt; e agora nossas classes de Serviço/Domínio não estão acopladas ao &lt;strong&gt;Spring&lt;/strong&gt;. &lt;br&gt;
Mas queremos que em algum momento, o &lt;strong&gt;Spring&lt;/strong&gt; registre elas no &lt;em&gt;ApplicationContext&lt;/em&gt; para ser injetada em algum lugar fora da nossa camada de Domínio, por exemplo na camada de &lt;strong&gt;Controller&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Configuration&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PersonConfiguration&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="nd"&gt;@Primary&lt;/span&gt;
    &lt;span class="nd"&gt;@Bean&lt;/span&gt;
    &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;personServiceImpl&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nc"&gt;PersonService&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;PersonServiceImpl&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="nd"&gt;@Bean&lt;/span&gt;
    &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;customPersonServiceImpl&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nc"&gt;PersonService&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt;    &lt;span class="nc"&gt;CustomPersonServiceImpl&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Criamos uma classe de configuração anotando com &lt;code&gt;@Configuration&lt;/code&gt;, onde usamos a Annotation &lt;code&gt;@Bean&lt;/code&gt; sobre uma &lt;em&gt;function&lt;/em&gt; que tem como tipo de retorno nossa &lt;em&gt;Interface&lt;/em&gt;. &lt;br&gt;
Só que em cada um retornamos uma instância diferente e, por convenção, usamos o nome da &lt;em&gt;function&lt;/em&gt; como o nome da classe começando com LowerCase, usando a mesma regra do &lt;strong&gt;Spring&lt;/strong&gt; quando está registrando os &lt;strong&gt;Beans&lt;/strong&gt; em seu &lt;em&gt;ApplicationContext&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Então, agora quando acontecer o "&lt;strong&gt;Component Scan&lt;/strong&gt;" ele perceberá que tem uma classe &lt;code&gt;@Configuration&lt;/code&gt; que está solicitando para o &lt;strong&gt;Spring&lt;/strong&gt; register alguns &lt;strong&gt;Beans&lt;/strong&gt; no &lt;em&gt;ApplicationContext&lt;/em&gt;. &lt;br&gt;
A partir daí tudo volta a funcionar, mas resolvemos o problema de acoplamento do Framework em nossas classes de domínio e perceba que usamos novamente a Annotation &lt;code&gt;@Primary&lt;/code&gt; para direcionar o &lt;strong&gt;Spring&lt;/strong&gt; que quando ele encontrar uma Injection da nossa Interface &lt;strong&gt;PersonService&lt;/strong&gt; sem um &lt;code&gt;@Qualifier&lt;/code&gt; ele deve priorizar o &lt;strong&gt;Bean&lt;/strong&gt; personServiceImpl.&lt;/p&gt;

&lt;p&gt;Para finalizar, quero só explicar que as Annotations &lt;code&gt;@Controller&lt;/code&gt;, &lt;code&gt;@RestController&lt;/code&gt;, &lt;code&gt;@Service&lt;/code&gt;, &lt;code&gt;@Repository&lt;/code&gt; são todas especializações de &lt;code&gt;@Component&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;@Target&lt;/span&gt;&lt;span class="o"&gt;({&lt;/span&gt;&lt;span class="nc"&gt;ElementType&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;TYPE&lt;/span&gt;&lt;span class="o"&gt;})&lt;/span&gt;
&lt;span class="nd"&gt;@Retention&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;RetentionPolicy&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;RUNTIME&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="nd"&gt;@Documented&lt;/span&gt;
&lt;span class="nd"&gt;@Component&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nd"&gt;@interface&lt;/span&gt; &lt;span class="nc"&gt;Controller&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;span class="nd"&gt;@Target&lt;/span&gt;&lt;span class="o"&gt;({&lt;/span&gt;&lt;span class="nc"&gt;ElementType&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;TYPE&lt;/span&gt;&lt;span class="o"&gt;})&lt;/span&gt;
&lt;span class="nd"&gt;@Retention&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;RetentionPolicy&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;RUNTIME&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="nd"&gt;@Documented&lt;/span&gt;
&lt;span class="nd"&gt;@Component&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nd"&gt;@interface&lt;/span&gt; &lt;span class="nc"&gt;Service&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;span class="nd"&gt;@Target&lt;/span&gt;&lt;span class="o"&gt;({&lt;/span&gt;&lt;span class="nc"&gt;ElementType&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;TYPE&lt;/span&gt;&lt;span class="o"&gt;})&lt;/span&gt;
&lt;span class="nd"&gt;@Retention&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;RetentionPolicy&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;RUNTIME&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="nd"&gt;@Documented&lt;/span&gt;
&lt;span class="nd"&gt;@Component&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nd"&gt;@interface&lt;/span&gt; &lt;span class="nc"&gt;Repository&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;O que são apenas &lt;em&gt;stereotype&lt;/em&gt; para deixar mais explícito o que as classes anotadas com elas quer tratar:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Service = Business&lt;/li&gt;
&lt;li&gt;Repository = Data&lt;/li&gt;
&lt;li&gt;Controller = Web&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;E em alguns casos, por exemplo, &lt;code&gt;@Repository&lt;/code&gt; o &lt;strong&gt;Spring&lt;/strong&gt; vai tratar diferente as &lt;em&gt;Exceptions&lt;/em&gt;. &lt;br&gt;
Uma vantagem de usar esta anotação é que ela possui a tradução automática de exceção de persistência ativada. &lt;br&gt;
E ao usar uma estrutura de persistência como o &lt;em&gt;Hibernate&lt;/em&gt;, as exceções ativas lançadas usarão classes anotadas com &lt;code&gt;@Repository&lt;/code&gt; para lançar automaticamente convertidas em subclasses do &lt;em&gt;DataAccessExeption&lt;/em&gt; do &lt;strong&gt;Spring&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  O POR QUÊ devemos usar tudo isso ?
&lt;/h2&gt;

&lt;p&gt;Isso é importante para podermos tirar um maior proveito do &lt;em&gt;Framework&lt;/em&gt; que estamos utilizando. &lt;br&gt;
Assim, usamos o &lt;em&gt;Framework&lt;/em&gt; para resolver problemas de implementação de alguns &lt;em&gt;Patterns&lt;/em&gt;, por exemplo &lt;strong&gt;MVC&lt;/strong&gt;, &lt;strong&gt;IoC/DI&lt;/strong&gt;, &lt;strong&gt;DAO/Repository&lt;/strong&gt;, e ainda deixamos a cargo do &lt;em&gt;Framework&lt;/em&gt; a responsabilidade de gerenciar o Ciclo de Vida dos nossos Objetos/Beans.&lt;/p&gt;

&lt;p&gt;Com isso conseguimos deixar nosso código mais coeso e menos acoplado melhorando o &lt;em&gt;Design&lt;/em&gt; do Software e ainda facilitando a implementação de &lt;em&gt;Tests&lt;/em&gt; Automatizados. &lt;br&gt;
Se entrarmos mais a fundo na questão do &lt;strong&gt;Spring Boot&lt;/strong&gt; em volta de tudo isso temos muito mais problemas resolvidos tornando nosso dia-a-dia como Desenvolvedores muito mais produtivo.&lt;/p&gt;

&lt;p&gt;Bom, se você chegou até aqui você foi muito guerreiro porque foi um Post bem teórico, mas como mencionei lá no começo, alguns momentos é preciso entender O QUE estamos fazendo e O POR QUÊ estamos fazendo determinadas coisas em nossos sistemas.&lt;/p&gt;

&lt;p&gt;Espero que este Post seja útil para melhorar seu entendimento sobre &lt;strong&gt;Spring Framework&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Um abraço e até a próxima.&lt;/p&gt;




&lt;h2&gt;
  
  
  Referencias
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.spring.io/spring/docs/3.2.x/spring-framework-reference/html/beans.html" rel="noopener noreferrer"&gt;https://docs.spring.io/spring/docs/3.2.x/spring-framework-reference/html/beans.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.spring.io/spring-javaconfig/docs/1.0.0.M4/reference/html/ch02s02.html" rel="noopener noreferrer"&gt;https://docs.spring.io/spring-javaconfig/docs/1.0.0.M4/reference/html/ch02s02.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/context/ApplicationContext.html" rel="noopener noreferrer"&gt;https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/context/ApplicationContext.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/stereotype/package-summary.html" rel="noopener noreferrer"&gt;https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/stereotype/package-summary.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.baeldung.com/spring-bean-annotations" rel="noopener noreferrer"&gt;https://www.baeldung.com/spring-bean-annotations&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  java #kotlin #spring #springframework #springboot #jvm #beans
&lt;/h1&gt;

</description>
      <category>kotlin</category>
      <category>springboot</category>
      <category>development</category>
      <category>code</category>
    </item>
  </channel>
</rss>
