O @Resource pode ser usado para injetar primitivas no EJB3.0?

Usando Glassfish, eu posso configurar uma input jndi string:

 Nome da JNDI: "com / xyzcompany / echo / EchoServiceBean / viewName"
 Classe de Fábrica: org.glassfish.resources.custom.factory.PrimitivesAndStringFactory
 Propriedades: value = "Teste123"

Eu posso então injetar essa string configurada em container no meu EJB:

     @Resource (pesquisa = "com / xyzcompany / echo / EchoServiceBean / viewName")
     String viewName;

A pesquisa = aparece internamente para fazer um InitialContext.lookup (…). No entanto, isso usa ejb3.1, mas infelizmente meu ambiente prod é apenas ejb3.0.

Eu acho que estou tentando descobrir se há uma maneira de usar @Resource (name =) ou @Resource (mappedName =) para fazer algo semelhante? name = parece ser específico do aplicativo, então eu deveria ser capaz de mapear um nome relativo para um nome JNDI global, mas não consigo descobrir qual anotação faz o mapeamento.

Obrigado!

Todos os 8 wrappers primitivos e String são compatíveis com os tipos @Resource e estão disponíveis para pesquisa ou injeção por meio de sua declaração no arquivo padrão ejb-jar.xml.

Declarando o valor do nome (e tipo) pares

Isso é feito com o elemento xml no descritor de implantação.

No EJB 3.0, você precisa fazer isso para cada bean que deseja referenciar os mesmos pares nome / valor. Isso ocorre porque o EJB foi originalmente projetado de forma diferente dos Servlets e cada EJB literalmente obtém seu próprio namespace JNDI privado, java:comp/env , enquanto todos os Servlets no mesmo módulo compartilham o mesmo java:comp/env .

    MySessionBean  myBoolean java.lang.Boolean true   myString java.lang.String hello world   myDouble java.lang.Double 1.1   myLong java.lang.Long 12345678   myFloat java.lang.Float 1.3   myInteger java.lang.Integer 1024   myShort java.lang.Short 42   myByte java.lang.Byte 128   myCharacter java.lang.Character D     

Para os leitores que tiveram a sorte de usar o EJB 3.1, você pode usar o JNDI global e declará-los no application.xml e procurá-los de qualquer lugar via java:app/myString . Um recurso que a maioria dos fornecedores tem há anos, que agora é padrão no Java EE 6. A injeção dessas inputs também é possível via @Resource(lookup="java:app/myString")

Outra novidade no Java EE 6 é o suporte para dois tipos de env-entry-type , java.lang.Class e qualquer enum. Por exemplo:

  myPreferredListImpl java.lang.Class java.util.ArrayList   myBillingStragety java.lang.Class org.superbiz.BiMonthly   displayElapsedTimeAs java.util.concurrent.TimeUnit MINUTES   myFavoriteColor org.superbiz.ColorEnum ORANGE  

Referenciando-os com injeção

Qualquer um dos @Resource acima pode ser injetado via @Resource . Apenas não esqueça de preencher o atributo name para corresponder ao

 @Stateless public class MySessionBean implements MySessionLocal { @Resource(name="myString") private String striing; @Resource(name = "myDouble") private Double doouble; @Resource(name = "myLong") private Long loong; @Resource(name = "myName") private Float flooat; @Resource(name = "myInteger") private Integer inteeger; @Resource(name = "myShort") private Short shoort; @Resource(name = "myBoolean") private Boolean booolean; @Resource(name = "myByte") private Byte byyte; @Resource(name = "myCharacter") private Character chaaracter; } 

Referenciando-os com JNDI

Esses nomes também podem ser visualizados de maneira padrão por meio do javax.naming.InitialContext no namespace java:comp/env privado e portátil do EJBs.

 @Stateless public class MySessionBean implements MySessionLocal { @PostConstruct private void init() { try { final InitialContext initialContext = new InitialContext();// must use the no-arg constructor final String myString = (String) initialContext.lookup("java:comp/env/myString"); final Boolean myBoolean = (Boolean) initialContext.lookup("java:comp/env/myBoolean"); final Double myDouble = (Double) initialContext.lookup("java:comp/env/myDouble"); final Long myLong = (Long) initialContext.lookup("java:comp/env/myLong"); final Float myFloat = (Float) initialContext.lookup("java:comp/env/myFloat"); final Integer myInteger = (Integer) initialContext.lookup("java:comp/env/myInteger"); final Short myShort = (Short) initialContext.lookup("java:comp/env/myShort"); final Byte myByte = (Byte) initialContext.lookup("java:comp/env/myByte"); final Character myCharacter = (Character) initialContext.lookup("java:comp/env/myCharacter"); } catch (NamingException e) { throw new EJBException(e); } } } 

Referenciando-os com o SessionContext

No EJB 3.0 como parte do esforço de simplificação, adicionamos a capacidade de usar o javax.ejb.SessionContext para fazer pesquisas. É essencialmente o mesmo, mas tem um pouco de açúcar nele.

  • o prefixo java:comp/env não é requerido
  • não lança uma exceção verificada (em vez disso, lançará EJBException para nomes ausentes)

Os padrões de Service Locator foram todos os burburinhos em 2003, então decidimos criar um pouco de conveniência na API EJB.

 @Stateless public class MySessionBean implements MySessionLocal { @Resource private SessionContext sessionContext; @PostConstruct private void init() { final String myString = (String) sessionContext.lookup("myString"); final Boolean myBoolean = (Boolean) sessionContext.lookup("myBoolean"); final Double myDouble = (Double) sessionContext.lookup("myDouble"); final Long myLong = (Long) sessionContext.lookup("myLong"); final Float myFloat = (Float) sessionContext.lookup("myFloat"); final Integer myInteger = (Integer) sessionContext.lookup("myInteger"); final Short myShort = (Short) sessionContext.lookup("myShort"); final Byte myByte = (Byte) sessionContext.lookup("myByte"); final Character myCharacter = (Character) sessionContext.lookup("myCharacter"); } } 

Nota lateral sobre o mal estar de IntialContext

Além disso, com o meu chapéu de fornecedor, posso dizer-lhe que há um pouco de encanamento lento que pode ser evitado sob o capô com a pesquisa SessionContext .

Quando você faz ‘java:’ pesquisas em um InitialContext , a chamada vai para a VM, através de um monte de aros para encontrar quem pode resolver esse nome e, eventualmente, para o fornecedor que terá que pesquisar estado do segmento para descobrir quem perguntou e qual namespace eles deveriam obter. Ele faz isso em todas as chamadas, independentemente das propriedades que você passa para o InitialContext e do contexto que o fornecedor inicializou em sua construção. O ‘java:’ simplesmente salta sobre tudo isso. É uma parte bastante frustrante de ser um fornecedor. É também por isso que a nova API javax.ejb.embedded.EJBContainer não usa InitialContext lugar nenhum e apenas faz referência a javax.naming.Context que é uma interface real em vez de uma class “fábrica” ​​concreta com encanamento intenso e obtuso.

Fazer a chamada no SessionContext deve ser muito mais rápido se o fornecedor fizer certo. Pelo menos no OpenEJB, todos os itens acima, incluindo o ThreadLocal, são ignorados e a chamada vai para o namespace JNDI do bean, que já está conectado ao SessionContext .

Outra maneira de evitar a sobrecarga do InitialContext é simplesmente pesquisar java:comp/env uma vez no @PostConstruct e manter o object Context resultante e usá-lo apenas. Então não prefixar lookups com java:comp/env/ e apenas procurar os nomes diretamente como myString e myInteger . Será mais rápido, garantido.