// 
//     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.
//

= Conceitos Básicos sobre a Injeção de Dependência e Contextos e JSF 2.x
:jbake-type: tutorial
:jbake-tags: tutorials 
:jbake-status: published
:icons: font
:syntax: true
:source-highlighter: pygments
:toc: left
:toc-title:
:description: Conceitos Básicos sobre a Injeção de Dependência e Contextos e JSF 2.x - Apache NetBeans
:keywords: Apache NetBeans, Tutorials, Conceitos Básicos sobre a Injeção de Dependência e Contextos e JSF 2.x

_Contribuição de Andy Gibson_


== Injeção de Dependência e Contextos

1. *Introdução ao CDI e ao JSF 2.0*
* <<creating,Criação de um Projeto Java Web com o Suporte de CDI>>
* <<named,Acessando Beans a partir da Linguagem de Expressão do JSF>>
* <<upgrading,Atualizando para um EJB>>
* <<seealso,Consulte Também>>


. link:cdi-inject.html[+Trabalhando com Injeção e Qualificadores no CDI+]


. link:cdi-validate.html[+Aplicando Anotações @Alternative Beans e de Ciclo de Vida+]


. 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/16/getting-started-with-jsf-2-0-and-cdi-in-jee-6-part-1/[+Introdução ao JSF 2.0 e CDI no JEE 6+]. Ele demonstra como utilizar o IDE para configurar um projeto Java Web com suporte para JSF 2.0 e CDI. Ele prossegue mostrando como conectar beans gerenciados CDI com as páginas Facelets e conclui com um breve exemplo da integração do CDI com a tecnologia EJB.

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+] |Pacote 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 
|===

NOTE: O pacote Java EE do NetBeans inclui também o GlassFish Server Open Source Edition, que é um contêiner compatível com Java EE.


[[creating]]
== Criação do Projeto Java Web com o Suporte CDI

Neste exercício, será criado um projeto Java Web ativado para JSF 2.x com o suporte CDI.

1. Clique no botão Novo Projeto (image:images/new-project-btn.png[]) na barra de ferramentas principal do IDE (Ctrl-Shift-N; ⌘-Shift-N no Mac).
2. No assistente Novo projeto, selecione a categoria Java Web e, em seguida, selecione Aplicação da Web. Clique em Próximo.
3. Digite `cdiDemo` como o nome do projeto e defina a localização do projeto. Clique em Próximo.
4. Defina o servidor como GlassFish.
5. Defina a Versão do Java EE como Java EE 6 Web ou Java EE 7 Web.

NOTE:  A versão do Java EE selecionada determina a versão do CDI ativada para sua aplicação e existem algumas diferenças importantes entre CDI 1.0 e CDI 1.1.

* Se você especificar o Java EE 6 Web como a versão do Java EE, confirme se a opção 'Ativar Injeção de Dependência e Contextos' está selecionada. A opção "Ativar injeção de dependência e contextos", quando selecionada, gera um arquivo `beans.xml` na pasta `WEB-INF` do projeto quando o modelo do projeto é criado. O arquivo `beans.xml` é utilizado pelo CDI para instruir o servidor compatível com Java EE que o projeto é um módulo que contém beans CDI. O Java EE 6 Web suporta CDI 1.0 e o arquivo `beans.xml` gerado especifica o CDI 1.0 como a versão.
* Se você especificar o Java EE 7 Web como a versão do Java EE, o CDI 1.1 será ativado por padrão e o arquivo  ``beans.xml``  não será necessário. No Java EE 7, quando nenhum  ``beans.xml``  estiver presente, o archive implantado será um *archive de bean implícito*. Se você usar o assistente de Novo Arquivo no IDE para gerar manualmente um arquivo `beans.xml` em uma aplicação Java EE 7 Web, por padrão, o archive implantado se tornará um *archive de bean explícito* porque o arquivo `beans.xml` especifica CDI 1.1 como versão e define também o atributo do  ``bean-discovery-mode``  como  ``all`` .

Para obter mais detalhes sobre os tipos de archives de CDI, consulte link:http://docs.oracle.com/javaee/7/tutorial/doc/cdi-adv001.htm[+Encapsulando Aplicações CDI+] no Tutorial do Java EE 7.

image::images/new-web-application1.png[title="A opção CDI, quando selecionada, gera um arquivo beans.xml para o projeto"]



. Clique em Próximo.


. No painel Frameworks, selecione a opção JavaServer Faces.


. Clique na guia Configuração e confirme se Facelets está selecionada como a Linguagem de Página Preferencial. Clique em Finalizar.

Quando você clica em Finalizar, o IDE gera o projeto de aplicação Web e abre a página de boas-vindas do arquivo `index.xhtml` no editor.



. Na janela Projetos, expanda o nó Bibliotecas > GlassFish Server para ver se a biblioteca `weld-osgi-bundle.jar` foi adicionada automaticamente. O GlassFish Server inclui o Weld, que é uma implementação do JBoss da especificação JSR-299 CDI. 

image::images/projects-window1.png[title="Novo projeto contém arquivo beans.xml do CDI e a biblioteca do GlassFish inclui o arquivo Weld JAR"]

Se você especificou Java EE 6 Web como a versão do Java EE quando criou o projeto, observe que a pasta Páginas Web > WEB-INF inclui um arquivo `beans.xml`. Este arquivo está atualmente vazio, mas pode ser utilizado para especificar informações relacionadas ao bean no XML como alternativa a anotações.


[[named]]
== Acessando o Beans a partir da Linguagem de Expressão do JSF

Este exercício demonstra como conectar os beans gerenciados do CDI às páginas Facelets utilizando a sintaxe EL.

1. Na janela Projetos, clique com o botão direito do mouse no nó Pacotes de Código-Fonte e selecione Nova > Classe Java.
2. No assistente Nova classe Java, nomeie a classe como *MessageServerBean* e digite *exercício1* como o Pacote. (O novo pacote é criado após a conclusão do assistente.) Clique em Finalizar. 

image::images/new-java-class.png[title="Criar novas classes Java usando o assistente de Classe Java"]

O novo pacote e a nova classe serão gerados e a classe será aberta no editor.



. Anote a classe com as anotações `@Named` e `@Dependent` e crie um único método para retornar uma string.

[source,java]
----

package exercise1;

*import javax.enterprise.context.Dependent;
import javax.inject.Named;*

*@Dependent
@Named*
public class MessageServerBean {

    *public String getMessage() {
        return "Hello World!";
    }*
}
----

Conforme você digita as anotações `@Dependent` e `@Named`, pressione Ctrl-Espaço para chamar o suporte ao preenchimento de código do editor, bem como a documentação Javadoc. Se aplicar a anotação utilizando os recursos de autocompletar código (ou seja, selecionar a anotação apropriada e pressionar Enter), a instrução `import` será automaticamente adicionada ao arquivo. No pop-up Javadoc você também pode clicar no botão "Mostrar documentação em browser externo da Web" (image:images/external-web-browser-btn.png[]) para exibir o Javadoc de tamanho completo em uma janela separada.

NOTE:  A anotação  ``@Dependent``  define o escopo do bean gerenciado. Em um *archive de bean implícito*, um bean gerenciado só pode ser descoberto e gerenciado pelo contêiner quando um escopo é especificado. A aplicação neste tutorial será encapsulada como um archive de bean implícito se você especificou o Java EE 7 Web como a versão do Java EE quando criou o projeto e não criou  ``beans.xml`` . Para obter detalhes sobre como especificar o escopo de beans gerenciados, consulte link:http://docs.oracle.com/javaee/7/tutorial/doc/jsf-configure001.htm[+Usando Anotações para Configurar Beans Gerenciados+] no Tutorial do Java EE 7.


. Salve o arquivo (Ctrl-S; ⌘-S no Mac). Com a adição da anotação `@Named`, a classe `MessageServerBean` se torna um _bean gerenciado_, como definido pelo CDI.


. Vá para a página Facelets `index.xhtml` (pressione Crtl-Tab) no editor e adicione o seguinte conteúdo às tags `<h:body>`.

[source,xml]
----

<h:body>
    Hello from Facelets
    *<br/>
    Message is: #{messageServerBean.message}
    <br/>
    Message Server Bean is: #{messageServerBean}*
</h:body>
----

TIP: Você pode pressionar Ctrl-Espaço nas expressões EL para aproveitar as sugestões da funcionalidade autocompletar código. A funcionalidade autocompletar código do editor lista os beans gerenciados e suas propriedades. Como a anotação `@Named` transforma a classe `MessageServerBean` em um bean gerenciado CDI, ela se torna acessível na sintaxe EL, como se fosse um bean gerenciado JSF.# 


image::images/facelets-el-completion.png[title="Criar novas classes Java usando o assistente de Classe Java"]



. Clique no botão Executar Projeto (image::images/run-project-btn.png[]) na barra de ferramentas principal do IDE. O projeto será compilado e implantado no GlassFish e a página de boas-vindas da aplicação (`index.xhtml`) será aberta no browser. Você poderá ver a mensagem "Olá Mundo!" do `MessageServerBean` exibida na página. 

image::images/browser-output1.png[title="A página de boas-vindas da aplicação exibe detalhes do MessageServerBean"]



. Volte para o bean da mensagem e altere a mensagem para algo diferente (ex., "Olá Weld!"). Salve o arquivo (Ctrl-S;⌘-S no Mac) e, em seguida, atualize o browser. A nova mensagem aparecerá automaticamente. Graças à Implantação do IDE no recurso Salvar, quaisquer alterações salvas resultarão em compilação automática e reimplantação no servidor. 

A partir da terceira linha da página você poderá ver que o nome da classe é `exercise1.MessageServerBean`. Observe que o bean é só um POJO (Plain Old Java Object - Objeto Java Antigo Simples). Embora esteja desenvolvendo no Java EE, não há hierarquia de classe complexa envolvida em camadas de transações, interceptores e todas as coisas "pesadas" que se costuma ouvir.


=== O que está Acontecendo?

Quando a aplicação é implantada, o servidor procura os beans gerenciados do CDI. Em uma aplicação Java EE 7, as classes do caminho são verificadas em busca de anotações de CDI por padrão. Em uma aplicação Java EE 6, as classes serão verificadas em busca de anotações de CDI se o módulo contiver um arquivo `beans.xml`. Em um módulo CDI, todos os beans são registrados com Weld, e a anotação `@Named` é utilizada para coincidir os beans com os pontos de injeção. Quando a página `index.xhtml` foi renderizada, o JSF tentou resolver o valor de `messageServerBean` na página, utilizando os resolvedores de expressão registrados no JSF. Um deles é o Resolvedor Weld EL, que tem a classe `MessageServerBean` registrada sob o nome `messageServerBean`. Poderíamos ter especificado um nome diferente com a anotação `@Named`, mas, como não fizemos isso, ele foi registrado sob o nome default, sendo que o nome da classe tem a primeira letra minúscula. O resolvedor Weld retorna uma instância desse bean em resposta à solicitação do JSF. A nomeação do bean só é necessária quando expressões EL são utilizadas e não deve ser utilizada como um mecanismo para injeção, já que o CDI fornece injeção segura por tipo de classe e anotações do qualificador.



[[upgrading]]
== Atualizando para um EJB

Como estamos utilizando uma pilha Java EE, podemos facilmente implantar o bean como um EJB com algumas pequenas alterações, graças ao EJB 3.1.

1. Abra o `MessageServerBean` e adicione a anotação `javax.ejb.Stateless` no nível da classe e altere a string para "Hello EJB!".

[source,java]
----

package exercise1;

*import javax.ejb.Stateless;*
import javax.enterprise.context.Dependent;
import javax.inject.Named;

/**
 *
 * @author nbuser
 */
@Dependent
@Named
*@Stateless*
public class MessageServerBean {

    public String getMessage() {
        return "*Hello EJB!*";
    }
}
----


. Salve o arquivo (Ctrl-S; ⌘-S no Mac), vá para o browser e atualize-o. Um resultado semelhante ao seguinte será visto: 

image::images/browser-output-ejb1.png[title="Usar a anotação @stateless transforma o MessageServerBean em um EJB"] 

De uma maneira impressionante, transformamos o POJO em um EJB com todas as funcionalidades com apenas uma anotação. Salvamos as alterações, atualizamos a página, e nossas alterações apareceram. Ao fazer isso, não foi necessário criar nenhuma configuração estranha do projeto, interfaces locais ou descritores de implantação obscuros.


=== Tipos diferentes de EJB

Você também pode tentar utilizar a anotação `@Stateful`. Outra alternativa, seria tentar a nova anotação `@Singleton` para instâncias singleton. Se fizer isso, poderá notar que há duas anotações: `javax.ejb.Singleton` e `javax.inject.Singleton`. Por que dois singletons? O singleton CDI (`javax.inject.Singleton`) lhe permite definir uma instância singleton fora do EJB, no caso de utilizar o CDI em um ambiente não-EJB. O singleton EJB (`javax.ejb.Singleton`) fornece todas as funcionalidades de um EJB, como gerenciamento de transação. Portanto, você pode optar, dependendo da necessidade e se está trabalhando em um ambiente EJB.

link:/about/contact_form.html?to=3&subject=Feedback:%20Getting%20Started%20with%20CDI%20and%20JSF%202.0[+Enviar Feedback neste Tutorial+]



[[seealso]]
== Consulte Também

O foco do próximo artigo desta série está na injeção CDI e oferece uma visão melhor do uso de CDI para gerenciar dependências em um ambiente Java EE.

* link:cdi-inject.html[+Trabalhando com Injeção e Qualificadores no CDI+]

Para obter mais informações sobre o CDI e o JSF 2.0, consulte os seguintes recursos.


=== Injeção de Dependência e Contextos

* link:cdi-validate.html[+Aplicando Anotações @Alternative Beans e de Ciclo de Vida+]
* link:cdi-events.html[+Trabalhando com Eventos no CDI+]
* 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://docs.oracle.com/javaee/7/tutorial/doc/cdi-basic.htm[+O Tutorial do Java EE 6: Introdução à Injeção de Dependência e Contextos para Java EE+]
* link:http://jcp.org/en/jsr/detail?id=299[+JSR 299: Especificação para Injeção de Dependência e Contextos+]


=== JavaServer Faces 2.0

* link:../web/jsf20-intro.html[+Introdução ao JavaServer Faces 2.x+]
* link:../web/jsf20-crud.html[+Gerando uma Aplicação CRUD JavaServer Faces 2.x Usando um Banco de Dados+]
* link:../../samples/scrum-toys.html[+Scrum Toys: A Aplicação de Amostra Completa do JSF 2.0+]
* link:http://www.oracle.com/technetwork/java/javaee/javaserverfaces-139869.html[+Tecnologia JavaServer Faces+] (homepage Oficial)
* link:http://docs.oracle.com/javaee/7/tutorial/doc/jsf-page.htm[+O Tutorial do Java EE 7: Usando a Tecnologia JavaServer Faces em Páginas Web+]
* link:http://jcp.org/en/jsr/summary?id=314[+JSR 314: Especificação para o JavaServer Faces 2.0+]
