Usar CDI ou @ManagedBean pra Controllers JSF?

Olá pessoal, atualmente estou começando a suar e me familiarizar com o uso do CDI em meus projetos, mas etsou tendo um sério problema com a nova perspectiva na construção de minhas páginas. Por exemplo quando uso meus Controllers com @Named, soforo com problemas como usar tags como <f:setPropertyActionListener /> ou <h:selectOneMenu />. Minha principal dificuldade é não ter o contexto de visão(@ViewScoped), pesquisei e vi que tem maneiras de suprir esta carência com pacotes ou atravaés da criação deste contexto através de classes.
Pelo que percebi, o uso de Injeção de Dependências e Contexto com o JSF não supre todas as facilidades do uso dos Contextos que o próprio JSF oferece. O que senti é que quando se usa CDI(@Named e os contextos do javax.enterprise) você tem que criar muitas “gambiarras” para usar coisas que você usa intuitivamente com as ferramentas do JSF(@ManagedBean e contextos do javax.faces). Quais as suas opiniões a respeito. Como vocês lidam com isto e qual suas justificativas entre usar um e outro.(Eu confesso que stou dividido por que de um lado, com CDI, estou seguindo as especificaçoes, mas por outro ganho mais agilidade com o uso das ferramentas da API do JSF) .

Agradeço pela atenção.

Eu li no livro de JSF que CDI era melhor mas ele não listou pq. O.o

Eu até então estou vendo ManagedBean melhor do que CDI viu.

Menos dor de Cabeça e melhor Flexibilidade. [=

[quote=jakefrog]

Eu até então estou vendo ManagedBean melhor do que CDI viu.

Menos dor de Cabeça e melhor Flexibilidade. [=[/quote]

Concordo com você jake, porém fico na dúvida se vale a pena se distanciar da especificação e ficar preso ao JSF.

Não entendi sua pergunta sobre ‘listar’.

Listar de listar uai.

Motivos do CDI ser melhor que o MB:
a)
b)
c)

Vc vai estar ficando preso ao JSF de qualquer modo uai. Você vai usar as bibliotecas do JSF de qualquer modo.

A única diferença é que vc terá que utilizar ManagedBean ao invés de Named.

Não sei se vai te ajudar muito, mas para CDI existe o @ConversationScoped. O ruim dele é que você tem que sempre abrir e fechar na unha suas ações. [=

Bem, eu não sei te listar essas vantagens e na verdade minha dúvida era justamente esta, qual a vantagem de usar o @Named e os contextos do CDI. Você assim como eu, defende mais o uso do JSF e entendo que de qualquer forma vamos estra preso ao JSF de qualquer forma, mas ainda assim, gostaria de uma visão do outro lado, dos que defendem o uso do CDIe por quem o defende.

Quanto ao conversation, já li a respeito e achei muito chato de se usar(esta era umadas coisas quando me referi a gambiarras, por mias que não seja uma gambiarra tão feia quanto muitas que existem por ai, mas convenhamos, não é nada prático de se usar).

Pelo que vi todos meus problemas se resolveriam se o @Named trabalhasse com o @ViewScoped do JSF, Até encontrei uma forma(leia-se gambiarra) de resolver isso, masacredito que não avle a pena ter tanto trabalho quando simplesmente trocar uma anotação(@Named para @MangedBean) me pouparia muita e código escrito dor de cabeça. Decidi continuar usar o @MangedBean or enquanto , pois vi que coisinhas tolas como um simples combobox param de funcionar se eu não usar o contexto de Visão. Que dá pra usar controladores com Injeçãoo, percebi que é perfeitamente possívell, mas a coisa desanda muito quando se usa renderização de compontentes com AJAX, componentes do Primefaces. Pra mim que tenho a prática d efzer viões com dialogs e dataTables, ficou inviável utilizar CDI, mas para telas mais simples é uma maona roda. Agora, acho ruim perder parte da usabilidade de um framework como o JSF só para usar CDI, que como falei, ainda não vi nenhuma vantagem sobre o uso da PAI do JSF.
Mas o tópico continua aberto e gostaria, e muito, de ter a opnião de quem defenda o uso do CDIem Controladores por que sei que posso estar equivocado quanto ao uso desta ferramenta.

a maior vantagem que vi ao utilizar cdi é poder Injetar as interfaces dos serviços nos beans ao inves das implementações, porém isso custou a @viewscoped do jsf que não faz parte do cdi

o problema pode ser resolvido com o conversationscoped ou sessionscoped do ejb, mas tudo depende do tamanho da aplicação e do contexto que será aplicado.

uai, mas no JSF 2.1 já dá para injetar um @EJB dentro de um @ManagedBean.

Qual tipo de injeção vc está falando?

Ao invés de voce precisar instanciar um serviço para utiliza-lo como abaixo:

UsuarioServiceImpl us = new UsuarioServiceImpl();

voce pode injeta-lo e passar a tarefa para o servidor de aplicações, e o mais importante, você injeta a interface, se tiver alteração na implementação, não vai fazer diferença para o bean

@Inject
UsuarioService us;

[quote=fabiozanardi]Ao invés de voce precisar instanciar um serviço para utiliza-lo como abaixo:

UsuarioServiceImpl us = new UsuarioServiceImpl();

voce pode injeta-lo e passar a tarefa para o servidor de aplicações, e o mais importante, você injeta a interface, se tiver alteração na implementação, não vai fazer diferença para o bean

@Inject
UsuarioService us;

[/quote] Saquei. Valeu. [=

Sou nova no mundo java, alguém por favor pode me ajudar?
Estou com a seguinte situação:
instalei o java jdk1.6.0_31
apache-tomcat-6.0.35
eclipse indigo

possuo os seguintes arquivos na libraries:
commons-logging-1.1.1.jar
commons-collections-3.2.1.jar
commons-digester3-3.2.jar
commons-beanutils-1.8.3.jar
jstl-impl-1.2.jar
jstl-api-1.2.jar
jsf-api.jar
jsf-impl.jar

o arquivo web.xml:
<?xml version=“1.0” encoding=“UTF-8”?>
<web-app xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance” xmlns=“http://java.sun.com/xml/ns/javaee” xmlns:web=“http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd” xsi:schemaLocation=“http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd” id=“WebApp_ID” version=“2.5”>
<display-name>FinanceiroWeb</display-name>

<servlet>
<display-name>Faces Servlet</display-name>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.jsf</url-pattern>
</servlet-mapping>

<context-param>
<param-name>javax.faces.PROJECT_STAGE</param-name>
<param-value>Development</param-value>
</context-param>

<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>

</welcome-file-list>
</web-app>

Usuario.xhtml
<?xml version=“1.0” encoding=“ISO-8859-1” ?>
<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>
<html xmlns=“http://www.w3.org/1999/xhtml
xmlns:h=“http://java.sun.com/jsf/html
xmlns:f=“http://java.sun.com/jsf/core”>
<h:head>
<meta http-equiv=“Content-Type” content=“text/html; charset=ISO-8859-1” />
<title>Cadastro de Usuários</title>
</h:head>
<h:body>
<h1>Cadastro de Usuários</h1>
<hr />
<h:form>
<h:messages />
<h:panelGrid columns=“2”>
<h:outputLabel value=“Nome:” for=“nome”/>
<h:inputText id=“nome” label=“Nome” value="#{usuarioBean.nome}" required=“true”/>
<h:outputLabel value=“e-Mail:“for=“email”/>
<h:inputText id=“email” label=“e-Mail” value=”#{usuarioBean.email}”/>
<h:outputLabel value=“Senha”: for=“senha”/>
<h:inputSecret id=“senha” label=“Senha” value="#{usuarioBean.senha}" required=“true”/>
<h:outputLabel value=“Confirmar Senha:” for=“confirmarsenha”/>
<h:inputSecret id=“confirmarsenha” label=“Confirmar Senha” value="#{usuarioBean.confirmaSenha}"
required=“true”/>
<h:outputText/>
<h:commandButton action="#{usuarioBean.salvar}" value=“Salvar”/>
</h:panelGrid>
</h:form>
<hr/>
</h:body>
</html>

faces-config-xml
<?xml version=“1.0” encoding=“ISO-8859-1” ?>
<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>
<html xmlns=“http://www.w3.org/1999/xhtml
xmlns:h=“http://java.sun.com/jsf/html
xmlns:f=“http://java.sun.com/jsf/core”>
<h:head>
<meta http-equiv=“Content-Type” content=“text/html; charset=ISO-8859-1” />
<title>Cadastro de Usuários</title>
</h:head>
<h:body>
<h1>Cadastro de Usuários</h1>
<hr />
<h:form>
<h:messages />
<h:panelGrid columns=“2”>
<h:outputLabel value=“Nome:” for=“nome”/>
<h:inputText id=“nome” label=“Nome” value="#{usuarioBean.nome}" required=“true”/>
<h:outputLabel value=“e-Mail:“for=“email”/>
<h:inputText id=“email” label=“e-Mail” value=”#{usuarioBean.email}”/>
<h:outputLabel value=“Senha”: for=“senha”/>
<h:inputSecret id=“senha” label=“Senha” value="#{usuarioBean.senha}" required=“true”/>
<h:outputLabel value=“Confirmar Senha:” for=“confirmarsenha”/>
<h:inputSecret id=“confirmarsenha” label=“Confirmar Senha” value="#{usuarioBean.confirmaSenha}"
required=“true”/>
<h:outputText/>
<h:commandButton action="#{usuarioBean.salvar}" value=“Salvar”/>
</h:panelGrid>
</h:form>
<hr/>
</h:body>
</html>

Classe

package financeiro.web;
import java.util.Map;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.RequestScoped;
import javax.faces.context.FacesContext;
@ManagedBean(name=“usuarioBean”)
@RequestScoped

public class UsuarioBean {
private String nome;
private String email;
private String senha;
private String confirmaSenha;
@ManagedProperty(value="#{param}")
private Map<String, String> parametros;

public String novo(){  
    return "usuario";  
}  
  
public String salvar(){  
    FacesContext context = FacesContext.getCurrentInstance();  
    if (!this.senha.equalsIgnoreCase(this.confirmaSenha)) {  
        context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR,  
                "Senha confirmada incorretamente",""));  
    return "usuario";  
    }  
    //Salva o usuario  
    return "sucesso";  
}  


public Map&lt;String, String&gt; getParametros() {
	return parametros;
}
public void setParametros(Map&lt;String, String&gt; parametros) {
	this.parametros = parametros;
}
public String getNome() {
	return nome;
}
public void setNome(String nome) {
	this.nome = nome;
}
public String getEmail() {
	return email;
}
public void setEmail(String email) {
	this.email = email;
}
public String getSenha() {
	return senha;
}
public void setSenha(String senha) {
	this.senha = senha;
}
public String getConfirmaSenha() {
	return confirmaSenha;
}
public void setConfirmaSenha(String confirmaSenha) {
	this.confirmaSenha = confirmaSenha;
}

}

No entanto quando rodo:
http://localhost:8086/FinanceiroWeb/usuario.jsf
aparece a seguinte msg:
An Error Occurred:
null source
± Stack Trace
java.lang.IllegalArgumentException: null source
at java.util.EventObject.<init>(Unknown Source)
at javax.faces.event.SystemEvent.<init>(SystemEvent.java:67)
at javax.faces.event.ComponentSystemEvent.<init>(ComponentSystemEvent.java:69)
at javax.faces.event.PostRestoreStateEvent.<init>(PostRestoreStateEvent.java:69)
at com.sun.faces.lifecycle.RestoreViewPhase.deliverPostRestoreStateEvent(RestoreViewPhase.java:256)
at com.sun.faces.lifecycle.RestoreViewPhase.execute(RestoreViewPhase.java:245)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:97)
at com.sun.faces.lifecycle.RestoreViewPhase.doPhase(RestoreViewPhase.java:107)
at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:114)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:308)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:859)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:602)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
at java.lang.Thread.run(Unknown Source)

± Component Tree
± Scoped Variables

POR FAVOR ALGUÉM ME AJUDE!

Desde já, agradeço
Clelia

[quote=jakefrog]Listar de listar uai.

Motivos do CDI ser melhor que o MB:
a)
b)
c)

Vc vai estar ficando preso ao JSF de qualquer modo uai. Você vai usar as bibliotecas do JSF de qualquer modo.

A única diferença é que vc terá que utilizar ManagedBean ao invés de Named.

Não sei se vai te ajudar muito, mas para CDI existe o @ConversationScoped. O ruim dele é que você tem que sempre abrir e fechar na unha suas ações. [=[/quote]

Eu acredito que uma das vantagens que poderia se encaixar nessa lista, eh essa aqui. Apenas uma modesta opinião!

[]'s

[quote=getAdicted]Eu acredito que uma das vantagens que poderia se encaixar nessa lista, eh essa aqui. Apenas uma modesta opinião!

[]'s
[/quote]
Cara, estamos todos aqui para aprender. [=

O que eu não gostei, é que a mesma classe está fazendo 300 coisas ao mesmo tempo. Olha a declaração:

@Stateful @Named public class PersonCRUD
Eu sei que em um ManagedBean você pode injetar o @EJB numa boa.

Qual a vantagem de se ter um MB como EJB? Acho que você está aclopando d+, diminuindo a coesão da classe.

Bem, mas aí eh questão de gosto né? Não se discute.

Valeu pelo link.

Oq eu não sabia era do @Inject. [=

[quote=jakefrog][quote=getAdicted]Eu acredito que uma das vantagens que poderia se encaixar nessa lista, eh essa aqui. Apenas uma modesta opinião!

[]'s
[/quote]
Cara, estamos todos aqui para aprender. [=

O que eu não gostei, é que a mesma classe está fazendo 300 coisas ao mesmo tempo. Olha a declaração:

@Stateful @Named public class PersonCRUD
Eu sei que em um ManagedBean você pode injetar o @EJB numa boa.

Qual a vantagem de se ter um MB como EJB? Acho que você está aclopando d+, diminuindo a coesão da classe.

Bem, mas aí eh questão de gosto né? Não se discute.

Valeu pelo link.

Oq eu não sabia era do @Inject. [=[/quote]

Opa,

Sem duvida eu estou aprendendo mais. =)

Eu não me atentei ao ponto do acoplamento, voce tem razão. Eu passei esse exemplo mais para o pessoal notar o ponto de vista do rapaz quando ele fala sobre diminuir a quantidade de abstrações.

Abração!!!

Achei bem interessante esta afirmação do Rafael no outro tópico.

[quote]Particularmente, quando estou usando JEE6 com CDI em projetos puramente WEB eu prefiro usar meus EJBs (Controllers) como ManagedBeans ao invés de usar dois objetos p/ essa taréfa, lembre-se q o padrão MVC descreve uma arquitetura em 3 camadas e ñ em 4 como é muito comum em aplicativos JEE5 (ou 5 se vc usar DAOs). De fato, os até mesmo os populares DAOs são hoje um pouco redundantes posto q o EntityManager do JPA oferece tds as funcionalidades de um DAOs genérico já pronto p/ vc, escrever DAOs é como reinventar a roda. É claro q p/ q isso funcione na prática vc precisa lançar mão das @NamedQueries através das quais vc pode separar a lógica de acesso ao banco do resto da lógica da aplicação.
[/quote]

Eu tinha uma perspectiva de usar bastante o GenericDAO, porém isto abriu mais minha mente e como já vi ele citando, abstrair o que já é abstraído.

[quote=renatosousafilho]Achei bem interessante esta afirmação do Rafael no outro tópico.

[quote]Particularmente, quando estou usando JEE6 com CDI em projetos puramente WEB eu prefiro usar meus EJBs (Controllers) como ManagedBeans ao invés de usar dois objetos p/ essa taréfa, lembre-se q o padrão MVC descreve uma arquitetura em 3 camadas e ñ em 4 como é muito comum em aplicativos JEE5 (ou 5 se vc usar DAOs). De fato, os até mesmo os populares DAOs são hoje um pouco redundantes posto q o EntityManager do JPA oferece tds as funcionalidades de um DAOs genérico já pronto p/ vc, escrever DAOs é como reinventar a roda. É claro q p/ q isso funcione na prática vc precisa lançar mão das @NamedQueries através das quais vc pode separar a lógica de acesso ao banco do resto da lógica da aplicação.
[/quote]

Eu tinha uma perspectiva de usar bastante o GenericDAO, porém isto abriu mais minha mente e como já vi ele citando, abstrair o que já é abstraído.[/quote]
O meu medo dessa abordagem é caso você precise retirar o EntityManager e trocar por exemplo pelo session o Hibernate você teria que alterar todas classes.

Caso você abstraísse isso, você alteraria apenas no DAO e pronto.

Eu já li no livro Design Patterns que é sempre bom você isolar bibliotecas de terceiros. [=

Tentem usar o JBoss Seam 3, você pode usar tranquilamente anotação do CDI com JSF. (inclusive EJB tbm)
Esses problemas de integração já foram resolvidos lá, só baixar o módulo Seam Faces, que já vem com o módulo Solder dentro.