繁体   English   中英

消除EJB注释和注入

[英]Demistifying EJB annotations and injection

目前,我对Glassfish 3.1.2.2处理EJB的方式感到困惑。

我有一个OSGi项目,其中包含许多OSGi捆绑包(罐)。 另外,还有一些WAR,包括Tapestry Web应用程序。

在一个这样的包中,我们将其称为“ interfaces.jar”,我定义了一个接口:

public interface MyInterface() {
    public static final String JNDI_NAME = "java:global/MyInterface";
    void myMethod();
}

该接口的实现如下,它包含在捆绑包“ beans.jar”中:

@Stateless
@EJB(name = MyInterface.JNDI_NAME, beanInterface = MyInterface)
public class MyBean implements MyInterface() {
    void myMethod() {
        ...
    }
}

我通过JNDI查找从我的Tapestry WAR应用程序中调用它:

InitialContext.doLookup(MyInterface.JNDI_NAME);

现在,我正在阅读EJB 3.1规范,它说我可以采用以下方案之一:

  1. 接口具有@Local批注; EJB正在实现此接口。
  2. 接口是没有注释的纯Java接口。 具有@Local批注的EJB正在实现它。
  3. 接口是没有注释的纯Java接口。 EJB正在实现它。
  4. 接口是没有注释的纯Java接口。 具有@Local批注的EJB没有实现它。
  5. EJB没有任何特殊的注释。

因此,通过消除:

  1. 我的界面上没有@Local
  2. 我在EJB上没有@Local
  3. 似乎有些正确
  4. 我在EJB上没有@Local
  5. 我的EJB上有@EJB注释

因此,似乎是情况3:

“因为它是EJB唯一实现的接口,所以容器假定它必须是本地业务接口。”

现在,有几个问题:

  1. 由于没有本地或远程注释,我的接口是本地还是远程接口?
  2. 如果它是本地的,我应该可以使用@EJB注释将其注入,但是失败了吗?
  3. 如果是远程的,是否不符合上面几行的说明?
  4. 如果我添加@Local@Remote并执行JNDI查找,则会得到一个命名异常,并且NPE告诉我该JNDI_NAME下没有任何JNDI_NAME 那怎么可能?
  5. @EJB(name = ..., beanInterface = ...)对bean类的作用是什么?它如何与@Local@Remote批注交互?

1.)首先,让我们看一下没有“不必要” @EJB注释的示例

@Stateless
public class MyBean implements MyInterface() {
    void myMethod() {
        ...
    }
}

现在您可以清楚地看到EJB仅实现了一个接口。 正如您在第3点中提到的那样,“接口是没有注释的普通Java接口; EJB正在实现它。”因此MyInterface是MyBean EJB的本地业务接口。

2.)

您使用错误的JNDI名称进行查找:

@Stateless
public class MyBean implements MyInterface() {
    ...

EJB的全局JNDI名称:

java:global[/app-name][/module-name]/MyBean[!interface-name]

接口名称为“ MyInterface”,但如果没有其他可用于您的bean的业务接口(例如此处),则它是可选的,因此可以跳过它。

对于OSGI,您必须弄清楚bean的应用程序名称和模块名称是什么。 在一个简单的EJB应用程序中,application-name是.ear文件的名称,而module-name是.war / .jar文件的名称。 如果您的模块未包装在耳边,则可以跳过application-name。

因此,例如:

new InitialContext().lookup("java:global/myModuleName/MyBean");

5.)

@Stateless
@EJB(name = "MyInterface", beanInterface = MyInterface.class)
public class MyBean implements MyInterface() {
    void myMethod() {
        ...
    }
}

在这里,@ EJB注释创建一个EJB,并将对它的引用放入环境命名上下文(ENC)中。 因此,它对MyBean EJB无效,只需使用新条目扩展其ENC。

因此,从当前bean的业务方法中,您可以查找该新条目:

    void myMethod() {
        new InitialContext().lookup("java:comp/env/MyInterface")
    }

您可以通过“ java:comp / env /” JNDI名称找到bean的ENC。

如您所见, name参数定义了ENC中条目的名称。

beanInterface定义了创建的Bean的业务接口。 如果Bean具有更多的业务接口,那么您也必须定义beanName,以便容器可以确定要创建的夹心Bean。

您可以在此处阅读有关此主题的信息: http : //thegreyblog.blogspot.hu/2010/09/introduction-to-ejb-30-injection-and.html

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM