当前位置: 首页 > 面试题库 >

可以使用@Resource在EJB3.0中注入基元吗?

卞安邦
2023-03-14
问题内容

使用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,但是不幸的是,我的产品环境仅为ejb3.0。

我想我想找出一种方法可以使用@Resource(name =)或@Resource(mappedName =)做类似的事情吗?name
=似乎是特定于应用程序的,因此我应该能够以某种方式将相对名称映射到全局JNDI名称,但是我无法弄清楚该映射使用了什么注释。

谢谢!


问题答案:

所有8种原始包装器和String都支持@Resource类型,并且可以通过在标准ejb-jar.xml文件中声明它们来进行查找或注入。

声明名称值(和类型)对

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

在EJB
3.0中,必须对希望引用相同名称/值对的每个bean执行此操作。这是因为EJB最初的设计与Servlet不同,并且每个EJB实际上都获得了自己的私有JNDI名称空间java:comp/env,而同一模块中的所有Servlet共享相同的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>

对于有幸使用EJB
3.1的读者,可以使用全局JNDI并在application.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
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;

}

用JNDI引用它们

这些名称也可以通过EJB私有和可移植java:comp/env命名空间中的javax.naming.InitialContext标准地查找。

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

使用SessionContext引用它们

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

  • java:comp/env不需要前缀
  • 不引发检查的异常(对于缺少的名称,将引发EJBException)

Service Locator模式在2003年一直是热门话题,因此我们决定在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");
    }
}

关于IntialContext邪恶的旁注

另外,戴上我的供应商帽子,我可以告诉你,在SessionContext查找过程中可以避免很多缓慢的管道。

当您在上执行“
java:”查询时InitialContext,调用将通过一堆箍转到VM,以查找谁可以解析该名称,然后最终找到供应商,后者将不得不从线程中查找状态以找出谁提出了要求。以及他们应该获得的命名空间。无论您将什么属性传递给InitialContext,以及供应商在构造时初始化的上下文,它都会在每个调用中执行此操作。“
java:”简单地跳过了所有这些。作为供应商,这是相当令人沮丧的一部分。这也是为什么新的javax.ejb.embedded.EJBContainerAPI根本不使用InitialContext任何地方,而只是引用javax.naming.Context它是一个实际的接口,而不是带有密集且钝的管道的具体“工厂”类的原因。

如果供应商正确执行,那么在SessionContext上进行调用应该会更快。至少在OpenEJB中,所有上述内容(包括ThreadLocal)都将被跳过,并且调用将直接进入已附加到Bean的JNDI名称空间SessionContext

避免InitialContext开销的另一种方法是,只需java:comp/env在@PostConstruct中查找一次,并保留该结果Context对象并仅使用它。然后,不要在查找之前添加前缀,java:comp/env/而直接查找诸如myString和的名称myInteger。它将更快,有保证。



 类似资料:
  • 问题内容: 我可以在JSON文件中使用注释吗?如果是这样,怎么办? 问题答案: 没有。 JSON应该都是数据,如果包含注释,那么它也将是数据。 您可能有一个称为(或其他名称)的指定数据元素,使用JSON数据的应用程序会忽略该数据元素。 在生成/接收JSON的过程中添加注释可能会更好,因为它们应该事先知道什么是JSON数据,或者至少知道其结构。 但是,如果您决定:

  • 我想把它转换成这样的东西: 这将使类不可变并且更容易进行单元测试。问题是,由于executorService需要通过@Resource注释获得,它似乎不能通过构造函数注入。

  • SimpleSession Bean类(EJB)的代码片段: EJB没有weblogic-ejb-jar.xml部署描述符,因此它是完全注释的EJB。 在管理控制台中部署WAR之后,在servlet中直接注入后,我得到了一个空引用。 http://docs.oracle.com/cd/e14571_01/web.1111/e14529/compatibility.htm “ WebLogic Se

  • 那么为什么我不能像这样为它编写单元测试: 使用这种方法我会面临什么缺点?

  • 问题内容: 是否可以在模块的config部分注入$ q?以下是我的示例配置部分。 我遇到的第一个错误是 未捕获的错误:未知提供程序:Reportqule中的$ q 如果我更改 至 然后我收到一条错误消息,指出 未捕获的TypeError:对象#从ReportModule没有方法“推迟” 好像我不能在配置部分注入$ q。是这种情况还是我做错了什么?我有一个用例,需要在模块的config部分中使用$

  • 有一个简单的Mongo DB生产者连接到Mongo数据库 我的src/main/resources/meta-inf中的一个资源文件 WeldContext和WeldJUnit4Runner来自这里-http://memorynotfound.com/java-se-unit-testing-cdi-junit-jboss-weld-se/