@Resource可以用于在EJB3.0中注入基元吗? [英] Can @Resource be used to inject primitives in EJB3.0?

查看:86
本文介绍了@Resource可以用于在EJB3.0中注入基元吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用Glassfish,我可以设置一个字符串jndi条目:

 
JNDI名称:com / xyzcompany / echo / EchoServiceBean / viewName
工厂类:org.glassfish.resources.custom.factory.PrimitivesAndStringFactory
属性:value =Testing123

然后我可以将这个容器配置的字符串注入到我的EJB中:

@Resource(lookup =com / xyzcompany / echo / EchoServiceBean / viewName )
字符串viewName;

lookup =似乎在内部执行InitialContext.lookup(...)。然而,这使用ejb3.1,但不幸的是我的prod环境只有ejb3.0。



我想我想知道有没有办法使用@资源(名称=)或@Resource(mappedName =)做类似的事情? name =似乎是特定于应用程序的,所以我应该能够以某种方式将相对名称映射到全局JNDI名称,但我无法弄清楚映射的注释是什么。



谢谢!

解决方案

所有8个原始包装和字符串都支持@Resource类型,可用于查找或注入声明它们在标准的ejb-jar.xml文件中。



声明名称值(和类型)对



这是通过部署描述符中的< env-entry> xml元素完成的。

为希望引用相同名称/值对的每个bean执行此操作。这是因为EJB最初设计的不同于Servlet,每个EJB字面上都有自己的私有JNDI命名空间 java:comp / env ,而同一模块中的所有Servlet共享相同的 java:comp / env
$ b

  < EJB-JAR> 
< enterprise-beans>
< session>
< ejb-name> MySessionBean< / ejb-name>
< env-entry>
< env-entry-name> myBoolean< / env-entry-name>
< env-entry-type> java.lang.Boolean< / env-entry-type>
< env-entry-value> true< / env-entry-value>
< / env-entry>
< env-entry>
< env-entry-name> myString< / env-entry-name>
< env-entry-type> java.lang.String< / env-entry-type>
< env-entry-value> hello world< / env-entry-value>
< / env-entry>
< env-entry>
< env-entry-name> myDouble< / env-entry-name>
< env-entry-type> java.lang.Double< / env-entry-type>
< env-entry-value> 1.1< / env-entry-value>
< / env-entry>
< env-entry>
< env-entry-name> myLong< / env-entry-name>
< env-entry-type> java.lang.Long< / env-entry-type>
< env-entry-value> 12345678< / env-entry-value>
< / env-entry>
< env-entry>
< env-entry-name> myFloat< / env-entry-name>
< env-entry-type> java.lang.Float< / env-entry-type>
< env-entry-value> 1.3< / env-entry-value>
< / env-entry>
< env-entry>
< env-entry-name> myInteger< / env-entry-name>
< env-entry-type> java.lang.Integer< / env-entry-type>
< env-entry-value> 1024< / env-entry-value>
< / env-entry>
< env-entry>
< env-entry-name> myShort< / env-entry-name>
< env-entry-type> java.lang.Short< / env-entry-type>
< env-entry-value> 42< / env-entry-value>
< / env-entry>
< env-entry>
< env-entry-name> myByte< / env-entry-name>
< env-entry-type> java.lang.Byte< / env-entry-type>
< env-entry-value> 128< / env-entry-value>
< / env-entry>
< env-entry>
< env-entry-name> myCharacter< / env-entry-name>
< env-entry-type> java.lang.Character< / env-entry-type>
< env-entry-value> D< / env-entry-value>
< / env-entry>
< / session>
< / enterprise-beans>
< / ejb-jar>

对于有幸使用EJB 3.1的读者,您可以使用全局JNDI并在应用程序中声明它们.xml并通过 java:app / myString 从任何地方查找它们。大多数供应商多年来一直使用的功能现在已经成为Java EE 6标准的标准功能。通过 @Resource(lookup =java:app / myString)

另外Java EE 6中的新功能还支持两个额外的 env-entry-type 类型,java .lang.Class和任何枚举。例如:

< env-entry>
< env-entry-name> myPreferredListImpl< / env-entry-name>
< env-entry-type> java.lang.Class< / env-entry-type>
< env-entry-value> java.util.ArrayList< / env-entry-value>
< / env-entry>
< env-entry>
< env-entry-name> myBillingStragety< / env-entry-name>
< env-entry-type> java.lang.Class< / env-entry-type>
< env-entry-value> org.superbiz.BiMonthly< / env-entry-value>
< / env-entry>
< env-entry>
< env-entry-name> displayElapsedTimeAs< / env-entry-name>
< env-entry-type> java.util.concurrent.TimeUnit< / env-entry-type>
< env-entry-value> MINUTES< / env-entry-value>
< / env-entry>
< env-entry>
< env-entry-name> myFavoriteColor< / env-entry-name>
< env-entry-type> org.superbiz.ColorEnum< / env-entry-type>
< env-entry-value> ORANGE< / env-entry-value>
< / env-entry>



用注射引用它们



上面可以通过 @Resource 注入。请不要忘记填写 name 属性以匹配< env-entry-name>

  @Stateless 
公共类MySessionBean实现MySessionLocal {

@Resource(name =myString )
私人字符串条纹;

@Resource(name =myDouble)
private Double double;

@Resource(name =myLong)
private Long loong;

@Resource(name =myName)
private Float flooat;

@Resource(name =myInteger)
private Integer;

@Resource(name =myShort)
private short shoort;

@Resource(name =myBoolean)
private布尔booolean;

@Resource(name =myByte)
private Byte byyte;

@Resource(name =myCharacter)
私人字符字符;




引用它们与JNDI



这些名称也可以通过EJBs private和portable java:comp / env 命名空间中的javax.naming.InitialContext进行标准查找。 p>

  @Stateless 
公共类MySessionBean实现MySessionLocal {

@PostConstruct
private void init(){

try {
final InitialContext initialContext = new InitialContext(); //必须使用无参数构造函数

final String myString =(String )initialContext.lookup(java:comp / env / myString);
final布尔值myBoolean =(布尔型)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字符myCharacter =(字符)initialContext.lookup(java:comp / env / myCharacter);
} catch(NamingException e){
抛出新的EJBException(e);




$ b $ h $引用它们与SessionContext

在EJB 3.0中,作为简化工作的一部分,我们添加了使用 javax.ejb.SessionContext 执行的功能查找。它基本上是一样的,但有一点糖。




  • java:comp / env


  • 不会抛出检查异常b
    $ b

    服务定位符模式在2003年是所有的嗡嗡声,所以我们决定为EJB API创建一些便利。

      @Stateless 
    public class MySessionBean实现MySessionLocal {

    @Resource
    private SessionContext sessionContext;

    @PostConstruct
    private void init(){

    final String myString =(String)sessionContext.lookup(myString);
    final布尔值myBoolean =(布尔值)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字符myCharacter =(Character)sessionContext.lookup(myCharacter);




    IntialContext恶意附注



    此外,在我的供应商面前,我可以告诉你,在 SessionContext lookup。

    当你在 InitialContext 上进行'java:'查找时,调用进入虚拟机,通过一堆箍来找出谁可以解决这个名字,然后最终到供应商谁将不得不从线程查询状态找出谁问,他们应该得到什么名称空间。它在每次调用时都会执行此操作,而不管您传递给InitialContext的属性以及供应商在其构建中初始化的上下文是什么。 'java:'简单地跳过了这一切。成为供应商是一件相当令人沮丧的事情。这也是为什么新的 javax.ejb.embedded.EJBContainer API没有在任何地方使用 InitialContext 并且只是引用 javax.naming.Context 这是一个实际的界面,而不是具有强烈而笨拙的管道的具体工厂类。

    如果供应商做对了,那么在SessionContext上进行调用应该快得多。至少在OpenEJB中,包括ThreadLocal在内的所有内容都会被跳过,并且调用会直接进入已经附加到 SessionContext 的bean的JNDI名称空间。



    避免 InitialContext 开销的另一种方法是简单地查找 java:comp / env 一次在@PostConstruct中,并保留结果 Context 对象,并只使用它。然后,不要在 java:comp / env / 前加上查找,直接查找名称,如 myString myInteger 。它会更快,保证。


    Using Glassfish, I can setup a string jndi entry:

    JNDI name: "com/xyzcompany/echo/EchoServiceBean/viewName"
    Factory Class: org.glassfish.resources.custom.factory.PrimitivesAndStringFactory
    Properties: value="Testing123"
    

    I can then inject this container configured string into my EJB:

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

    The lookup= appears to internally do an InitialContext.lookup(...). However, this uses ejb3.1, but unfortunately my prod environment is only ejb3.0.

    I guess i'm trying to figure out is there a way to use @Resource(name=) or @Resource(mappedName=) to do something similar? name= appears to be application specific, so I should be able to somehow map a relative name to a global JNDI name, but I can't figure out what annotation does the mapping.

    Thanks!

    解决方案

    All 8 primitive wrappers and String are supported @Resource types and are available for lookup or injection via declaring them in the standard ejb-jar.xml file.

    Declaring the name value (and type) pairs

    This is done with the <env-entry> xml element in deployment descriptor.

    In EJB 3.0 you have to do this for each bean that wishes to reference the same name/value pairs. This is because EJB was originally designed different than Servlets and each EJB literally gets its own private JNDI namespace, java:comp/env, whereas all Servlets in the same module share the same java:comp/env.

    <ejb-jar>
      <enterprise-beans>
        <session>
          <ejb-name>MySessionBean</ejb-name>
          <env-entry>
            <env-entry-name>myBoolean</env-entry-name>
            <env-entry-type>java.lang.Boolean</env-entry-type>
            <env-entry-value>true</env-entry-value>
          </env-entry>
          <env-entry>
            <env-entry-name>myString</env-entry-name>
            <env-entry-type>java.lang.String</env-entry-type>
            <env-entry-value>hello world</env-entry-value>
          </env-entry>
          <env-entry>
            <env-entry-name>myDouble</env-entry-name>
            <env-entry-type>java.lang.Double</env-entry-type>
            <env-entry-value>1.1</env-entry-value>
          </env-entry>
          <env-entry>
            <env-entry-name>myLong</env-entry-name>
            <env-entry-type>java.lang.Long</env-entry-type>
            <env-entry-value>12345678</env-entry-value>
          </env-entry>
          <env-entry>
            <env-entry-name>myFloat</env-entry-name>
            <env-entry-type>java.lang.Float</env-entry-type>
            <env-entry-value>1.3</env-entry-value>
          </env-entry>
          <env-entry>
            <env-entry-name>myInteger</env-entry-name>
            <env-entry-type>java.lang.Integer</env-entry-type>
            <env-entry-value>1024</env-entry-value>
          </env-entry>
          <env-entry>
            <env-entry-name>myShort</env-entry-name>
            <env-entry-type>java.lang.Short</env-entry-type>
            <env-entry-value>42</env-entry-value>
          </env-entry>
          <env-entry>
            <env-entry-name>myByte</env-entry-name>
            <env-entry-type>java.lang.Byte</env-entry-type>
            <env-entry-value>128</env-entry-value>
          </env-entry>
          <env-entry>
            <env-entry-name>myCharacter</env-entry-name>
            <env-entry-type>java.lang.Character</env-entry-type>
            <env-entry-value>D</env-entry-value>
          </env-entry>
        </session>
      </enterprise-beans>
    </ejb-jar>
    

    For readers lucky enough to be using EJB 3.1, you can use global JNDI and declare them in the application.xml and look them up from anywhere via java:app/myString. A feature most vendors have had for years which is now finally standard as of Java EE 6. Injection of those entries is also possible via @Resource(lookup="java:app/myString")

    Also new in Java EE 6 is support for two extra env-entry-type types, java.lang.Class and any enum. For example:

    <env-entry>
      <env-entry-name>myPreferredListImpl</env-entry-name>
      <env-entry-type>java.lang.Class</env-entry-type>
      <env-entry-value>java.util.ArrayList</env-entry-value>
    </env-entry>
    <env-entry>
      <env-entry-name>myBillingStragety</env-entry-name>
      <env-entry-type>java.lang.Class</env-entry-type>
      <env-entry-value>org.superbiz.BiMonthly</env-entry-value>
    </env-entry>
    <env-entry>
      <env-entry-name>displayElapsedTimeAs</env-entry-name>
      <env-entry-type>java.util.concurrent.TimeUnit</env-entry-type>
      <env-entry-value>MINUTES</env-entry-value>
    </env-entry>
    <env-entry>
      <env-entry-name>myFavoriteColor</env-entry-name>
      <env-entry-type>org.superbiz.ColorEnum</env-entry-type>
      <env-entry-value>ORANGE</env-entry-value>
    </env-entry>
    

    Referencing them with Injection

    Any of the above can be injected via @Resource. Just don't forget to fill in the name attribute to match the <env-entry-name>

    @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;
    
    }
    

    Referencing them with JNDI

    These names can also be standardly looked up via the javax.naming.InitialContext in the EJBs private and portable java:comp/env namespace.

    @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);
            }
        }
    }
    

    Referencing them with the SessionContext

    In EJB 3.0 as part of the simplification effort we added the ability to use the javax.ejb.SessionContext to do lookups. It is essentially the same, but has a little bit of sugar on it.

    • the java:comp/env prefix is not required
    • does not throw a checked exception (will instead throw EJBException for missing names)

    Service Locator patterns were all the buzz in 2003 so we decided to build a little bit of convenience into the EJB API.

    @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");
        }
    }
    

    Side note on IntialContext evilness

    Also, with my vendor hat on, I can tell you that there's a fair bit of slow plumbing that can be avoided under the hood with the SessionContext lookup.

    When you do 'java:' lookups on an InitialContext, the call goes to the VM, through a bunch of hoops to find who can resolve that name, then eventually to the vendor who will have to lookup state from the thread to figure out who asked and what namespace they're supposed to get. It does this on each and every call no matter what properties you pass into the InitialContext and what context the vendor initialized in its construction. The 'java:' simply jumps over all that. It's a rather frustrating part of being a vendor. It's also why the new javax.ejb.embedded.EJBContainer API does not use InitialContext anywhere at all and just references javax.naming.Context which is an actual interface rather than a concrete "factory" class with intense and obtuse plumbing.

    Doing the call on SessionContext should be much faster if the vendor did it right. In OpenEJB at least, all the above including the ThreadLocal is skipped and the call goes right into that bean's JNDI namespace which is already attached to the SessionContext.

    Another way to avoid the InitialContext overhead is to simply lookup java:comp/env once in the @PostConstruct and keep that resulting Context object and only use that. Then don't prefix lookups with java:comp/env/ and just lookup the names directly such as myString and myInteger. It will be faster, guaranteed.

    这篇关于@Resource可以用于在EJB3.0中注入基元吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆