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.
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
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; }
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); } } }
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.
java:comp/env
não é requerido 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"); } }
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.