Skip to content

Instantly share code, notes, and snippets.

@jeffbicca
Created April 11, 2012 19:15
Show Gist options
  • Save jeffbicca/2361562 to your computer and use it in GitHub Desktop.
Save jeffbicca/2361562 to your computer and use it in GitHub Desktop.
Observações sobre o "DI" do CDI.
Durante a migração de algumas funcionalidades de um sistema que foi desenvolvido utilizando JEE 5 para JEE 6 conforme
algumas experiências expostas em (https://gist.github.com/2361046), fui observando e prestando a atenção em especial no
funcionamento do DI (Dependency Injection) do CDI. Alguns detalhes que exponho aqui podem parecer óbvios para quem já
trabalha com o CDI, mas que para "marinheiros de primeira viagem" possam não ser naturais.
- Injections null em construtores e como o CDI os trata
A verdade sobre construtores é: JAMAIS coloque muita responsabilidade em construtores. Construtores servem para
inicializar um objeto, desde que não se tenha muitas dependências para realizar isso. Ao usar CDI, até recomendo que nem
se crie um construtor. Você raramente (só para não dizer NUNCA) irá usar a keyword "new" para instanciar objetos CDI.
Deixe o container cuidar disso pra você.
O CDI primeiramente cria o objeto para só DEPOIS injetar as instâncias das dependências. Ou seja: se você está anotando
por fields, prepare-se para "agradáveis surpresas" (na real, NullPointerExceptions) se estiver usando estas dependências
já no construtor.
A partir desta observação e perder algum tempo com isso, exponho aqui 3 possibilidades para se injetar dependências
utilizando o CDI:
i) Annotation em fields
Definitivamente é a minha forma favorita. Basta inserir a annotation @Inject na frente da declaração de um atributo de
classe e era isso. Porém, caso você já necessite utilizar alguma instância desta injeção em um construtor, digo,
inicialização de objeto, você terá que:
i.1) Mandar os construtores pro "beleléu": exclua-os, pois definitivamente você não precisará deles;
i.2) "Migrar" o seu código de inicialização de objeto para um método específico de inicialização e o anote com
"@PostConstruct". Dessa forma, o CDI "automagicamente" irá disparar este método logo após a construção dele, já com as
injeções devidamente feitas.
ii) Annotation em methods
Esta forma é para aqueles que são "old school" e preferem manter o construtor e/ou anotar métodos. A injeção aqui é
simples também: basta anotar o método ou construtor com "@Inject" e inserir os parâmetros em camelCase na chamada do seu
método ou construtor e, se necessário, atribuir este valor injetado para o atributo da classe. Aqui, novamente o CDI vai
te reservar uma surpresa caso você esteja fazendo a injeção em um construtor: lembra do que mencionei anteriormente, de
que construtores não podem ter muita responsabilidade? Pois é... O CDI segue a risca isso, e
como é ele quem gerencia a instanciação dos seus objetos, ele espera um construtor simples, sem argumentos. Logo, caso
você venha a usar "@Inject" no seu construtor, não se esqueça de criar um construtor sem parâmetros na sua classe.
iii) "Lookup" através do BeanManager
O método getBeans e getReference desta classe vão lhe ajudar a fazer este "lookup". Alguns frameworks encapsulam a
chamada a estes dois métodos em um método estático ou em classe utilitária para resumir isto em uma chamada só. Consulte
a documentação do framework que você esteja utilizando para verificar como ele pode lhe ajudar nisso. PORÉM, só
recomendo usar esta forma de injeção somente em ÚLTIMO caso onde realmente não se esteja conseguindo injetar.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment