Por que eu devo ler este artigo:Este artigo apresenta motivações do porquê utilizar metadados em nossas aplicações e como podemos fazer uso deles em tempo de desenvolvimento e compilação para minimizar erros e aumentar a produtividade de nossos desenvolvedores.

Neste contexto encontra-se Annotation processors, uma ferramenta muito útil quando uma solução para validações e geração de artefatos e arquivos em tempo de compilação é necessária, fazendo com que estes processos tediosos e propensos a erros, quando executados manualmente, possam ser automatizados utilizando recursos nativos da plataforma Java.

O uso de metadados é bastante difundido atualmente no desenvolvimento de aplicações e pode ser definido como sendo a incorporação de informações adicionais a determinados artefatos de um sistema. Um exemplo disso seria a criação de uma entidade persistente em uma aplicação que faz uso de JPA, Hibernate ou qualquer outra ferramenta de mapeamento objeto-relacional.

Normalmente tem-se uma classe como qualquer outra, porém no momento que definimos em um XML ou através de anotações específicas que esta classe deve ser tratada como uma entidade persistente, esta classe passa a ser interpretada pela aplicação como algo diferente, e ter comportamentos adicionais.

Em outras palavras, a partir do momento que associamos informações adicionais a simples classes, elas passam a ser tratadas pela aplicação de forma diferenciada, e são estas informações adicionais que chamamos de metadados, ou metainformações (veja a Listagem 1).

O conceito de metadados já está presente há bastante tempo no processo de desenvolvimento de software. Além de adicionar comportamentos adicionais, metadados são utilizados também para configuração.

Originalmente estes dados eram comumente informados em arquivos externos, normalmente arquivos XML, ou também arquivos de propriedades, como .properties, .ini, etc. Porém, a definição destas informações em arquivos separados fazia, e ainda faz, com que os desenvolvedores não soubessem exatamente quais informações adicionais já tinham sido definidas para determinadas classes do sistema.

Isso acaba exigindo que conhecimento prévio de determinados arquivos de configuração seja pré-requisito para cada desenvolvedor, forçando a criação de documentação adicional para estas configurações.

Este tipo de abordagem faz com que soluções como J2EE, Hibernate, etc., tenham uma curva de aprendizado ainda mais alta, sem contar os problemas de deployment difíceis de depurar e corrigir, muitas vezes por motivos de simples erros em inúmeros arquivos de configuração.

Para resolver ou minimizar esta situação, projetos como o XDoclet foram criados. Estes frameworks foram extremamente importantes para a produtividade de vários desenvolvedores e projetos, pois com eles se tornava possível definir os metadados diretamente nas classes ou métodos que necessitavam de informações adicionais, fazendo com que estas informações fossem definidas de forma contextualizada, diretamente no elemento ao qual estavam relacionadas.

Isto foi possível através do uso de instruções especiais no Javadoc, os chamados doclets. A partir do uso de doclets específicos para J2EE, Hibernate, Spring, entre tantos outros projetos, o XDoclet fez com que nossas vidas fossem simplificada sem muito.

Listagem 1. Exemplo de mapeamento de classe persistente no Hibernate 2 utilizando XDoclet


    /**
   * @hibernate.class table = "NOTA_FISCAL" dynamic-update="true"
   * 
   * @hibernate.query name="NotaFiscal.findByNumeros"
   *   query="select notaFiscal
   *                  from NotaFiscal
   *                where notaFiscal.numero in (:numeros)"
   */
  public class NotaFiscal implements Serializable {
     private Integer numero;
   
     /* outras propriedades omitidas */
   
     /**
     * @hibernate.id generator-class="assigned" column ="N_INTERNO"
     */
     public Integer getNumero() {
        return numero;
     }
   
     /* outros getters/setters omitidos */
   
  }

Porém, o uso de Javadoc não resolvia todos os problemas e tinha algumas limitações. A principal delas era que estas informações continuavam sendo definidas fora do contexto da linguagem e consequentemente não havia uma forma padronizada de acessar este tipo de informação.

Além disso, como estes recursos não faziam parte da linguagem, era preciso que um processo adicional fosse incorporado no momento do empacotamento da aplicação e apenas neste momento é que alguns tipos de erros eram tratados e informados ao desenvolvedor.

Em alguns casos, plugins específicos foram criados para algumas IDEs, mas ainda ...

Fim do trecho gratuito • continue abaixo
CONTEÚDO EXCLUSIVO

Desbloqueie toda a DevMedia

  • +2000 artigos e vídeos
  • +40 trilhas sobre Front-end, Back-end, IA e muito mais
  • +5000 exercícios práticos
  • Mentorias ao vivo individuais
até 50% OFF
A partir de
R$ 69 /mês
Assinar agora