[英]Demistifying EJB annotations and injection
I'm currently puzzled with the way Glassfish 3.1.2.2 handles EJBs. 目前,我对Glassfish 3.1.2.2处理EJB的方式感到困惑。
I have an OSGi project, which consists of many OSGi bundles (jars). 我有一个OSGi项目,其中包含许多OSGi捆绑包(罐)。 Also, there are a few WARs, including a Tapestry web application.
另外,还有一些WAR,包括Tapestry Web应用程序。
In one such bundle, let's call it "interfaces.jar", I have an interface defined: 在一个这样的包中,我们将其称为“ interfaces.jar”,我定义了一个接口:
public interface MyInterface() {
public static final String JNDI_NAME = "java:global/MyInterface";
void myMethod();
}
The implementation of that interface is as following, and it's contained in bundle "beans.jar": 该接口的实现如下,它包含在捆绑包“ beans.jar”中:
@Stateless
@EJB(name = MyInterface.JNDI_NAME, beanInterface = MyInterface)
public class MyBean implements MyInterface() {
void myMethod() {
...
}
}
I am calling it from my Tapestry WAR app via JNDI lookup: 我通过JNDI查找从我的Tapestry WAR应用程序中调用它:
InitialContext.doLookup(MyInterface.JNDI_NAME);
Now, I was reading EJB 3.1 specification, and it says that I can one of the following scenarios: 现在,我正在阅读EJB 3.1规范,它说我可以采用以下方案之一:
So, by elimination: 因此,通过消除:
So, it seems that it's case 3: 因此,似乎是情况3:
"Because it's the only implemented interface of the EJB, a container assumes that it must be a local business interface."
“因为它是EJB唯一实现的接口,所以容器假定它必须是本地业务接口。”
Now, a few questions: 现在,有几个问题:
@EJB
annotation, but it fails? @EJB
注释将其注入,但是失败了吗? @Local
or @Remote
, and perform JNDI lookup, I get a naming exception and NPE telling me there is nothing under that JNDI_NAME
. @Local
或@Remote
并执行JNDI查找,则会得到一个命名异常,并且NPE告诉我该JNDI_NAME
下没有任何JNDI_NAME
。 How is that possible? @EJB(name = ..., beanInterface = ...)
do on bean class and how does it interact with @Local
and @Remote
annotations? @EJB(name = ..., beanInterface = ...)
对bean类的作用是什么?它如何与@Local
和@Remote
批注交互? 1.) First, let's see your example without the "unnecessary" @EJB annotation 1.)首先,让我们看一下没有“不必要” @EJB注释的示例
@Stateless
public class MyBean implements MyInterface() {
void myMethod() {
...
}
}
You can now see clearly, that the EJB implements only one interface. 现在您可以清楚地看到EJB仅实现了一个接口。 As you mentioned in the 3rd points, "Interface is a plain Java interface without annotation; EJB is implementing it.", so MyInterface is a Local Business Interface of the MyBean EJB.
正如您在第3点中提到的那样,“接口是没有注释的普通Java接口; EJB正在实现它。”因此MyInterface是MyBean EJB的本地业务接口。
2.) 2.)
You use wrong JNDI name for the lookup: 您使用错误的JNDI名称进行查找:
@Stateless
public class MyBean implements MyInterface() {
...
The global JNDI name of your EJB: EJB的全局JNDI名称:
java:global[/app-name][/module-name]/MyBean[!interface-name]
The interface-name is "MyInterface", but it is optional if there are no other business interfaces for your beans, like here, so you can skip it. 接口名称为“ MyInterface”,但如果没有其他可用于您的bean的业务接口(例如此处),则它是可选的,因此可以跳过它。
You have to figure out what the application- and module-name is for your bean in case of OSGI. 对于OSGI,您必须弄清楚bean的应用程序名称和模块名称是什么。 In a simple EJB application, the application-name is the name of the .ear file, and the module-name is the name of the .war/.jar file.
在一个简单的EJB应用程序中,application-name是.ear文件的名称,而module-name是.war / .jar文件的名称。 application-name can be skipped if your module is not packaged in an ear.
如果您的模块未包装在耳边,则可以跳过application-name。
So for example: 因此,例如:
new InitialContext().lookup("java:global/myModuleName/MyBean");
5.) 5.)
@Stateless
@EJB(name = "MyInterface", beanInterface = MyInterface.class)
public class MyBean implements MyInterface() {
void myMethod() {
...
}
}
Here the @EJB annotation creates an EJB and put a reference to it into the Environment Naming Context (ENC). 在这里,@ EJB注释创建一个EJB,并将对它的引用放入环境命名上下文(ENC)中。 So it does nothing with the MyBean EJB, just expand its ENC with a new entry.
因此,它对MyBean EJB无效,只需使用新条目扩展其ENC。
So from the business method of the current bean you can lookup for that new entry: 因此,从当前bean的业务方法中,您可以查找该新条目:
void myMethod() {
new InitialContext().lookup("java:comp/env/MyInterface")
}
You can locate the bean's ENC by "java:comp/env/" JNDI name. 您可以通过“ java:comp / env /” JNDI名称找到bean的ENC。
As you can see, the name parameter defines the name of the entry in the ENC. 如您所见, name参数定义了ENC中条目的名称。
The beanInterface defines the Business Interface of the created Bean. beanInterface定义了创建的Bean的业务接口。 If the Bean has more business interfaces, then you have to define beanName too, so the container could determine wich Bean you would like to create.
如果Bean具有更多的业务接口,那么您也必须定义beanName,以便容器可以确定要创建的夹心Bean。
You can read about this topic here: http://thegreyblog.blogspot.hu/2010/09/introduction-to-ejb-30-injection-and.html 您可以在此处阅读有关此主题的信息: http : //thegreyblog.blogspot.hu/2010/09/introduction-to-ejb-30-injection-and.html
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.