我能否以类似于在 Spring 中使用名称别名的方式以多个名称部署 EJB?
2 回答
是的,可以使用描述符以多个名称或别名部署相同的 EJB。ejb-jar.xml
此外,EJB xml 描述符中定义的名称和注释中定义的名称都将被考虑在内(尽管出于可移植性原因,在这种情况下我不会冒险混合 xml 描述符和注释)。
此示例适用于 JBoss AS 7.1.1.Final:
@Local
public interface PingWorker {
String ping(String name);
}
@Stateless(name = "PingAlias") // first name
public class PingWorkerBean implements PingWorker {
@Override
public String ping(String name) {
return "Hello " + name;
}
}
<ejb-jar xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:ejb="http://java.sun.com/xml/ns/javaee/ejb-jar_3_0.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/ejb-jar_3_0.xsd" version="3.0">
<enterprise-beans>
<session>
<ejb-name>PingWorker</ejb-name> <!-- second name -->
<ejb-class>com.xyz.service.PingWorkerBean</ejb-class>
<session-type>Stateless</session-type>
</session>
<session>
<ejb-name>PingProcessor</ejb-name> <!-- third name -->
<ejb-class>com.xyz.service.PingWorkerBean</ejb-class>
<session-type>Stateless</session-type>
</session>
</enterprise-beans>
</ejb-jar>
在引用组件中,您可以声明:
@Stateless
public class PingBean implements Ping {
@EJB(beanName = "PingAlias")
private PingWorker pingWorkerByAnnotaion;
@EJB(beanName = "PingWorker")
private PingWorker pingWorkerByDescriptorOne;
@EJB(beanName = "PingProcessor")
private PingWorker pingWorkerByDescriptorTwo;
}
并且应该满足所有三个参考。在部署时,部署了三个 EJB,它们公开相同的接口和实现,但名称不同:
java:global/ear-app-1/ejb-1/PingProcessor!com.xyz.service.PingWorker
java:app/ejb-1/PingProcessor!com.xyz.service.PingWorker
java:module/PingProcessor!com.xyz.service.PingWorker
java:global/ear-app-1/ejb-1/PingProcessor
java:app/ejb-1/PingProcessor
java:module/PingProcessor
java:global/ear-app-1/ejb-1/PingAlias!com.xyz.service.PingWorker
java:app/ejb-1/PingAlias!com.xyz.service.PingWorker
java:module/PingAlias!com.xyz.service.PingWorker
java:global/ear-app-1/ejb-1/PingAlias
java:app/ejb-1/PingAlias
java:module/PingAlias
java:global/ear-app-1/ejb-1/PingWorker!com.xyz.service.PingWorker
java:app/ejb-1/PingWorker!com.xyz.service.PingWorker
java:module/PingWorker!com.xyz.service.PingWorker
java:global/ear-app-1/ejb-1/PingWorker
java:app/ejb-1/PingWorker
java:module/PingWorker
正如您可能看到的,这与 Spring 中的别名不同。虽然在 Spring 中别名只是引用相同实例或实例集的不同名称(取决于范围) - 在 EJB 中,您需要多次声明 EJB。在 EJB 容器中,这些在实例池等方面成为单独的 EJB。
根据您要实现的目标 - 您还可以考虑在引用 EJB 时覆盖引用的 EJB 名称(beanName
使用描述符覆盖注释<ejb-link/>
)。更多信息在这里:
选择要注入的 EJB 而无需重新编译。
根据 EJB 3.0 规范:
申报时:
姓名
注释元素名称定义了 bean “名称”,默认为 bean 类的非限定名称。bean 名称在包含 EJB的模块范围内必须是唯一的。
引用 EJB:
豆名
beanName 元素指定bean“名称”,如在@Stateful 和@Stateless 注释中通过name 元素或在部署描述符中通过该元素声明的那样。当多个 EJB 在应用程序中实现相同的业务接口时,beanName 元素最有用:beanName 让开发人员可以引用特定模块中的特定 EJB。
所以,是的,你可以,但 ejb 必须打包在不同的模块中,然后通过 beanName 指向它。
不像春天。,可能有方法,但这是特定于供应商的,不可移植。