Created
April 11, 2012 19:15
-
-
Save jeffbicca/2361562 to your computer and use it in GitHub Desktop.
Revisions
-
jeffbicca created this gist
Apr 11, 2012 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,40 @@ 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.