blob: 0150944ea2544ecf75b8092e6ddf5cdcd4b3c4c9 [file] [log] [blame]
//
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
//
= Trabalhando com Injeção e Qualificadores no CDI
:jbake-type: tutorial
:jbake-tags: tutorials
:jbake-status: published
:icons: font
:syntax: true
:source-highlighter: pygments
:toc: left
:toc-title:
:description: Trabalhando com Injeção e Qualificadores no CDI - Apache NetBeans
:keywords: Apache NetBeans, Tutorials, Trabalhando com Injeção e Qualificadores no CDI
_Contribuição de Andy Gibson_
== Injeção de Dependência e Contextos
1. link:cdi-intro.html[+Introdução ao CDI e ao JSF 2.0+]
2. *Trabalhando com Injeção e Qualificadores no CDI*
* <<inject,Injeção: o "I" no CDI>>
* <<qualifier,Trabalhando com Qualificadores>>
* <<alternative,Métodos de Injeção Alternativos>>
* <<seealso,Consulte Também>>
[start=3]
. link:cdi-validate.html[+Aplicando Anotações @Alternative Beans e de Ciclo de Vida+]
[start=4]
. link:cdi-events.html[+Trabalhando com Eventos no CDI+]
A Injeção de Dependência e Contextos (CDI), especificada por link:http://jcp.org/en/jsr/detail?id=299[+JSR-299+], é parte integrante do Java EE 6 e fornece uma arquitetura que permite aos componentes do Java EE, como os servlets, enterprise beans e JavaBeans, existirem dentro do ciclo de vida de uma aplicação com escopos bem definidos. Além disso, os serviços CDI permitem que os componentes do Java EE, como beans de sessão EJB e beans gerenciados do JavaServer Faces (JSF), sejam injetados e interajam de maneira acoplada flexível, disparando e observando eventos.
Este tutorial tem base no post do blog de Andy Gibson, intitulado link:http://www.andygibson.net/blog/index.php/2009/12/22/getting-started-with-cdi-part-2-injection/[+Introdução ao CDI parte 2: Injeção+]. Ele demonstra como é possível utilizar a injeção de CDI para _injetar_ classes ou interfaces em outras classes. Também mostra como aplicar _qualificadores _ CDI ao código, de modo que seja possível especificar qual tipo de classe deverá ser injetada em um determinado ponto de injeção.
O NetBeans IDE fornece um suporte incorporado para a Injeção de Dependência e Contextos, incluindo a opção de geração do arquivo de configuração de CDI `beans.xml` durante a criação do projeto, do editor e do suporte de navegação para anotações, assim como vários assistentes para a criação de artefatos CDI comumente utilizados.
Para concluir este tutorial, você precisa dos seguintes recursos e softwares.
|===
|Software ou Recurso |Versão Necessária
|link:https://netbeans.org/downloads/index.html[+NetBeans IDE+] |Versão Java EE 7.2, 7.3, 7.4, 8.0
|link:http://www.oracle.com/technetwork/java/javase/downloads/index.html[+JDK (Java Development Kit)+] |versão 7 ou 8
|link:http://glassfish.dev.java.net/[+GlassFish Server+] |Open Source Edition 3.x ou 4.x
|link:https://netbeans.org/projects/samples/downloads/download/Samples%252FJavaEE%252FcdiDemo.zip[+cdidemo.zip +] |n/d
|===
*Observações:*
* O pacote Java EE do NetBeans inclui também o GlassFish Server Open Source Edition, que é um contêiner compatível com Java EE.
* Pode ser feito o download do projeto de amostra de solução para esse tutorial: link:https://netbeans.org/projects/samples/downloads/download/Samples%252FJavaEE%252FcdiDemo2.zip[+cdiDemo2.zip+]
[[inject]]
== Injeção: o "I" do CDI
O CDI é uma API para injeção de dependências e contextos. Em Seam e Spring, as dependências funcionam, principalmente, nomeando beans e os vinculando aos seus pontos de injeção pelos nomes. Se estiver seguindo este tutorial depois de ter concluído link:cdi-intro.html[+Introdução a Injeção de Dependência e Contextos e JSF 2.0+], você terá, até agora, feito referência apenas a um bean gerenciado por nome, da página do JSF, quando definimos o nome para o bean utilizando a anotação `@Named`. A atribuição principal da anotação `@Named` é definir o bean com o objetivo de resolver instruções EL na aplicação, normalmente por meio dos resolvedores JSF EL. A injeção _poderia_ ser executada com o uso de nomes, mas não era assim que a injeção no CDI deveria funcionar, já que o CDI nos proporciona uma maneira muito mais rica de expressar pontos de injeção e os beans a serem injetados neles.
No exemplo a seguir, você cria um `ItemProcessor` que pega uma lista de itens de uma classe que implementa a interface do `ItemDao`. Aproveite a anotação `@Inject` do CDI para demonstrar como é possível _injetar_ um bean em outra classe. O diagrama a seguir retrata o cenário construído neste exercício.
image::images/cdi-diagram-inject.png[title="Use a injeção de CDI para acoplar, livremente, as classes na sua aplicação"]
DAO significa _data access object_.
1. Comece extraindo o projeto de início da amostra do arquivo `cdiDemo.zip` (Consulte a <<requiredSoftware,tabela que lista os recursos necessários>> acima.) Abra o projeto no IDE escolhendo Arquivo > Abrir Projeto (Ctrl-Shift-O; ⌘-Shift-O no Mac) e, em seguida, selecionando o projeto no seu local no computador.
2. Clique com o botão direito do mouse no nó do projeto na janela Projetos e escolha Propriedades.
3. Selecione a categoria Executar e confirme se a instância do GlassFish está selecionada na lista drop-down Servidor.
4. Crie uma nova classe `Item` e armazene-a em um novo pacote nomeado `exercise2`. Clique no botão Novo Arquivo (image:images/new-file-btn.png[]) ou pressione CTRL-N (⌘-N no Mac) para abrir o assistente de Arquivo.
5. Selecione a categoria Java e, em seguida, a Classe Java. Clique em Próximo.
6. Informe *Item* como o nome da classe e, em seguida, *exercise2* como o pacote. (O novo pacote é criado após a conclusão do assistente.)
image::images/java-class-wizard.png[title="Criar uma nova classe Java usando o assistente de Arquivo"]
[start=7]
. Clique em Finalizar. A nova classe e o novo pacote são gerados e a classe `item` é aberta no editor.
[start=8]
. Crie as propriedades `value` e `limit` para o POJO do `Item` e implemente o método `toString()`. Adicione o conteúdo a seguir à classe.
[source,java]
----
public class Item {
*private int value;
private int limit;
@Override
public String toString() {
return super.toString() + String.format(" [Value=%d, Limit=%d]", value,limit);
}*
}
----
[start=9]
. Adicione os métodos getter e setter à classe. Para isso, garanta que o cursor esteja colocado entre a definição de classe (ou seja, entre as chaves da classe) e, em seguida, clique com o botão direito do mouse no editor e escolha Inserir Código (Alt-Insert; Ctrl-I no Mac). Escolha Getter e Setter.
image::images/insert-code.png[title="Criar getters e setters usando o pop-up Inserir Código"]
[start=10]
. Marque a caixa de seleção `Item` (fazer isso seleciona todas as propriedades contidas na classe).
image::images/generate-getters-setters.png[title="Marque a caixa de seleção da classe para selecionar todas as propriedades contidos na classe"]
[start=11]
. Clique em Gerar. Os métodos getter e setter são gerados para a classe.
[source,java]
----
public class Item {
private int value;
private int limit;
*public int getLimit() {
return limit;
}
public void setLimit(int limit) {
this.limit = limit;
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}*
@Override
public String toString() {
return super.toString() + String.format(" [Value=%d, Limit=%d]", value, limit);
}
}
----
[start=12]
. Crie um construtor que utilize os argumentos `value` e `limit`. Novamente, o IDE pode ajudar com isso. Pressione Ctrl-Espaço na definição da classe e escolha a opção "`Item(int value, int limit) - generate`".
image::images/generate-constructor.png[title="Pressione Ctrl-Espaço para utilizar os recursos de autocompletar código do editor"]
O construtor a seguir é adicionado à classe.
[source,java]
----
public class Item {
*public Item(int value, int limit) {
this.value = value;
this.limit = limit;
}*
private int value;
private int limit;
...
----
[start=13]
. Crie uma interface `ItemDao` para definir como obtemos a lista de objetos `Item`. Nesta aplicação de teste, antecipamos o uso de várias implementações, portanto, codificaremos para interfaces.
Clique no botão Novo Arquivo (image:images/new-file-btn.png[]) ou pressione CTRL-N (⌘-N no Mac) para abrir o assistente de Arquivo.
[start=14]
. Selecione a categoria Java e, em seguida, selecione Interface Java. Clique em Próximo.
[start=15]
. Digite *ItemDao* como o nome da classe e, em seguida, insira *exercise2* como o pacote.
[start=16]
. Clique em Finalizar. A nova interface será gerada e aberta no editor.
[start=17]
. Adicione um método chamado `fetchItems()` que retorna uma `Lista` de objetos `Item`.
[source,java]
----
public interface ItemDao {
*List<Item> fetchItems();*
}
----
(Utilize a dica do editor para adicionar a instrução de importação de `java.util.List`.)
[start=18]
. Crie uma classe `ItemProcessor`. É a classe principal em que você injetará seus beans e da qual executará o processo. Por enquanto, iniciaremos com a DAO e examinaremos como será feita a sua injeção no nosso bean processador.
Clique no botão Novo Arquivo (image:images/new-file-btn.png[]) ou pressione CTRL-N (⌘-N no Mac) para abrir o assistente de Arquivo.
[start=19]
. Selecione a categoria Java e, em seguida, a Classe Java. Clique em Próximo.
[start=20]
. Digite *ItemProcessor* como o nome da classe e, em seguida, *exercise2* como o pacote. Clique em Finalizar.
A nova classe é gerada e aberta no editor.
[start=21]
. Modifique a classe como se segue:
[source,java]
----
@Named
@RequestScoped
public class ItemProcessor {
private ItemDao itemDao;
public void execute() {
List<Item> items = itemDao.fetchItems();
for (Item item : items) {
System.out.println("Found item " + item);
}
}
}
----
[start=22]
. Corrigir importações. Clique com o botão direito do mouse no editor e selecione Corrigir Importações ou pressione Ctrl-Shift-I (⌘-Shift-I no Mac).
image::images/fix-imports.png[title="Clique com o botão direito do mouse no editor e escolha Corrigir Importações para adicionar instruções de importação à classe"]
[start=23]
. Clique em OK. Instruções de importação para as classes a seguir são necessárias:
* `java.util.List`
* `javax.inject.Named`
* `javax.enterprise.context.RequestScoped`
[start=24]
. Comece com um DAO simples que apenas cria uma lista de itens e retorna uma lista fixa de itens.
Na janela Projetos, clique com o botão direito do mouse no nó de pacote `exercise2` e escolha Novo > Classe Java. No assistente de Classe Java, nomeie a classe `DefaultItemDao`. Clique em Finalizar.
image::images/java-class-wizard2.png[title="Criar uma nova classe Java usando o assistente de Classe Java"]
[start=25]
. No editor, faça com que `DefaultItemDao` implemente a interface `ItemDao` e forneça uma implementação de `fetchItems()`.
[source,java]
----
public class DefaultItemDao *implements ItemDao* {
*@Override
public List<Item> fetchItems() {
List<Item> results = new ArrayList<Item>();
results.add(new Item(34, 7));
results.add(new Item(4, 37));
results.add(new Item(24, 19));
results.add(new Item(89, 32));
return results;
}*
}
----
(Pressione Ctrl-Shift-I (⌘-Shift-I no Mac) para adicionar instruções de importação para `java.util.List` e `java.util.ArrayList`.)
[start=26]
. Mude para a classe `ItemProcessor` (pressione Ctrl-Tab). Para injetar o `DefaultItemDao` no `ItemProcessor`, adicionamos a anotação `javax.inject.Inject` ao campo `ItemDao` para indicar que esse campo é um ponto de injeção.
[source,java]
----
*import javax.inject.Inject;*
...
@Named
@RequestScoped
public class ItemProcessor {
*@Inject*
private ItemDao itemDao;
...
}
----
TIP: Utilize o suporte à funcionalidade autocompletar código do editor para adicionar a anotação `@Inject` e a instrução de importação à classe. Por exemplo, digite "`@Inj`" e, em seguida, pressione Ctrl-Espaço.#
[start=27]
. Finalmente, precisamos de alguma maneira para chamar o método `execute()` no `ItemProcessor`. Podemos executá-lo em um ambiente SE, mas, no momento, o manteremos em uma página JSF. Crie uma nova página chamada `process.xhtml` que contém um botão para chamar o método `execute()`.
Clique no botão Novo Arquivo (image:images/new-file-btn.png[]) ou pressione CTRL-N (⌘-N no Mac) para abrir o assistente de Arquivo.
[start=28]
. Selecione a categoria JavaServer Faces e selecione a Página JSF. Clique em Próximo.
[start=29]
. Digite *processo* como o nome do arquivo e clique em Finalizar.
image::images/new-jsf-page.png[title="Criar uma nova página Facelets usando o assistente de arquivo JSF"]
[start=30]
. No novo arquivo `process.xhtml`, adicione um botão que esteja conectado ao método `ItemProcessor.execute()`. Utilizando EL, o nome default para o bean gerenciado é o mesmo que o nome da classe, mas com a primeira letra minúscula (por exemplo., `itemProcessor`).
[source,xml]
----
<h:body>
*<h:form>
<h:commandButton action="#{itemProcessor.execute}" value="Execute"/>
</h:form>*
</h:body>
----
[start=31]
. Antes de executar o projeto, defina o arquivo `process.xhtml` como a nova página de boas-vindas no descritor de implantação web do projeto.
Utilize a caixa de diálogo Ir para Arquivo do IDE para abrir rapidamente o arquivo `web.xml`. Escolha Navegar > Ir para Arquivo no menu principal do IDE (Alt-Shift-O; Ctrl-Shift-O no Mac) e, em seguida, digite "`web`".
image::images/go-to-file.png[title="Use a caixa de diálogo Ir para Arquivo para localizar rapidamente um arquivo de projeto"]
[start=32]
. Clique em OK. Na view XML do arquivo `web.xml`, faça a alteração a seguir.
[source,xml]
----
<welcome-file-list>
<welcome-file>faces/*process.xhtml*</welcome-file>
</welcome-file-list>
----
[start=33]
. Clique no botão Executar Projeto (image:images/run-project-btn.png[]) na barra de ferramentas principal do IDE. O projeto é compilado e implantado no GlassFish e o arquivo `process.xhtml` será aberto no browser.
[start=34]
. Clique no botão "`Execute`" que é exibido na página. Volte ao IDE e examine o log do GlassFish Server. O log do servidor é exibido na janela Saída (Ctrl-4; ⌘-4 no Mac) na guia GlassFish Server. Quando o botão é clicado, o log lista os itens da nossa implementação de DAO default.
image::images/output-window.png[title="Examine o log do servidor na janela Saída do IDE"]
TIP: Clique com o botão direito do mouse na janela Saída e escolha Limpar (Ctrl-L; ⌘-L no Mac) para limpar o log. Na imagem acima, o log foi limpo pouco antes de clicar no botão "`Execute`".#
Criamos uma classe que implementa a interface `ItemDao` e quando a aplicação foi implantada, nossos beans gerenciados no módulo foram processados pela implementação do CDI (por causa do arquivo `beans.xml` no módulo). Nossa anotação `@Inject` especifica que queremos injetar um bean gerenciado nesse campo e a única coisa que sabemos sobre o bean injetável é que ele deve implementar `ItemDao` ou algum subtipo dessa interface. Nesse caso, a classe `DefaultItemDao` se adapta perfeitamente.
O que aconteceria se houvesse várias implementações de `ItemDao` que pudessem ter sido injetadas? O CDI não saberia qual implementação escolher e sinalizaria um erro de tempo de implantação. Para superar isso, seria necessário utilizar um qualificador CDI. Qualificadores são explorados na próxima seção.
[[qualifier]]
== Trabalhando com Qualificadores
Um qualificador CDI é uma anotação que pode ser aplicada no nível da classe para indicar o tipo de bean que a classe é e, no nível do campo (entre outros lugares), para indicar que tipo de bean precisa ser injetado nesse ponto.
Para demonstrar a necessidade de um qualificador na aplicação que estamos construindo, vamos adicionar outra classe DAO à nossa aplicação, que também implementa a interface `ItemDao`. O diagrama a seguir retrata o cenário que você está construindo neste exercício. O CDI deve conseguir determinar qual implementação de bean deverá ser utilizada em um ponto de injeção. Como há duas implementações de `ItemDao`, podemos resolver isso criando um qualificador chamado `Demo`. Em seguida, "marcamos" o bean que queremos utilizar e o ponto de injeção em `ItemProcessor` com uma anotação `@Demo`.
image::images/cdi-diagram-qualify.png[title="Use a injeção e os qualificadores de CDI para acoplar, livremente, as classes na sua aplicação"]
Execute as seguintes etapas.
1. Na janela Projetos, clique com o botão direito do mouse no pacote `exercise2` e escolha Novo > Classe Java.
2. No assistente Nova Classe Java, nomeie a nova classe *AnotherItemDao* e clique em Finalizar. A nova classe é gerada e aberta no editor.
3. Modifique a classe como se segue, de modo que ela implemente a interface `ItemDao` e defina o método `fetchItems()` da interface.
[source,java]
----
public class AnotherItemDao *implements ItemDao* {
*@Override
public List<Item> fetchItems() {
List<Item> results = new ArrayList<Item>();
results.add(new Item(99, 9));
return results;
}*
}
----
Certifique-se de adicionar instruções de importação para `java.util.List` e `java.util.ArrayList`. Para isso, clique com o botão direito do mouse no editor e escolha Corrigir Importações ou pressione Ctrl-Shift-I (⌘-Shift-I no Mac).
Agora que há duas classes que implementam o `ItemDao`, a escolha não está tão clara com relação a em qual bean queremos injetar.
[start=4]
. Clique no botão Executar Projeto (image:images/run-project-btn.png[]) para executar o projeto. Observe que o projeto agora falha na implantação.
Provavelmente, você só precisa salvar o arquivo porque o IDE implantará o projeto automaticamente, visto que a opção Implantar ao Salvar está ativada por default.
[start=5]
. Examine o log do servidor na janela Saída (Ctrl-4; ⌘-4 no Mac). Será exibida uma mensagem de erro semelhante ao seguinte.
[source,java]
----
Caused by: org.jboss.weld.DeploymentException: Injection point has ambiguous dependencies.
Injection point: field exercise2.ItemProcessor.itemDao;
Qualifiers: [@javax.enterprise.inject.Default()];
Possible dependencies: [exercise2.DefaultItemDao, exercise2.AnotherItemDao]
----
Para quebrar o texto em várias linhas na janela Saída, clique com o botão direito do mouse e escolha Quebrar texto. Isso elimina a necessidade de rolar horizontalmente.
Weld, a implementação para CDI, nos proporciona um erro de dependência ambígua, o que significa que não pode determinar qual bean utilizar para o ponto de injeção determinado. A maioria dos erros, se não todos, que podem ocorrer com relação à injeção CDI em Weld são informados no momento da implantação, até mesmo se os beans ativados para passivação estiverem sem uma implementação `Serializable`.
Poderíamos tornar nosso campo `itemDao` no `ItemProcessor` um tipo específico que corresponde a um dos tipos de implementação (`AnotherItemDao` ou `DefaultItemDao`), já que corresponderia, em seguida, a um e apenas um tipo de classe. No entanto, perderíamos os benefícios da codificação para uma interface e seria mais difícil alterar as implementações sem alterar o tipo de campo. Uma solução melhor seria, portanto, examinarmos os qualificadores de CDI.
Quando o CDI inspeciona um ponto de injeção para encontrar um bean adequado para injetar, não leva em conta apenas o tipo de classe, mas também todos os qualificadores. Sem saber disso, já utilizamos um qualificador que é o qualificador default chamado `@Any`. Vamos criar um qualificador `@Demo` que podemos aplicar à nossa implementação de `DefaultItemDao` e também ao ponto de injeção em `ItemProcessor`.
O IDE fornece um assistente que permite gerar qualificadores CDI.
[start=6]
. Clique no botão Novo Arquivo (image:images/new-file-btn.png[]) ou pressione CTRL-N (⌘-N no Mac) para abrir o assistente de Arquivo.
[start=7]
. Selecione a categoria Injeção de Dependência e Contexto e, em seguida, selecione Tipo de Qualificador. Clique em Próximo.
[start=8]
. Digite *Demo* como o nome da classe e, em seguida, *exercise2* como o pacote.
[start=9]
. Clique em Finalizar. O novo qualificador `Demo` será aberto no editor.
[source,java]
----
package exercise2;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.PARAMETER;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import javax.inject.Qualifier;
/**
*
* @author nbuser
*/
@Qualifier
@Retention(RUNTIME)
@Target({METHOD, FIELD, PARAMETER, TYPE})
public @interface Demo {
}
----
Em seguida, você adicionará este qualificador à implementação DAO default no nível da classe.
[start=10]
. Altere para `DefaultItemDao` no editor (pressione Ctrl-Tab) e, em seguida, digite "`@Demo`" acima da definição da classe.
[source,java]
----
*@Demo*
public class DefaultItemDao implements ItemDao {
@Override
public List<Item> fetchItems() {
List<Item> results = new ArrayList<Item>();
results.add(new Item(34, 7));
results.add(new Item(4, 37));
results.add(new Item(24, 19));
results.add(new Item(89, 32));
return results;
}
}
----
TIP: Depois de digitar "`@`", pressione Ctrl-Espaço para chamar sugestões da funcionalidade autocompletar código. O editor reconhece o qualificador `Demo` e lista `@Demo` como uma opção para a funcionalidade autocompletar código.#
[start=11]
. Clique no botão Executar Projeto (image:images/run-project-btn.png[]) para executar o projeto. O projeto será compilado e implantado sem erros.
*Observação.* Para esta modificação talvez você precise executar explicitamente o projeto para reimplantar a aplicação, em vez de implantar incrementalmente as alterações.
[start=12]
. No browser, clique no botão "`Execute`", retorne para o IDE e examine o log do servidor na janela Saída. Você verá a seguinte saída.
[source,java]
----
INFO: Found item exercise2.Item@1ef62a93 [Value=99, Limit=9]
----
A saída lista o item da classe `AnotherItemDao`. Lembre-se de que anotamos a implementação `DefaultItemDao`, mas não o ponto de injeção em `ItemProcessor`. Adicionando o qualificador `@Demo` à implementação DAO default, tornamos a outra implementação uma correspondência mais adequada para o ponto de injeção, pois houve coincidência no tipo e no qualificador. O `DefaultItemDao` tem, no momento, o qualificador `Demo`, que não está no ponto de injeção, o que o torna, portanto, menos adequado.
Em seguida, você adicionará a anotação `@Demo` ao ponto de injeção em `ItemProcessor`.
[start=13]
. Altere para `ItemProcessor` no editor (pressione Ctrl-Tab) e, em seguida, faça a seguinte alteração.
[source,java]
----
@Named
@RequestScoped
public class ItemProcessor {
@Inject *@Demo*
private ItemDao itemDao;
public void execute() {
List<Item> items = itemDao.fetchItems();
for (Item item : items) {
System.out.println("Found item " + item);
}
}
}
----
[start=14]
. No browser, clique no botão "`Execute`", retorne para o IDE e examine o log do servidor na janela Saída. Você verá, novamente, a saída da implementação default (`DefaultItemDao`).
[source,java]
----
INFO: Found item exercise2.Item@7b3640f1 [Value=34, Limit=7]
INFO: Found item exercise2.Item@26e1cd69 [Value=4, Limit=37]
INFO: Found item exercise2.Item@3274bc70 [Value=24, Limit=19]
INFO: Found item exercise2.Item@dff76f1 [Value=89, Limit=32]
----
Isso ocorre porque agora estamos fazendo a correspondência com base em qualificadores do tipo _and_, e `DefaultItemDao` é o único bean com o tipo correto e a anotação `@Demo`.
[[alternative]]
== Métodos de Injeção Alternativos
Há várias maneiras de definir um ponto de injeção na classe injetada. Até agora, anotamos os campos que fazem referência ao objeto injetado. Não é necessário fornecer getters e setters para a injeção de campo. Se quisermos criar beans gerenciados imutáveis com campos finais, poderemos utilizar a injeção no construtor anotando-o com a anotação `@Inject`. Em seguida, poderemos aplicar quaisquer anotações aos parâmetros do construtor para qualificar os beans para injeção. (Claro, cada parâmetro tem um tipo que pode ajudar na qualificação de beans para injeção). Um bean pode ter apenas um construtor com pontos de injeção definidos, mas pode implementar mais de um construtor.
[source,java]
----
@Named
@RequestScoped
public class ItemProcessor {
private final ItemDao itemDao;
@Inject
public ItemProcessor(@Demo ItemDao itemDao) {
this.itemDao = itemDao;
}
}
----
Também podemos chamar um método de inicialização que pode ser passado a um bean a ser injetado.
[source,java]
----
@Named
@RequestScoped
public class ItemProcessor {
private ItemDao itemDao;
@Inject
public void setItemDao(@Demo ItemDao itemDao) {
this.itemDao = itemDao;
}
}
----
Embora no caso acima tenhamos utilizado o método setter para a inicialização, podemos criar qualquer método e utilizá-lo para a inicialização com quantos beans quisermos na chamada do método. Também podemos ter vários métodos de inicialização em um bean.
[source,java]
----
@Inject
public void initBeans(@Demo ItemDao itemDao, @SomeQualifier SomeType someBean) {
this.itemDao = itemDao;
this.bean = someBean;
}
----
As mesmas regras se aplicam à correspondência de beans, independente de como o ponto de injeção é definido. O CDI tentará encontrar a melhor correspondência, com base no tipo e nos qualificadores, e haverá falha na implantação se houver vários beans correspondentes ou nenhum bean correspondente para um ponto de injeção.
link:/about/contact_form.html?to=3&subject=Feedback:%20Working%20with%20Injection%20and%20Qualifiers%20in%20CDI[+Enviar Feedback neste Tutorial+]
[[seealso]]
== Consulte Também
Vá para o próximo artigo desta série sobre Injeção de Dependência e Contextos:
* link:cdi-validate.html[+Aplicando Anotações @Alternative Beans e de Ciclo de Vida+]
Para obter mais informações sobre o CDI e o Java EE, consulte os recursos a seguir.
* link:cdi-intro.html[+Introdução à Injeção de Dependência e Contextos e JSF 2.0+]
* link:javaee-gettingstarted.html[+Conceitos Básicos sobre Aplicações do Java EE+]
* link:http://blogs.oracle.com/enterprisetechtips/entry/using_cdi_and_dependency_injection[+Dica Técnica do Enterprise: Utilizando Injeção de Dependência e de CDI para Java em uma Aplicação JSF 2.0+]
* link:http://download.oracle.com/javaee/6/tutorial/doc/gjbnr.html[+O Tutorial do Java EE 6, Parte V: Injeção de Dependência e Contextos para a Plataforma Java EE+]
* link:http://jcp.org/en/jsr/detail?id=299[+JSR 299: Especificação para Injeção de Dependência e Contextos+]