<?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: Renata Fraga</title>
    <description>The latest articles on DEV Community by Renata Fraga (@renatasfraga).</description>
    <link>https://dev.to/renatasfraga</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%2F455945%2Fbb49e7a5-5928-43b7-8b48-3369ee0c70b3.PNG</url>
      <title>DEV Community: Renata Fraga</title>
      <link>https://dev.to/renatasfraga</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/renatasfraga"/>
    <language>en</language>
    <item>
      <title>Quarkus: Entendendo a relação entre o Mutiny e o Vert.x</title>
      <dc:creator>Renata Fraga</dc:creator>
      <pubDate>Sun, 04 Apr 2021 06:16:52 +0000</pubDate>
      <link>https://dev.to/renatasfraga/quarkus-entendendo-a-relacao-entre-o-mutiny-e-o-vert-x-1e3o</link>
      <guid>https://dev.to/renatasfraga/quarkus-entendendo-a-relacao-entre-o-mutiny-e-o-vert-x-1e3o</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Se você está começando a interagir com o supersônico e subatômico Quarkus, deve ter se perguntado qual a relação entre o Vert.x e o Mutiny. São opostos? Se complementam? Vivem de forma independente? Isso e muito mais no Dev Repórter!&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  O que é o Vert.x?
&lt;/h1&gt;

&lt;p&gt;O Eclipse Vert.x é nada mais nada menos que um kit de ferramentas focado na construção de aplicações reativas. Ele é facilmente incorporável a qualquer aplicação que rode em cima da JVM &lt;em&gt;(Java Virtual Machine)&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Ele conta com bibliotecas de conexão de banco de dados, comunicação com &lt;em&gt;brokers&lt;/em&gt; de mensageria, comunicação HTTP e muito mais (pensa num kit poderoso).&lt;/p&gt;

&lt;p&gt;A proposta do Vert.x é atuar com processamento de conexões simultâneas com &lt;strong&gt;menos &lt;em&gt;threads&lt;/em&gt; possíveis&lt;/strong&gt;. Ele verifica continuamente se há novos eventos, caso haja, ele despacha-os rapidamente para que alguém saiba como lidar com ele.&lt;/p&gt;

&lt;p&gt;O Vert.x consegue atuar com eventos simultâneos utilizando &lt;em&gt;event loop&lt;/em&gt; (este pode ser tema de outro artigo). Na Figura I é possível acompanhar como o Vert.x trabalha de forma otimizada através de &lt;em&gt;Event Loop&lt;/em&gt;.&lt;/p&gt;
Figura 1: Estratégia de Event Loop no Vert.x

 

&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%2F7laz75o7343v1ond7jpf.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%2F7laz75o7343v1ond7jpf.png" alt="Figura 1: Vertx Event Loop Image"&gt;&lt;/a&gt;&lt;br&gt;
Fonte: &lt;a href="https://vertx.io/introduction-to-vertx-and-reactive/#asynchronous-programming-scalability-and-resource-efficiency" rel="noopener noreferrer"&gt;Vert.x Doc&lt;/a&gt;&lt;/p&gt;
&lt;h1&gt;
  
  
  E o Mutiny?
&lt;/h1&gt;

&lt;p&gt;O Mutiny é uma biblioteca de programação reativa orientada a eventos. Com características semelhantes ao Vert.x, ela também tem I/Os não-bloqueantes, atua de forma assíncrona. Ela é baseada na especificação do &lt;em&gt;Reactive Streams&lt;/em&gt; bem como o &lt;em&gt;Spring Reactor&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Os tipos reativos existentes no Mutiny são &lt;code&gt;Uni&lt;/code&gt; e &lt;code&gt;Multi&lt;/code&gt;. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Uni&lt;/code&gt;: representa fluxos que recebem &lt;strong&gt;um item ou uma falha&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Multi&lt;/code&gt;: representa fluxos de &lt;strong&gt;0 ou N itens&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No trecho abaixo, é possível acompanhar o trecho onde é criado um fluxo do tipo &lt;code&gt;Multi&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="nc"&gt;Multi&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="n"&gt;source&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Multi&lt;/span&gt;
                        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;createForm&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; 
                        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;itens&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"a"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"b"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"c"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  A relação entre Vert.x e Mutiny no Quarkus
&lt;/h1&gt;

&lt;p&gt;O Quarkus é baseado no Vert.x, ou seja, em seu alicerce, encontra-se uma instância do mesmo sendo gerenciada. Exemplo: quando você desenvolve qualquer I/O, por baixo dos panos o Vert.x está atuando de forma totalmente reativa. Na Figura II é possível acompanhar onde o Vert.x se encontra na estrutura do Framework.&lt;/p&gt;
 Figura II: Arquitetura do Quarkus 



&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%2Fm6pxt0sg3bhpgp66bso4.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%2Fm6pxt0sg3bhpgp66bso4.png" alt="Quarkus Architecture"&gt;&lt;/a&gt;&lt;br&gt;
Com o Quarkus é possível você utilizar Vert.x de duas maneiras: utilizando a API "simples" Vert.x tal qual consta na &lt;a href="https://vertx.io/" rel="noopener noreferrer"&gt;documentação&lt;/a&gt; ou a &lt;strong&gt;variação com  Mutiny&lt;/strong&gt;. Segundo (ESCOFFIER, 2020), a implementação utilizando Mutiny, torna &lt;strong&gt;perfeita a experiência com outras APIs reativas oferecidas pelo Quarkus&lt;/strong&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Neste artigo iremos focar na variação com Mutiny.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Na Figura III é possível acompanhar o processo de transformação com a variação do Mutiny. &lt;/p&gt;
 Figura III: Mutiny Generator

 

&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%2Fw5y29cgkkolz2uaoi1c4.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%2Fw5y29cgkkolz2uaoi1c4.png" alt="Figura III"&gt;&lt;/a&gt;&lt;br&gt;
A transformação ocorre da seguinte forma:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;O pacote &lt;code&gt;io.vertx&lt;/code&gt; para &lt;code&gt;io.vertx.mutiny&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;métodos assícrononos para métodos que retornem o tipo &lt;code&gt;Uni&amp;lt;T&amp;gt;&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ReadStreams&amp;lt;T&amp;gt;&lt;/code&gt;serão consumidos como &lt;code&gt;Multi&amp;lt;T&amp;gt;&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;WriteStreams&amp;lt;T&amp;gt;&lt;/code&gt; serão consumidos como &lt;code&gt;Subscriber&amp;lt;T&amp;gt;&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No trecho abaixo é possível acompanhar a implementação utilizando Mutiny, na qual permite que o desenvolvedor faça uso das representações e funções disponíveis integrando com as APIs do Vert.x através do &lt;code&gt;Mutiny Generator&lt;/code&gt;(Figura IV).&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="nc"&gt;Uni&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Buffer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;uni&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;vertx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;fileSystem&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;readFile&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"my-file.txt"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;uni&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;subscribe&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
   &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"File content is: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;É importante ressaltar que o Mutiny pode ser usado de forma independente, sem nenhuma integração com Quarkus e Vert.x. Porém, na implementação do Quarkus, a relação entre as duas bibliotecas inevitavelmente irá ocorrer.&lt;br&gt;
Existe uma diferença importante entre a API "simples" do Vert.x e a variante com Mutiny. Enquanto a API "simples" aciona a operação assim que o método é chamado, o Mutiny necessita que ocorra uma assinatura para que a operação seja acionada.&lt;/p&gt;

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

&lt;p&gt;Neste artigo falamos sobre a relação entre Vert.x e Mutiny dentro do Quarkus. &lt;br&gt;
Se fizermos uma análise acerca das possibilidades fornecidas pelo Quarkus, podemos considerar que há uma implementação do padrão &lt;code&gt;Strategy&lt;/code&gt; no &lt;code&gt;Code Generator&lt;/code&gt;. Isso porque é possível fazer uso da API "nua" do Vert.x (inclusive adoção de APIs baseadas no &lt;code&gt;Reactive Streams&lt;/code&gt; tais como, RxJava), além da variante com Mutiny. Essa flexibilidade facilita a vida do desenvolvedor, pois ele terá a possibilidade de escolher qual a biblioteca ele deseja utilizar sem deixar de aproveitar os recursos Vert.x. &lt;/p&gt;

&lt;p&gt;Não deixem de conferir o referencial teórico que utilizei para este artigo.&lt;/p&gt;

&lt;h1&gt;
  
  
  Referências:
&lt;/h1&gt;

&lt;p&gt;ESCOFFIER, Clement. Mutiny and the Reactiverse. Disponível em: &lt;a href="https://quarkus.io/blog/mutiny-vertx/" rel="noopener noreferrer"&gt;https://quarkus.io/blog/mutiny-vertx/&lt;/a&gt;. Acesso em: 03 Abr 2021.&lt;/p&gt;

&lt;p&gt;SMALLRYE IO. Philosophy. Disponível em: &lt;a href="https://smallrye.io/smallrye-mutiny/pages/philosophy" rel="noopener noreferrer"&gt;https://smallrye.io/smallrye-mutiny/pages/philosophy&lt;/a&gt;. Acesso em: 03 Abr 2021.&lt;/p&gt;

&lt;p&gt;VERT.X. Eclipse Vert.x and reactive in just a few words. Disponível em: &lt;a href="https://vertx.io/introduction-to-vertx-and-reactive/" rel="noopener noreferrer"&gt;https://vertx.io/introduction-to-vertx-and-reactive/&lt;/a&gt;. Acesso em: 03 Abr 2021.&lt;/p&gt;

</description>
      <category>vertx</category>
      <category>mutiny</category>
      <category>quarkus</category>
    </item>
    <item>
      <title>Java Annotations no Spring: Crie restrições em suas DTOs</title>
      <dc:creator>Renata Fraga</dc:creator>
      <pubDate>Wed, 26 Aug 2020 23:55:09 +0000</pubDate>
      <link>https://dev.to/renatasfraga/java-annotations-no-spring-crie-restricoes-em-suas-dtos-2nfj</link>
      <guid>https://dev.to/renatasfraga/java-annotations-no-spring-crie-restricoes-em-suas-dtos-2nfj</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Vibrante por encontrar pessoas que querem criar &lt;em&gt;annotations&lt;/em&gt; comigo!&lt;/p&gt;
&lt;/blockquote&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%2Fi%2Fj6jcxqh365b6qx2oc5dr.gif" 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%2Fi%2Fj6jcxqh365b6qx2oc5dr.gif" alt="Série Seinfeld: Elenco vibrando"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Olá queridos devs!&lt;br&gt;
Hoje neste tutorial irei explicar &lt;strong&gt;o que são&lt;/strong&gt; e &lt;strong&gt;como se comportam&lt;/strong&gt; as famosas annotations, um mecanismo muito poderoso e nem tanto explorado pelos desenvolvedores no universo Java. Além da contextualização, irei apresentar &lt;strong&gt;dois exemplos&lt;/strong&gt; muito simples que podem ser um bom norteador a você que está iniciando esta caminhada.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  -1. Alinhando expectativas
&lt;/h2&gt;

&lt;p&gt;Neste tutorial você vai encontrar: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Conceitos sobre o que é uma anotação&lt;/li&gt;
&lt;li&gt;Disponibilidade de anotações&lt;/li&gt;
&lt;li&gt;Exemplos de anotações disponíveis em tempo de execução focadas em validar restrições&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Neste tutorial você &lt;strong&gt;não&lt;/strong&gt; vai encontrar: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Fundamentação teórica densa (deixarei bons materiais como referência) &lt;/li&gt;
&lt;li&gt;Inclusão de atributos na anotação&lt;/li&gt;
&lt;li&gt;Uso de &lt;em&gt;reflections&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  1. O que é?
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;"As annotations são responsáveis por fornecer informações complementares sobre um programa." (GeeksForGeeks, 2020, tradução nossa)&lt;/p&gt;

&lt;p&gt;Segundo Oracle ([20--]) "[...] uma forma de metadados, fornecem dados sobre um programa que não faz parte do próprio programa". &lt;/p&gt;

&lt;p&gt;As annotations são responsáveis por embutir informações complementares no código fonte. (Groner, 2015)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;As anotações surgiram a partir da versão 1.5 do Java e são precedidas por um arroba &lt;code&gt;@&lt;/code&gt;. Provavelmente você já deve ter observado algumas dispersas em seu código, como por exemplo: &lt;code&gt;@Override&lt;/code&gt;, &lt;code&gt;@RequestBody&lt;/code&gt;, &lt;code&gt;@PathVariable&lt;/code&gt;, &lt;code&gt;@Getter&lt;/code&gt;, &lt;code&gt;@Setter&lt;/code&gt;. &lt;/p&gt;

&lt;h2&gt;
  
  
  2. Qual a finalidade?
&lt;/h2&gt;

&lt;p&gt;As anotações podem ser utilizadas em três finalidades distintas dentro do ciclo de vida do seu projeto (quem define esta configuração é a meta-annotation chamada &lt;code&gt;@Retention&lt;/code&gt;, na qual, entrarei em detalhes nas próximas seções). Esta definição também é importante para indicar em qual momento as instruções da anotação devem estar disponíveis e serem descartadas (JAVA2NOVICE, 2020). As três finalidades são exemplificadas abaixo:  &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Instruções em tempo de compilação (CLASS):&lt;/strong&gt; tem como objetivo gerar códigos fonte em tempo de compilação. Um exemplo famoso é o da biblioteca Mapstruct, que em tempo de compilação gera componentes que convertem objetos em outros, em cima de uma varredura em todas as interfaces que utilizam a anotação &lt;code&gt;@Mapper&lt;/code&gt; (MAPSTRUCT, [201-]). &lt;br&gt;
&lt;strong&gt;Instruções em tempo de construção (SOURCE):&lt;/strong&gt; tem como objetivo gerar empacotamento de arquivos, arquivos XML em tempo de construção do projeto, ou seja, na etapa que está sendo gerado o arquivo &lt;code&gt;.jar&lt;/code&gt; ou &lt;code&gt;.war&lt;/code&gt; (JENKOV, 2019).&lt;br&gt;
&lt;strong&gt;Instruções em tempo de execução(RUNTIME):&lt;/strong&gt; tem como objetivo criar validações ou injetar informações em tempo de execução, como por exemplo, a anotação &lt;code&gt;@NotNull&lt;/code&gt; que é utilizada para validar obrigatoriedade de um atributo de uma classe. &lt;/p&gt;
&lt;h2&gt;
  
  
  4. Como funciona: exemplo prático
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Entendendo as três finalidades apresentadas na seção anterior e sabendo que queremos criar anotações que validem nossas requisições, necessitamos que estas estejam disponíveis em &lt;strong&gt;tempo de execução&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Como o foco deste tutorial são anotações disponíveis em tempo de execução, usaremos como exemplo explicativo a anotação &lt;code&gt;@NotNull&lt;/code&gt; presente no projeto &lt;code&gt;JakartaEE&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;METHOD&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;FIELD&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;ANNOTATION_TYPE&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;CONSTRUCTOR&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;PARAMETER&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_USE&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;@Repeatable&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;NotNull&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;List&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;@Documented&lt;/span&gt;
&lt;span class="nd"&gt;@Constraint&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;validatedBy&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="kd"&gt;public&lt;/span&gt; &lt;span class="nd"&gt;@interface&lt;/span&gt; &lt;span class="nc"&gt;NotNull&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;message&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="s"&gt;"{javax.validation.constraints.NotNull.message}"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="nc"&gt;Class&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;?&amp;gt;[]&lt;/span&gt; &lt;span class="n"&gt;groups&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="o"&gt;{};&lt;/span&gt;

    &lt;span class="nc"&gt;Class&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;?&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Payload&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;[]&lt;/span&gt; &lt;span class="nf"&gt;payload&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="k"&gt;default&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;METHOD&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;FIELD&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;ANNOTATION_TYPE&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;CONSTRUCTOR&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;PARAMETER&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_USE&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="kd"&gt;public&lt;/span&gt; &lt;span class="nd"&gt;@interface&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;NotNull&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="nf"&gt;value&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;Abaixo é possível acompanhar as meta-annotations e atributos com seu nome e significado:  &lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Meta-Annotation/Atributo&lt;/th&gt;
&lt;th&gt;Descrição&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;@Target&lt;/td&gt;
&lt;td&gt;Indica qual contexto esta anotação pode ser aplicada. Estes valores são indicados pelo enumerador &lt;code&gt;ElementType&lt;/code&gt;. No exemplo acima, percebe-se que é possível aplicar esta anotação em níveis de: métodos, campos (atributos), classes, construtores e parâmetros&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;@Retention&lt;/td&gt;
&lt;td&gt;Indica se a anotação estará disponível em tempo de compilação, execução ou construção. Estes valores são indicados pelo enumerador &lt;code&gt;RetentionPolicy&lt;/code&gt;. No exemplo acima, a retenção é do tipo RUNTIME, ou seja, a anotação estará disponível para uso em tempo de execução.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;@Repeatable&lt;/td&gt;
&lt;td&gt;Indica possibilidade de utilizar mais de uma vez a anotação em uma classe. Observe que nesta meta-annotation é informado o tipo de anotação na qual deseja-se repetir. No final da implementação da mesma, é possível acompanhar uma espécie de "sub-annotation" que tem um &lt;code&gt;array&lt;/code&gt; do tipo &lt;code&gt;NotNull&lt;/code&gt;. Só é possível que a anotação utilize o mecanismo de repetição se for implementada esta estrutura com o &lt;code&gt;array&lt;/code&gt; do mesmo tipo.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;@Documented&lt;/td&gt;
&lt;td&gt;Indica que essa anotação será documentada via javadoc ou uma ferramenta similar.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;@Constraint&lt;/td&gt;
&lt;td&gt;Indica que a anotação será marcada para uso de restrição de validação. O atributo &lt;code&gt;validatedBy&lt;/code&gt; indica a classe que conterá essa validação de restrição (no exemplo acima, não foi elencada esta classe de validação, porém nos exemplos apresentados nas próximas seções irei apresentar o uso desse recurso). Com a adoção desta anotação, é necessário implementar os seguintes atributos: &lt;code&gt;message&lt;/code&gt;, &lt;code&gt;groups&lt;/code&gt;, &lt;code&gt;payload&lt;/code&gt;.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;message()&lt;/td&gt;
&lt;td&gt;Indica a mensagem de erro na qual será informada caso a restrição de validação seja violada. Por padrão, é necessário que informe uma mensagem de erro, que provavelmente estará no arquivo &lt;code&gt;message.properties&lt;/code&gt; do seu projeto. No exemplo acima, esta mensagem está internamente em arquivos &lt;code&gt;.properties&lt;/code&gt; da biblioteca &lt;code&gt;JakartaEE&lt;/code&gt;.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;groups()&lt;/td&gt;
&lt;td&gt;Este atributo é assunto que renderia um bom artigo. Mas resumidamente, este atributo serve para criar grupos de validação específicos. No exemplo, você percebe que não utilizamos este recurso. Ele apenas está ali como uma espécie de "contrato" necessário em detrimento do uso da anotação &lt;code&gt;@Constraint&lt;/code&gt;.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;payload()&lt;/td&gt;
&lt;td&gt;Este atributo é assunto que renderia um bom artigo. Segundo a documentação JBoss (2020), "pode ser usada [...] para atribuir objetos de payload personalizados a uma restrição". No exemplo, você percebe que não utilizamos este recurso. Ele apenas está ali como uma espécie de "contrato" necessário em detrimento do uso da anotação &lt;code&gt;@Constraint&lt;/code&gt;.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  5. Criando anotações
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Nosso case:&lt;/em&gt; Temos uma API RESTful responsável por cadastrar pessoas físicas e jurídicas. Estas pessoas necessitam ter informações como: nome,documento e tipo de documento. Iremos utilizar duas abordagens para validar estes campos: uso de anotação em nível de classe e campo. &lt;/p&gt;

&lt;p&gt;Primeiramente, é necessário que você adicione a anotação &lt;code&gt;@Valid&lt;/code&gt; ao lado da &lt;code&gt;@RequestBody&lt;/code&gt;. Só assim, é possível que as validações presentes nas anotações utilizadas pelo classe &lt;code&gt;PersonRequest&lt;/code&gt; sejam aplicadas. A seguir você acompanha como fica o trecho do código onde se adiciona esta propriedade:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@RestController&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PersonController&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nd"&gt;@PostMapping&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;consumes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;MediaType&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;APPLICATION_JSON_VALUE&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;Object&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;@Valid&lt;/span&gt; &lt;span class="nd"&gt;@RequestBody&lt;/span&gt; &lt;span class="nc"&gt;PersonRequest&lt;/span&gt; &lt;span class="n"&gt;personRequest&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;
  
  
  5.1 Nível de campo (Field Level)
&lt;/h3&gt;

&lt;p&gt;Iremos criar uma anotação que seja capaz de verificar se o campo &lt;code&gt;fullName&lt;/code&gt; tem mais de uma palavra. Caso este campo tenha apenas uma única palavra, uma exceção será lançada.&lt;br&gt;
No trecho abaixo, é possível observar a classe &lt;code&gt;PersonRequest&lt;/code&gt; com a anotação &lt;code&gt;@GreaterThanOneWord&lt;/code&gt; acima do campo &lt;code&gt;fullName&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="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PersonRequest&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nd"&gt;@GreaterThanOneWord&lt;/span&gt;
    &lt;span class="nd"&gt;@NotBlank&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;fullName&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

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

    &lt;span class="nd"&gt;@NotNull&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;DocumentType&lt;/span&gt; &lt;span class="n"&gt;documentType&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;Colocamos uma anotação inexistente acima do atributo, porém é hora de pôr a mão na massa e cria-la!  &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Abaixo é possível acompanhar a implementação da anotação:&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;@Repeatable&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;GreaterThanOneWord&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;List&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;@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;FIELD&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;@Constraint&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;validatedBy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;GreaterThanOneWorldValidation&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="nd"&gt;@interface&lt;/span&gt; &lt;span class="nc"&gt;GreaterThanOneWord&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;message&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="s"&gt;"{error.business.greater_than_one_word}"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="nc"&gt;Class&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;?&amp;gt;[]&lt;/span&gt; &lt;span class="n"&gt;groups&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="o"&gt;{};&lt;/span&gt;

    &lt;span class="nc"&gt;Class&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;?&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Payload&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;[]&lt;/span&gt; &lt;span class="nf"&gt;payload&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="k"&gt;default&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;@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;FIELD&lt;/span&gt;&lt;span class="o"&gt;})&lt;/span&gt;
    &lt;span class="nd"&gt;@interface&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;GreaterThanOneWord&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="nf"&gt;value&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;Observe que no exemplo acima, utilizamos a meta-annotation &lt;code&gt;@Repeatable&lt;/code&gt; para possibilitar o reuso desta anotação em outros atributos da mesma classe. Na &lt;code&gt;@Target&lt;/code&gt;, informamos que a anotação só pode ser utilizada em nível de campo. Em &lt;code&gt;@Retention&lt;/code&gt;, utilizamos o tipo &lt;code&gt;RUNTIME&lt;/code&gt; em razão de sua utilização ser em tempo de execução. Em &lt;code&gt;@Constraint&lt;/code&gt;, informamos no atributo &lt;code&gt;validatedBy&lt;/code&gt; a classe que iremos aplicar a validação que indicará se ocorreu ou não violação da restrição. &lt;/p&gt;

&lt;p&gt;No trecho a seguir, é possível acompanhar o arquivo &lt;code&gt;messages_en_US.properties&lt;/code&gt; com a mensagem padrão que será apresentada caso haja violação da restrição:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight properties"&gt;&lt;code&gt;&lt;span class="py"&gt;error.business.greater_than_one_word&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;The field must be filled with more than one word&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Abaixo é possível acompanhar a implementação da validação das restrições:&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="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;GreaterThanOneWorldValidation&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;ConstraintValidator&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;GreaterThanOneWord&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="nf"&gt;isValid&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;field&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;ConstraintValidatorContext&lt;/span&gt; &lt;span class="n"&gt;constraintValidatorContext&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;field&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;split&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="na"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1&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;Observe no exemplo acima que para utilizar esta classe na propriedade &lt;code&gt;validatedBy&lt;/code&gt;, é necessário que esta implemente a interface &lt;code&gt;ConstraintValidator&lt;/code&gt;. Nos dois generics apresentados pela interface, você deve informar: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;1º: o tipo da anotação criada&lt;/li&gt;
&lt;li&gt;2º: tipo de objeto que será validado (caso queira trabalhar com atributos genéricos você deve informar &lt;code&gt;Object&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Essa interface oferece dois métodos: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;initilize()&lt;/code&gt;: pode ou não ser implementado. Normalmente utilizado quando a anotação recebe informações nos atributos que necessitam ser utilizados no método &lt;code&gt;isValid&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;isValid()&lt;/code&gt;: método booleano responsável por validar se há restrição violada ou não. Ali é aplicado a lógica desejada. Caso retorne &lt;code&gt;true&lt;/code&gt; significa que nenhuma restrição foi violada, caso contrário uma exceção será lançada. &lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Acesse o &lt;a href="https://gitlab.com/renata_fraga/java-annotation-spring/-/tree/master/annotation-field-level-example" rel="noopener noreferrer"&gt;LINK&lt;/a&gt; do repositório do projeto. Lá você encontra a implementação completa, além de tratamento de exceções, internacionalização e testes unitários. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  5.2 Nível de classe (Type Level)
&lt;/h3&gt;

&lt;p&gt;Agora, iremos criar uma anotação para verificar se a quantidade de caracteres inseridos no campo &lt;code&gt;document&lt;/code&gt; corresponde ao &lt;code&gt;documentType&lt;/code&gt; informado, ou seja: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;se &lt;code&gt;documentType&lt;/code&gt; for igual a &lt;code&gt;CNPJ&lt;/code&gt;, o campo &lt;code&gt;document&lt;/code&gt; deve ter 14 caracteres&lt;/li&gt;
&lt;li&gt;se &lt;code&gt;documentType&lt;/code&gt; for igual a &lt;code&gt;CPF&lt;/code&gt;, o campo &lt;code&gt;document&lt;/code&gt; deve ter 11 caracteres&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Peço que não levem em consideração a veracidade desta validação na qual criei, pois sabemos que existem algumas variações acerca da quantidade de caracteres de um CNPJ. Mas para fins didáticos, esse exemplo será útil.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;No trecho abaixo, é possível observar a anotação &lt;code&gt;@IsValidDocumentFormat&lt;/code&gt; sobre a classe &lt;code&gt;PersonRequest&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;@IsValidDocumentFormat&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;PersonRequest&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

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

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

    &lt;span class="nd"&gt;@NotNull&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;DocumentType&lt;/span&gt; &lt;span class="n"&gt;documentType&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Abaixo é possível acompanhar a implementação da anotação:&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;@Constraint&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;validatedBy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;IsValidDocumentFormatValidation&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="nd"&gt;@interface&lt;/span&gt; &lt;span class="nc"&gt;IsValidDocumentFormat&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;message&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="s"&gt;"{error.business.is_valid_document_format}"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="nc"&gt;Class&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;?&amp;gt;[]&lt;/span&gt; &lt;span class="n"&gt;groups&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="o"&gt;{};&lt;/span&gt;

    &lt;span class="nc"&gt;Class&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;?&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Payload&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;[]&lt;/span&gt; &lt;span class="nf"&gt;payload&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="k"&gt;default&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;Como apresentado no exemplo acima, não utilizamos a meta-annotation &lt;code&gt;@Repeatable&lt;/code&gt;, pois desejamos que esta seja utilizada apenas uma única vez na classe. Na &lt;code&gt;@Target&lt;/code&gt;, informamos que a anotação só pode ser utilizada em nível de classe. As demais meta-annotations já foram esclarecidas na sub-seção anterior. &lt;/p&gt;

&lt;p&gt;No trecho a seguir, é possível acompanhar o arquivo &lt;code&gt;messages_en_US.properties&lt;/code&gt; com a mensagem padrão que será apresentada caso haja violação da restrição:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight properties"&gt;&lt;code&gt;&lt;span class="py"&gt;error.business.is_valid_document_format&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;Invalid document format for the type entered&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Abaixo é possível acompanhar a implementação da validação das restrições:&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="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;IsValidDocumentFormatValidation&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;ConstraintValidator&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;IsValidDocumentFormat&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
        &lt;span class="nc"&gt;PersonRequest&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="nf"&gt;isValid&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;PersonRequest&lt;/span&gt; &lt;span class="n"&gt;personRequest&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;ConstraintValidatorContext&lt;/span&gt; &lt;span class="n"&gt;constraintValidatorContext&lt;/span&gt;&lt;span class="o"&gt;)&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;boolean&lt;/span&gt; &lt;span class="n"&gt;isValidCpf&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;personRequest&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getDocument&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;length&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;11&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;personRequest&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getDocumentType&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;equals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;DocumentType&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;CPF&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;boolean&lt;/span&gt; &lt;span class="n"&gt;isValidCnpj&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;personRequest&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getDocument&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;length&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;14&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;personRequest&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getDocumentType&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;equals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;DocumentType&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;CNPJ&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;isValidCpf&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="n"&gt;isValidCnpj&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;Observe que nos dois generics apresentados pela interface, você deve informar: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;1º: o tipo da anotação criada&lt;/li&gt;
&lt;li&gt;2º: tipo de classe que será validada (caso queira trabalhar com classes genéricas você deve informar &lt;code&gt;Object&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Acesse o &lt;a href="https://gitlab.com/renata_fraga/java-annotation-spring/-/tree/master/annotation-type-level-example" rel="noopener noreferrer"&gt;LINK&lt;/a&gt; do repositório do projeto. Lá você encontra a implementação completa, além de tratamento de exceções, internacionalização e testes unitários. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  6. Conclusão e Próximos passos
&lt;/h2&gt;

&lt;p&gt;O que podemos concluir acerca da adotação de anotações é que elas podem ser um ótimo mecanismo para realizar validações de entrada, reaproveitando códigos e abstraindo muitas estruturas.&lt;/p&gt;

&lt;p&gt;É importante ressaltar que as anotações não são soluções mágicas que resolvem todos os seus problemas. Elas não podem ser utilizadas de forma demasiada, nem ter grande responsabilidade a ponto de sua camada de negócios tornar-se um mero coadjuvante dentro do seu serviço (acredito que isso seja pauta inclusive de maiores discussões). &lt;/p&gt;

&lt;p&gt;Neste exemplo, não pude apresentar anotações em tempo de compilação e construção, tampouco a adoção de anotações genéricas que fazem uso de Reflections. Resolvi trazer neste artigo esta parte introdutória para que possamos ir aprofundando aos poucos. Caso você queira que eu continue essa série de artigos deixe nos comentários ou no meu LinkedIn. &lt;/p&gt;

&lt;p&gt;Vou deixar abaixo as referências de minha pesquisa e recomendo fortemente que você as leia, principalmente na documentação oficial sobre as meta-annotations. &lt;/p&gt;

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

&lt;p&gt;DOLSZEWSKI. &lt;strong&gt;Spring Custom Validation by Example&lt;/strong&gt;. Disponível em: &lt;a href="http://dolszewski.com/spring/custom-validation-annotation-in-spring/" rel="noopener noreferrer"&gt;http://dolszewski.com/spring/custom-validation-annotation-in-spring/&lt;/a&gt;. Acesso em: 26 Ago 2020.&lt;br&gt;
GEEKS FOR GEEKS.&lt;strong&gt;Annotations In Java&lt;/strong&gt;. Disponível em: &lt;a href="https://www.geeksforgeeks.org/annotations-in-java/" rel="noopener noreferrer"&gt;https://www.geeksforgeeks.org/annotations-in-java/&lt;/a&gt;. Acesso em: 23 Ago 2020. &lt;br&gt;
GRONER, Loiane.&lt;strong&gt;Vídeo: Curso de Java 65: Annotations (anotações)&lt;/strong&gt;. Disponível em: &lt;a href="https://www.youtube.com/watch?v=6M8EE_oRwtM" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=6M8EE_oRwtM&lt;/a&gt;. Acesso em: 23 Ago 2020. &lt;br&gt;
JAKARTAEE.&lt;strong&gt;Annotation Type NotNull&lt;/strong&gt;. Disponível em: &lt;a href="https://jakarta.ee/specifications/platform/8/apidocs/javax/validation/constraints/NotNull.html" rel="noopener noreferrer"&gt;https://jakarta.ee/specifications/platform/8/apidocs/javax/validation/constraints/NotNull.html&lt;/a&gt;. Acesso em: 23 Ago 2020.&lt;br&gt;
JAVA2NOVICE. &lt;strong&gt;What is Retention policy in java annotations?&lt;/strong&gt;. Disponível em: &lt;a href="https://www.java2novice.com/java-annotations/retention-policy/#:%7E:text=Annotation%20with%20retention%20policy%20SOURCE,to%20the%20JVM%20through%20runtime" rel="noopener noreferrer"&gt;https://www.java2novice.com/java-annotations/retention-policy/#:~:text=Annotation%20with%20retention%20policy%20SOURCE,to%20the%20JVM%20through%20runtime&lt;/a&gt;. Acesso em: 26 Ago 2020.&lt;br&gt;
JBOSS. &lt;strong&gt;6. Creating custom constraints&lt;/strong&gt;. Disponível em: &lt;a href="https://docs.jboss.org/hibernate/stable/validator/reference/en-US/html_single/#validator-customconstraints" rel="noopener noreferrer"&gt;https://docs.jboss.org/hibernate/stable/validator/reference/en-US/html_single/#validator-customconstraints&lt;/a&gt;. Acesso em: 26 Ago 2020. &lt;br&gt;
JENKOV, Jakob. &lt;strong&gt;Java Annotations&lt;/strong&gt;. Disponível em: &lt;a href="http://tutorials.jenkov.com/java/annotations.html" rel="noopener noreferrer"&gt;http://tutorials.jenkov.com/java/annotations.html&lt;/a&gt;. Acesso em: 23 Ago 2020. &lt;br&gt;
MAPSTRUCT. &lt;strong&gt;Mapper Annotation Type&lt;/strong&gt;. Disponível em: &lt;a href="https://mapstruct.org/documentation/dev/api/" rel="noopener noreferrer"&gt;https://mapstruct.org/documentation/dev/api/&lt;/a&gt;. Acesso em: 26 Ago 2020. &lt;br&gt;
ORACLE. &lt;strong&gt;Annotation Type Constraint&lt;/strong&gt;. Disponível em: &lt;a href="https://jakarta.ee/specifications/platform/8/apidocs/javax/validation/Constraint.html" rel="noopener noreferrer"&gt;https://jakarta.ee/specifications/platform/8/apidocs/javax/validation/Constraint.html&lt;/a&gt;. Acesso em: 26 Ago 2020.&lt;br&gt;
ORACLE. &lt;strong&gt;Annotation Type Documented&lt;/strong&gt;. Disponível em: &lt;a href="https://docs.oracle.com/javase/8/docs/api/java/lang/annotation/Documented.html?is-external=true" rel="noopener noreferrer"&gt;https://docs.oracle.com/javase/8/docs/api/java/lang/annotation/Documented.html?is-external=true&lt;/a&gt;. Acesso em: 26 Ago 2020.&lt;br&gt;
ORACLE. &lt;strong&gt;Annotation Type Repeatable&lt;/strong&gt;. Disponível em: &lt;a href="https://docs.oracle.com/javase/8/docs/api/java/lang/annotation/Repeatable.html?is-external=true" rel="noopener noreferrer"&gt;https://docs.oracle.com/javase/8/docs/api/java/lang/annotation/Repeatable.html?is-external=true&lt;/a&gt;. Acesso em: 26 Ago 2020.&lt;br&gt;
ORACLE. &lt;strong&gt;Annotation Type Retention&lt;/strong&gt;. Disponível em: &lt;a href="https://docs.oracle.com/javase/8/docs/api/java/lang/annotation/Retention.html" rel="noopener noreferrer"&gt;https://docs.oracle.com/javase/8/docs/api/java/lang/annotation/Retention.html&lt;/a&gt;. Acesso em: 26 Ago 2020. &lt;br&gt;
ORACLE. &lt;strong&gt;Annotation Type Target&lt;/strong&gt;. Disponível em: &lt;a href="https://docs.oracle.com/javase/8/docs/api/java/lang/annotation/Target.html" rel="noopener noreferrer"&gt;https://docs.oracle.com/javase/8/docs/api/java/lang/annotation/Target.html&lt;/a&gt;. Acesso em: 26 Ago 2020.&lt;br&gt;
ORACLE.&lt;strong&gt;Lesson: Annotations&lt;/strong&gt;. Disponível em: &lt;a href="https://docs.oracle.com/javase/tutorial/java/annotations/" rel="noopener noreferrer"&gt;https://docs.oracle.com/javase/tutorial/java/annotations/&lt;/a&gt;. &lt;br&gt;
Acesso em: 23 Ago 2020.&lt;/p&gt;

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