Acabei de começar a ler Core JavaServer Faces, 3ª ed. e eles dizem isso (ênfase minha):
É um acidente histórico que haja dois mecanismos separados, os beans CDI e os beans gerenciados JSF, para os beans que podem ser usados nas páginas JSF. Sugerimos que você use os beans CDI, a menos que seu aplicativo deva funcionar em um executor de servlet simples, como o Tomcat.
Por quê? Eles não fornecem nenhuma justificativa. Tenho usado @ManagedBean
para todos os beans em um aplicativo de protótipo em execução no GlassFish 3 e realmente não notei nenhum problema com isso. Não me importo especialmente em migrar de @ManagedBean
para @Named
, mas quero saber por que deveria me preocupar .
jsf
jakarta-ee
jsf-2
cdi
Matt Ball
fonte
fonte
Respostas:
O CDI é preferível ao JSF simples porque o CDI permite a injeção de dependência em todo o JavaEE. Você também pode injetar POJOs e permitir que sejam gerenciados. Com o JSF, você só pode injetar um subconjunto do que é possível com o CDI.
fonte
@ManagedBean
se quiser injetá-la com JSF?Use CDI.
De acordo com o JSF 2.3,
@ManagedBean
está obsoleto . Consulte também o problema de especificação 1417 . Isto significa que não há mais uma razão para escolher@ManagedBean
mais@Named
. Isso foi implementado pela primeira vez no Mojarra 2.3.0 beta versão m06.História
A principal diferença é que
@ManagedBean
é gerenciado pelo framework JSF e está@ManagedProperty
disponível apenas para outros beans gerenciados JSF.@Named
é gerido pelo servidor de aplicativos (o recipiente) via quadro CDI e é via@Inject
disponível para qualquer tipo de recipiente artefato gerido como@WebListener
,@WebFilter
,@WebServlet
,@Path
,@Stateless
, etc e até mesmo um JSF@ManagedBean
. Do outro lado,@ManagedProperty
se não trabalhar dentro de uma@Named
ou qualquer outro recipiente artefato gerenciado. Funciona realmente apenas por dentro@ManagedBean
.Outra diferença é que o CDI realmente injeta proxies que delegam à instância atual no escopo de destino por solicitação / thread (por exemplo, como os EJBs são injetados). Esse mecanismo permite injetar um bean de escopo mais restrito em um bean de escopo mais amplo, o que não é possível com JSF
@ManagedProperty
. O JSF "injeta" aqui a instância física diretamente chamando um setter (é exatamente por isso que um setter é necessário, embora não seja necessário com@Inject
).Embora não seja uma desvantagem direta - existem outras maneiras - o escopo do
@ManagedBean
é simplesmente limitado. Da outra perspectiva, se você não quiser expor "demais" para@Inject
, também pode apenas manter seus beans gerenciados@ManagedBean
. É comoprotected
versuspublic
. Mas isso realmente não conta.Pelo menos, no JSF 2.0 / 2.1, a principal desvantagem de gerenciar beans de apoio JSF por CDI é que não há equivalente de CDI
@ViewScoped
. O@ConversationScoped
chega perto, mas ainda requer iniciar e parar manualmente e anexar umcid
parâmetro de solicitação feio aos URLs resultantes. MyFaces CODI torna isso mais fácil, conectando JSFsjavax.faces.bean.ViewScoped
a CDI de forma totalmente transparente, de modo que você possa simplesmente fazer@Named @ViewScoped
, no entanto, isso anexa umwindowId
parâmetro de solicitação feio a URLs resultantes, também na navegação simples de página a página. OmniFaces resolve tudo isso com um verdadeiro CDI@ViewScoped
que realmente vincula o escopo do bean ao estado de exibição JSF em vez de a um parâmetro de solicitação arbitrário.JSF 2.2 (que é lançado 3 anos após esta pergunta / resposta) oferece uma nova
@ViewScoped
anotação totalmente compatível com CDI fora da caixa no sabor dejavax.faces.view.ViewScoped
. O JSF 2.2 vem com um CDI apenas@FlowScoped
que não tem um@ManagedBean
equivalente, empurrando os usuários do JSF para o CDI. A expectativa é que@ManagedBean
e amigos sejam descontinuados de acordo com o Java EE 8. Se você ainda estiver usando@ManagedBean
, é altamente recomendável mudar para o CDI para estar preparado para caminhos de atualização futuros. O CDI está disponível em containers compatíveis com o Java EE Web Profile, como WildFly, TomEE e GlassFish. Para o Tomcat, você deve instalá-lo separadamente, exatamente como já fez para o JSF. Veja também Como instalar o CDI no Tomcat?fonte
beans.xml
, converti@ManagedBean
beans de apoio em@Named
e converti@ManagedProperty
em@Inject
. Tudo está bem com o mundo. No entanto, se eu alterar minhas@EJB
anotações para@Inject
, a implantação falhará (org.jboss.weld.exceptions.DeploymentException
) com mensagemWELD-001408 Injection point has unsatisfied dependencies
. Devo realmente usar@Inject
para injetar EJBs sem interface em um@Named
bean, ou devo continuar@EJB
? Os EJBs são empacotados em um EJB JAR, no mesmo EAR que o WAR que contém meus beans CDI.@Named
.@Named @ViewScoped
, no entanto, que anexa um parâmetro de solicitação windowId feio aos URLs resultantes, também na navegação página a página simples." Observe que com DeltaSpike isso não é mais verdadeiro. Você pode desativar os parâmetros de URL dsId e windowId, se não precisar do Window Scope.@ViewScoped
para JSF 2.0 / 2.1: showcase.omnifaces.org/cdi/ViewScopedCom Java EE 6 e CDI você tem opções diferentes para Managed Beans
@javax.faces.bean.ManagedBean
refere-se a JSR 314 e foi introduzido com JSF 2.0. O objetivo principal era evitar a configuração no arquivo faces-config.xml para usar o bean dentro de uma página JSF.@javax.annotation.ManagedBean(“myBean”)
é definido por JSR 316. Ele generaliza os beans gerenciados JSF para uso em outro lugar em Java EE@javax.inject.Named(“myBean”)
são quase iguais ao anterior, exceto que você precisa de um arquivo beans.xml na pasta web / WEB-INF para ativar o CDI.fonte
beans.xml
arquivo? Isso ainda é verdade hoje?Eu estava usando CDI no GlassFish 3.0.1, mas para fazê-lo funcionar, tive que importar o framework Seam 3 (Weld). Isso funcionou muito bem.
No GlassFish 3.1 CDI parou de funcionar, e o Seam Weld parou de funcionar com ele. Eu abri um bug sobre isso, mas não vi corrigido ainda. Tive que converter todo o meu código para usar as anotações javax.faces. *, Mas pretendo voltar ao CDI assim que ele começar a funcionar.
Concordo que você deve usar CDI, mas um problema que ainda não vi resolvido é o que fazer com a anotação @ViewScoped. Eu tenho muito código que depende disso. Não está claro se @ViewScoped funciona se você não estiver usando @ManagedBean com ele. Se alguém puder esclarecer isso eu agradeceria.
fonte
Um bom motivo para mudar para CDI: você poderia ter um recurso com escopo de sessão comum (perfil de usuário, por exemplo)
@Inject
instalado em beans gerenciados JSF e serviços REST (ou seja, Jersey / JAX-RS).Por outro lado,
@ViewScoped
é um motivo convincente para manter o JSF@ManagedBean
- especialmente para qualquer coisa com AJAX significativo. Não existe um substituto padrão para isso no CDI.Parece que ele pode ter algum suporte para uma
@ViewScoped
anotação semelhante a um para beans CDI, mas não brinquei com ele pessoalmente.http://seamframework.org/Seam3/FacesModule
fonte