<?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: josevjunior</title>
    <description>The latest articles on DEV Community by josevjunior (@josevjunior).</description>
    <link>https://dev.to/josevjunior</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%2F486228%2F454a1cc4-47d5-4db7-9367-cba5f4b52241.jpeg</url>
      <title>DEV Community: josevjunior</title>
      <link>https://dev.to/josevjunior</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/josevjunior"/>
    <language>en</language>
    <item>
      <title>Abstraindo o gerenciamento de conexões do banco de dados em uma API Rest com Javalin e seus Handlers</title>
      <dc:creator>josevjunior</dc:creator>
      <pubDate>Tue, 21 Sep 2021 00:23:33 +0000</pubDate>
      <link>https://dev.to/josevjunior/abstraindo-o-gerenciamento-de-conexoes-do-banco-de-dados-em-uma-api-rest-com-javalin-e-seus-handlers-2296</link>
      <guid>https://dev.to/josevjunior/abstraindo-o-gerenciamento-de-conexoes-do-banco-de-dados-em-uma-api-rest-com-javalin-e-seus-handlers-2296</guid>
      <description>&lt;h1&gt;
  
  
  Como os Frameworks abstraem isso?
&lt;/h1&gt;

&lt;p&gt;Quando utilizei o Spring framework pela primeira vez fiquei curioso quando descobri que as classes criadas através dele (Beans) são, por padrão, singleton. Ou seja, a mesma instância de um @Controller por exemplo, é utilizada em toda requisição feita para a url em que ela está mapeada. Minha curiosidade era em saber como ele lidava com o estado dos atributos desses objetos. Em um bean podemos injetar outros objetos como um EntityManager e nesse caso os valores injetados em uma requisição não devem se misturar com os valores de outra. Devem ser Thread-Safe.&lt;/p&gt;

&lt;p&gt;Graças a internet consegui encontrar alguém que teve a mesma curiosidade, foi estudar o código-fonte do Spring e escreveu um post sobre que você pode acessar &lt;a href="http://shengwangi.blogspot.com/2016/01/why-dao-or-respository-bean-can-be-singleton-in-spring.html"&gt;aqui&lt;/a&gt;. O artigo tem o foco na utilização do @Repository, mas o princípio é o mesmo.&lt;/p&gt;

&lt;p&gt;Em resumo, o Spring cria um proxy para cada Bean criado (Que pode ser um @Service, @Repository ou qualquer outro tipo) e internamente ele salva as propriedades que devem ser Thread Safe em um objeto ThreadLocal. Normalmente objetos com a anotação @PersistenceContext não devem existir em 2 threads(Requisições) diferentes. Então, quando existir uma propriedade com essa anotação em um fonte, o que acessamos é apenas um proxy que dará acesso ao valor pertencente àquela thread. Dessa forma não ocorrerá a situação de um EntityManager existir em duas requisições simultâneas.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Um exemplo bem simples da utilização de um ThreadLocal&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h1&gt;
  
  
  O Microframework Javalin
&lt;/h1&gt;

&lt;p&gt;Quando se trata de microframeworks, existem algumas opções que sempre vem a tona como o Vert.x e Spark (Não o Apache Spark). Porém, o microframework que tive contato foi o Javalin, mesmo não sendo o mais completo, possui uma curva de aprendizado muito baixa, é compatível com Kotlin, tem suporte a Websocket e Server Sent Events (SSE), e é extremamente leve.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dependências necessárias para utilizá-lo&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Um simples exemplo esperando uma requisição na porta 7000&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h2&gt;
  
  
  Como o Javalin funciona
&lt;/h2&gt;

&lt;p&gt;Quando se cria um novo servidor com o Javalin, é possível usar os chamados Handlers (Semelhante a um callback, listener, observable, etc) que serão responsáveis por tratar as requisições http. Os Handlers geralmente são interfaces de apenas um método com um paramêtro do tipo Context (que é um facilitador de acesso aos métodos da classe HttpServletRequest e HttpServletResponse. Sim, o javalin utiliza a api do javax.servlet e sua implementação é o Jetty). Abaixo um exemplo de como utilizá-los.&lt;/p&gt;


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



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


&lt;h1&gt;
  
  
  O problema com as conexões
&lt;/h1&gt;

&lt;p&gt;Da primeira vez que utilizei o Javalin eu precisava lidar com o operações com banco de dados. Na época eu não optei por nenhuma biblioteca de ORM para facilitar o acesso aos dados ou de injeção de dependência para outros aspectos. O resultado disso foi muito código chato e repetitivo para tratar acesso ao banco e transações como os abaixo:&lt;/p&gt;


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


&lt;p&gt;A situação era ainda pior quando precisava implementar algo muito extenso e com várias etapas. Como um método depende do resultado do outro, para manter tudo na mesma transação era preciso passar a referência da conexão que está sendo usada. Como no exemplo seguinte:&lt;/p&gt;


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


&lt;h2&gt;
  
  
  O que poderia ser feito para evitar esse tipo de código?
&lt;/h2&gt;

&lt;p&gt;Depois de entender a premissa de como o Spring trata seus beans em um ambiente multithread, podemos usar as funcionalidades que o próprio Javalin disponibiliza para chegar em um resultado semelhante.&lt;/p&gt;

&lt;p&gt;Com o objetivo de usar uma conexão  por thread, podemos abstrair a criação, fechamento e rollbacks das conexões no ciclo de vida das requisições do Javalin. Dessa forma, podemos nos concentrar somente na lógica dos métodos de negócio sem a necessidade de passar a referência para todos os métodos que dependem de outro.&lt;/p&gt;

&lt;p&gt;Mas, por onde começar?&lt;/p&gt;

&lt;p&gt;Vinculando uma conexão do banco de dados a uma thread (que é criada para cada requisição feito por um client). E para isso vamos utilizar a classe ThreadLocal para nos ajudar.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Abaixo temos a classe que será responsável por vincular uma conexão a uma thread. Dessa forma não precisamos nos preocupar com thread-safety na camada de acesso a dados.&lt;/li&gt;
&lt;/ul&gt;


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


&lt;ul&gt;
&lt;li&gt;Utilizei o hikari CP para o pool de conexões com a base de dados. O arquivo .properties está disponível no repositório do github.&lt;/li&gt;
&lt;/ul&gt;


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


&lt;p&gt;Agora com os handlers que conversam com o ciclo de vida da requisição, é possíveis criar, fechar e desfazer as alterações feitas durante aquela requisição.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Um handler para abrir a conexão a cada requisição&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Um Handler para commitar e fechar a conexão após cada requisição&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Um handler que irá fazer rollback na transação caso uma exceção especifica seja lançada. (Poderia ser qualquer tipo de exceção)&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Para testar tudo isso, vamos fazer um cadastro simples&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Uma entidade simples&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Um service para acessar os dados&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Um controller que chamará o service&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Por fim a classe principal que inicializa tudo. Como não precisamos nos preocupar com threads em relação ao acesso a base de dados, os handlers podem usar sempre a mesma instancia do controlador&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;

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

&lt;p&gt;Esse foi apenas uma demonstração de como é possível utilizar apenas o que o Javalin nos dá para resolver o problema relacionado a gerência de transações/conexões. Claro que poderia ser mais sofisticado utilizando um framework de injeção de dependência ou ORM, mas não era o objetivo do artigo. O código pode ser acessado neste &lt;a href="https://github.com/josevjunior/transactional-javalin"&gt;repositório&lt;/a&gt;.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://javalin.io/documentation"&gt;https://javalin.io/documentation&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.baeldung.com/java-threadlocal"&gt;https://www.baeldung.com/java-threadlocal&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>java</category>
      <category>javalin</category>
      <category>rest</category>
    </item>
    <item>
      <title>Cache de dados em Java utilizando Proxy Dinâmico e Annotations</title>
      <dc:creator>josevjunior</dc:creator>
      <pubDate>Mon, 06 Sep 2021 21:37:24 +0000</pubDate>
      <link>https://dev.to/josevjunior/cache-de-dados-utilizando-proxy-dinamico-e-annotations-3k9g</link>
      <guid>https://dev.to/josevjunior/cache-de-dados-utilizando-proxy-dinamico-e-annotations-3k9g</guid>
      <description>&lt;p&gt;Durante o desenvolvimento de uma aplicação vão existir diversos momentos que será necessário implementarmos algum tipo de cache. Seja para diminuirmos acessos à algum serviço externo como um banco de dados ou webservice, ou para evitarmos a criação desnecessária de objetos ditos como "caros". Exemplos comuns desse tipo de objeto são EntityManagerFactory, DataSources, etc...&lt;/p&gt;

&lt;p&gt;Normalmente, temos que modificar trechos de código para utilizarmos o cache em algum ponto de nosso sistema. Pode ser que seja apenas um simples &lt;code&gt;if&lt;/code&gt; ou uma modificação mais complexa, não iremos escapar de "sujar" nosso código com alguma verificação ou tratamento.&lt;/p&gt;

&lt;p&gt;No exemplo abaixo temos uma rotina antes e depois da implementação de cache utilizando um HashMap:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Antes do cache&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Depois do cache&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Pode parecer uma alteração simples, mas dependendo da quantidade de métodos que precisam ser cacheados, como os métodos estão organizados ou como os valores são salvo no cache, pode se tornar complexo. No exemplo anterior o identificador para acessar os avisos é o próprio código do usuário para qual o aviso foi destinado, mas pode haver outras situações em que precisaremos identificar por usuário e data, ou somente por data. No balanço das horas tudo pode mudar.&lt;/p&gt;

&lt;p&gt;Para evitarmos incluir esse tipo de regra de interesse transversal no nosso código, vamos utilizar 2 funcionalidades bastante utilizadas no mundo java: os proxies dinâmicos e as annotations.&lt;/p&gt;

&lt;h2&gt;
  
  
  Proxy Dinâmico
&lt;/h2&gt;

&lt;p&gt;É uma classe que pode implementar um conjunto de interfaces definidas em tempo de execução e, em cada chamada feita a um dos método dessas interfaces, um despachante será chamado e ficará responsável por definir o comportamento da execução do método. Ou seja, teremos controle do próximo método a ser chamada antes da ação acontecer.&lt;/p&gt;

&lt;p&gt;Proxies são muito usados no mundo dos frameworks de injeção de dependências. Pois, como não criamos nossos objetos explicitamente através do comando &lt;code&gt;new&lt;/code&gt;, isso dá liberdade para eles, internamente, criarem proxies de nossos objetos adicionando funcionalidades a eles que em um primeiro momento pode parecer mágica, como abrir e fechar uma transação no BD durante a execução de um método ou chamar outro trecho de código que "intercepta" nosso objeto.&lt;/p&gt;

&lt;p&gt;Neste exemplos não usaremos o mecanismo de proxy nativo da jdk mas sim um provido pela biblioteca &lt;a href="https://www.baeldung.com/cglib"&gt;cglib&lt;/a&gt;. Através dessa lib não ficaremos presos a utilização de proxy dinâmico apenas em interfaces e poderemos utilizá-los em classes concretas.&lt;/p&gt;

&lt;h2&gt;
  
  
  Annotations
&lt;/h2&gt;

&lt;p&gt;As annotations ou anotações, por outro lado, não foram feitas para mudar o comportamento de um objeto em tempo de execução, mas sim definir informações(metadados) sobre determinado objeto que podem ser obtidas durante sua execução ou compilação. Podemos ver a utilização das anotações sempre que implementamos o método de uma interface ou sobrescrevemos um método de alguma superclasse. &lt;/p&gt;


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


&lt;p&gt;No caso do &lt;code&gt;@Override&lt;/code&gt;, estamos adicionados a informação que o seguinte método está sendo sobrescrito e que não pertence originalmente a essa classe. Tecnicamente isso não altera em nada o comportamento da aplicação, mas através de um proxy é possível verificar se um método, classe, parâmetro ou atributo possui anotações e a partir disso adicionar um comportamento novo de acordo com as informados obtidas.&lt;/p&gt;

&lt;h2&gt;
  
  
  Implementado nosso cache
&lt;/h2&gt;

&lt;p&gt;Para iniciar, vamos definir nossas annotations e que tipo de informação elas irão nos passar.&lt;/p&gt;


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


&lt;p&gt;Através da anotação &lt;code&gt;Cacheable&lt;/code&gt; informaremos qual método gostaríamos de cachear e qual o identificador dele no cache.&lt;/p&gt;

&lt;p&gt;Após ter definido o que identificará um método como cacheável, vamos partir para a api responsável por expor os dados cacheados&lt;/p&gt;

&lt;p&gt;A classe &lt;code&gt;CacheValue&lt;/code&gt; terá o papel de representar um valor cacheado em nossa api, além de conter informações adicionais como a data de criação do valor. &lt;/p&gt;


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


&lt;p&gt;Para consultar ou editar esses valores implementaremos a interface &lt;code&gt;CacheManager&lt;/code&gt;&lt;/p&gt;


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


&lt;p&gt;Por ser uma interface ganhamos certa liberdade para definir o mecanismo/engine de armazenamento de dados. Neste exemplo, vamos salvar os dados em um Map. Se quisermos algo mais elaborado, no futuro basta trocar a implementação para usar algo mais "potente" como o &lt;a href="https://redis.io/"&gt;Redis&lt;/a&gt; ou até mesmo um SGBD.&lt;/p&gt;

&lt;p&gt;A implementação do &lt;code&gt;CacheManager&lt;/code&gt; que utilizaremos neste exemplo:&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h3&gt;
  
  
  Agora vamos ao proxy...
&lt;/h3&gt;

&lt;p&gt;Como dito anteriormente, utilizaremos a cglib para criar proxy's de classes concretas. Para incluir essa dependência em um projeto maven basta adicionar a dependência abaixo no pom.xml&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;dependency&amp;gt;
    &amp;lt;groupId&amp;gt;cglib&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;cglib&amp;lt;/artifactId&amp;gt;
    &amp;lt;version&amp;gt;3.2.4&amp;lt;/version&amp;gt;
&amp;lt;/dependency&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Com essa lib no classpath, implementamos a interface &lt;code&gt;net.sf.cglib.proxy.MethodInterceptor&lt;/code&gt;, que contêm o método &lt;code&gt;intercept(Object o, Method method, Object[] os, MethodProxy mp)&lt;/code&gt;. Ele, como o nome diz, irá interceptar qualquer método cuja chamada for feita pela instancia do proxy. Através da classe &lt;code&gt;Method&lt;/code&gt; temos acesso ao método que está sendo executado. Utilizaremos essas informações para saber quais serão cacheados ou não. A classe &lt;code&gt;CacheProxy&lt;/code&gt; abaixo mostra toda essa lógica:&lt;/p&gt;


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



&lt;p&gt;O trecho seguinte mostra o método que utilizaremos para criar os proxys. Nele vemos como definimos a classe que será 'proxiada' e como vinculamos o ´MethodInteceptor´.&lt;/p&gt;


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


&lt;h2&gt;
  
  
  Utilizando nosso cache
&lt;/h2&gt;

&lt;p&gt;Vamos criar uma classe fictícia responsável por consultar as mensagens disponíveis para cada usuário e definir um de seus método com a anotação &lt;code&gt;@Cacheable&lt;/code&gt;&lt;/p&gt;


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


&lt;p&gt;Os valores serão armazenados em estrutura de Map (Chave =&amp;gt; Valor) da seguinte forma:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;       CHAVE                  VALOR
 ------------   ---
|"USER_MESSAGE"| 1 | =&amp;gt; [MENSAGEM_1, MENSAGEM_2]   
 ------------   ---

 -------------- ---
|"USER_MESSAGE"| 2 | =&amp;gt; []   
 -------------- ---
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O &lt;code&gt;cacheName&lt;/code&gt; definido na anotação, em conjunto com os valores dos parâmetros, serão usados como identificadores para salvar o retorno do método em cache. Dessa forma, cada chamada ao método utilizando um valor diferente no parâmetro será um "registro" cacheado.&lt;/p&gt;

&lt;p&gt;Alguns testes foram feitos para validar o funcionamento do nosso mecanismo de cache.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;set 05, 2021 6:26:22 PM br.com.simplecache.core.CacheProxy intercept
INFORMAÇÕES: Executando método cacheavel: getMessagesOfUser
set 05, 2021 6:26:22 PM br.com.simplecache.core.CacheProxy intercept
INFORMAÇÕES: Consultando valor no cache...
set 05, 2021 6:26:22 PM br.com.simplecache.core.CacheProxy intercept
INFORMAÇÕES: Não foi encontrado nenhum valor no cache. Executando método original...
set 05, 2021 6:26:22 PM br.com.simplecache.service.MessageService getMessagesOfUser
INFORMAÇÕES: Acessando messagens do usuário...
set 05, 2021 6:26:23 PM br.com.simplecache.core.CacheProxy intercept
INFORMAÇÕES: Salvando retorno no cache...
set 05, 2021 6:26:23 PM br.com.simplecache.core.CacheProxy intercept
INFORMAÇÕES: Executando método cacheavel: getMessagesOfUser
set 05, 2021 6:26:23 PM br.com.simplecache.core.CacheProxy intercept
INFORMAÇÕES: Consultando valor no cache...
set 05, 2021 6:26:23 PM br.com.simplecache.core.CacheProxy intercept
INFORMAÇÕES: Retornando valor cacheado
É a mesma lista: true
set 05, 2021 6:26:23 PM br.com.simplecache.core.SimpleCacheManager removeAll
INFORMAÇÕES: Limpando todo o cache
set 05, 2021 6:26:23 PM br.com.simplecache.core.CacheProxy intercept
INFORMAÇÕES: Executando método cacheavel: getMessagesOfUser
set 05, 2021 6:26:23 PM br.com.simplecache.core.CacheProxy intercept
INFORMAÇÕES: Consultando valor no cache...
set 05, 2021 6:26:23 PM br.com.simplecache.core.CacheProxy intercept
INFORMAÇÕES: Não foi encontrado nenhum valor no cache. Executando método original...
set 05, 2021 6:26:23 PM br.com.simplecache.service.MessageService getMessagesOfUser
INFORMAÇÕES: Acessando messagens do usuário...
set 05, 2021 6:26:23 PM br.com.simplecache.core.CacheProxy intercept
INFORMAÇÕES: Salvando retorno no cache...
É a mesma lista: false
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Neste post quis mostrar uma forma de implementar um cache um pouco mais sofisticado, mas sem partir para a utilização de um container CDI, um servidor de aplicação ou migrar para o Spring, já que em sistemas legados não temos tanta liberdade para implementar esse tipo de solução e essa seria um proposta menos invasiva.&lt;/p&gt;

&lt;p&gt;Repositório com os fontes: &lt;a href="https://github.com/josevjunior/simple-cache-manager"&gt;https://github.com/josevjunior/simple-cache-manager&lt;/a&gt;&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.baeldung.com/cglib"&gt;https://www.baeldung.com/cglib&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://refactoring.guru/pt-br/design-patterns/proxy/java/example"&gt;https://refactoring.guru/pt-br/design-patterns/proxy/java/example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.oracle.com/javase/7/docs/technotes/guides/reflection/proxy.html"&gt;https://docs.oracle.com/javase/7/docs/technotes/guides/reflection/proxy.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>java</category>
      <category>programming</category>
      <category>proxy</category>
      <category>annotations</category>
    </item>
  </channel>
</rss>
