Eu sinto que há uma pequena bagunça na especificação do Java EE 6. Existem vários conjuntos de anotações.
Temos javax.ejb
anotações como @Stateful
e @Stateless
para a criação de EJBs.
Também existe um @javax.annotation.ManagedBean
recurso para criar um bean gerenciado.
Existem anotações em javax.enterprise.context
like @SessionScoped
e @RequestScoped
.
Além do mais, também há anotações @ManagedBean
e @SessionScoped
/ @RequestScoped
no javax.faces.bean
pacote.
E para complicar ainda mais os eventos, existe um pacote javax.inject
com @Named
anotações.
Alguém pode descrever como eles se relacionam um com o outro?
Onde posso usar @EJB
, @Inject
ou @ManagedPropery
para injetar outros grãos?
java
jakarta-ee
java-ee-6
cdi
Piotr Gwiazda
fonte
fonte
Respostas:
Em primeiro lugar, deixe-me fazer alguns esclarecimentos:
Definição de bean gerenciado : geralmente um bean gerenciado é um objeto cujo ciclo de vida (construção, destruição, etc.) é gerenciado por um contêiner.
Em Java ee temos muitos containers que gerenciam o ciclo de vida de seus objetos, como container JSF, container EJB, container CDI, container Servlet, etc.
Todos esses contêineres funcionam de forma independente, eles inicializam na inicialização do servidor de aplicativos e examinam as classes de todos os artefatos, incluindo jar, ejb-jar, war e arquivos ear em tempo de implantação e reúnem e armazenam alguns metadados sobre eles, então quando você precisa de um objeto de uma classe em tempo de execução, eles fornecerão instâncias dessas classes e, após terminar o trabalho, eles as destruirão.
Portanto, podemos dizer que temos:
Portanto, quando você vir a palavra Managed Bean, deve perguntar sobre o contexto ou tipo dela. (JSF, CDI, EJB, etc.)
Então você pode perguntar por que temos muitos desses contêineres: AFAIK, os caras do Java EE queriam ter uma estrutura de injeção de dependência, mas não conseguiram reunir todos os requisitos em uma especificação porque não podiam prever os requisitos futuros e criaram EJB 1.0 e então 2.0 e depois 3.0 e agora 3.1, mas o objetivo do EJB era apenas para alguns requisitos (transação, modelo de componente distribuído, etc).
Ao mesmo tempo (em paralelo), eles perceberam que precisavam oferecer suporte ao JSF também, então eles fizeram beans gerenciados JSF e outro contêiner para os beans JSF e o consideraram um contêiner DI maduro, mas ainda não era um contêiner completo e maduro.
Depois disso, Gavin King e alguns outros caras legais;) fizeram CDI, que é o contêiner de DI mais maduro que já vi. CDI (inspirado em Seam2, Guice e Spring) foi feito para preencher a lacuna entre JSF e EJB e muitas outras coisas úteis como injeção de pojo, métodos de produção, interceptores, decoradores, integração SPI, muito flexível, etc. e pode até fazer o que os beans gerenciados EJB e JSF estão fazendo, então podemos ter apenas um contêiner de DI maduro e poderoso. Mas por alguma compatibilidade com versões anteriores e razões políticas, os caras do Java EE querem mantê-los !!!
Aqui você pode encontrar a diferença e os casos de uso para cada um desses tipos:
JSF Managed Beans, CDI Beans e EJBs
O JSF foi inicialmente desenvolvido com seu próprio bean gerenciado e mecanismo de injeção de dependência que foi aprimorado para JSF 2.0 para incluir beans baseados em anotação. Quando o CDI foi lançado com o Java EE 6, era considerado o framework de bean gerenciado para aquela plataforma e, claro, os EJBs os desatualizaram, já que existem há mais de uma década.
O problema, claro, é saber qual usar e quando usá-los.
Vamos começar com os beans gerenciados JSF mais simples.
JSF Managed Beans
Resumindo, não os use se estiver desenvolvendo para Java EE 6 e usando CDI. Eles fornecem um mecanismo simples para injeção de dependência e definição de beans de apoio para páginas da web, mas são muito menos poderosos do que os beans CDI.
Eles podem ser definidos usando a
@javax.faces.bean.ManagedBean
anotação que leva um parâmetro de nome opcional. Este nome pode ser usado para fazer referência ao bean a partir das páginas JSF.O escopo pode ser aplicado ao bean usando um dos diferentes escopos definidos no
javax.faces.bean
pacote, que incluem a solicitação, sessão, aplicativo, visualização e escopos personalizados.Os beans JSF não podem ser misturados com outros tipos de beans sem algum tipo de codificação manual.
Feijão CDI
CDI é a estrutura de gerenciamento de bean e injeção de dependência que foi lançada como parte do Java EE 6 e inclui um recurso de bean gerenciado completo e abrangente. Os beans CDI são muito mais avançados e flexíveis do que os beans gerenciados JSF simples. Eles podem fazer uso de interceptores, escopo de conversação, eventos, injeção de segurança de tipo, decoradores, estereótipos e métodos produtores.
Para implementar os beans CDI, você deve colocar um arquivo chamado beans.xml em uma pasta META-INF no classpath. Depois de fazer isso, cada bean no pacote se torna um bean CDI. Existem muitos recursos no CDI, muitos para cobrir aqui, mas como uma referência rápida para recursos do tipo JSF, você pode definir o escopo do bean CDI usando um dos escopos definidos no
javax.enterprise.context
pacote (ou seja, solicitação, conversação , sessão e escopos de aplicativo). Se quiser usar o bean CDI de uma página JSF, você pode dar um nome a ele usando ajavax.inject.Named
anotação. Para injetar um bean em outro bean, você anota o campo comjavax.inject.Inject
anotação.A injeção automática como a definida acima pode ser controlada através do uso de qualificadores que podem ajudar a combinar a classe específica que você deseja injetar. Se você tiver vários tipos de pagamento, poderá adicionar um qualificador para saber se é assíncrono ou não. Embora você possa usar a
@Named
anotação como um qualificador, não deveria, pois ela é fornecida para expor os beans em EL.O CDI lida com a injeção de beans com escopos incompatíveis por meio do uso de proxies. Por causa disso, você pode injetar um bean com escopo de solicitação em um bean com escopo de sessão e a referência ainda será válida em cada solicitação porque, para cada solicitação, o proxy se reconecta a uma instância ativa do bean com escopo de solicitação.
O CDI também tem suporte para interceptores, eventos, o novo escopo de conversação e muitos outros recursos que o tornam uma escolha muito melhor em relação aos beans gerenciados JSF.
EJB
Os EJBs são anteriores aos beans CDI e, de alguma forma, são semelhantes aos beans CDI e, de outras maneiras, muito diferentes. Primeiramente, as diferenças entre os beans CDI e EJBs é que os EJBs são:
Os dois tipos de EJBs são chamados de stateless e stateful. EJBs sem estado podem ser considerados como beans de uso único thread-safe que não mantêm nenhum estado entre duas solicitações da web. EJBs com estado mantêm o estado e podem ser criados e permanecer em funcionamento pelo tempo que forem necessários até que sejam descartados.
Definir um EJB é simples, basta adicionar uma anotação
javax.ejb.Stateless
oujavax.ejb.Stateful
à classe.Os beans sem estado devem ter um escopo dependente, enquanto um bean de sessão com estado pode ter qualquer escopo. Por padrão, eles são transacionais, mas você pode usar a anotação de atributo de transação.
Embora os EJBs e os beans CDI sejam muito diferentes em termos de recursos, escrever o código para integrá-los é muito semelhante, já que os beans CDI podem ser injetados em EJBs e os EJBs podem ser injetados em beans CDI. Não há necessidade de fazer qualquer distinção ao injetar um no outro. Novamente, os diferentes escopos são tratados pelo CDI por meio do proxy. Uma exceção a isso é que o CDI não oferece suporte à injeção de EJBs remotos, mas isso pode ser implementado escrevendo um método de produtor simples para ele.
A
javax.inject.Named
anotação, bem como quaisquer qualificadores, podem ser usados em um EJB para combiná-lo com um ponto de injeção.Quando usar qual feijão
Como saber quando usar qual bean? Simples.
Nunca use beans gerenciados JSF, a menos que esteja trabalhando em um contêiner de servlet e não queira tentar fazer o CDI funcionar no Tomcat (embora haja alguns arquétipos Maven para isso, então não há desculpa).
Em geral, você deve usar os beans CDI, a menos que precise da funcionalidade avançada disponível nos EJBs, como funções transacionais. Você pode escrever seu próprio interceptor para tornar os beans CDI transacionais, mas, por enquanto, é mais simples usar um EJB até que o CDI obtenha os beans CDI transacionais que estão logo ali. Se você estiver preso em um contêiner de servlet e estiver usando CDI, as transações escritas à mão ou seu próprio interceptor de transação são a única opção sem EJBs.
Se você precisa usar
@ViewScoped
em CDI, você deve@ViewScoped
funcionará no CDI. MyFaces CODI tem um suporte ainda mais sólido de @ViewScoped@ViewAccessScoped
, é uma extensão escrita em cima do CDI pelo Apache, basta fazer o download e usar@ViewAccessScoped
anotação em vez de@ViewScoped
.@ConversationScoped
e torne-o de longa duração. Veja aqui para mais informações .Algumas peças roubadas daqui .
fonte
@ManagedProperty("#{someBean})"
maneira correta?@Named
e@javax.enterprise.context.RequestScoped
e injeção de uso CDI usando anotação @Inject. não use beans gerenciados jsf se não for necessário;).Sim, isso pode ser confuso.
Por algumas razões históricas ehm , JSF e CDI estão usando as mesmas anotações para escopos, mas de pacotes diferentes.
Como você provavelmente deve estar adivinhando, eles
javax.faces.bean
são da especificação JSF e não estão relacionados ao CDI. Não os use, a menos que tenha um bom motivo para fazê-lo. E nunca, jamais, misture-os com as anotações CDI dejavax.ejb
. Isso produzirá uma lista infinita de bugs e anomalias sutis.Eu geralmente recomendo que você folheie as primeiras (ou até mais) páginas da excelente documentação do Weld . Isso deve colocá-lo no caminho certo para o Java EE 6.
E fique à vontade para postar mais perguntas aqui.
fonte
@javax.annotation.ManagedBean
é inútil, já que o CDI trata todas as classes como beans gerenciados, certo?Como não há respostas específicas sobre
@javax.annotation.ManagedBean
, aqui está um link para a resposta de uma pergunta semelhante: Beans de apoio (@ManagedBean) ou Beans de CDI (@Named)? . A especificação pode ser encontrada em http://download.oracle.com/otndocs/jcp/managed_beans-1.0-fr-eval-oth-JSpec/ . Portanto, parece-me que@javax.annotation.ManagedBean
era para ser uma generalização de@javax.faces.bean.ManagedBean
.Pelo que eu percebi, o JSF Managed Beans está sendo eliminado em favor dos CDI Beans (talvez ficando obsoleto do JSF 2.3?), Então acho que
@javax.annotation.ManagedBean
está se tornando cada vez mais obsoleto agora.fonte
@Named
irá substituir@ManagedBean
no futuro?@Named
beans CDI substituirão o JSF@ManagedBeans
, por exemplo, em stackoverflow.com/questions/4347374/… , BalusC diz "A expectativa é que @ManagedBean e amigos sejam descontinuados de acordo com o Java EE 8. ".