0

我能否以类似于在 Spring 中使用名称别名的方式以多个名称部署 EJB?

4

2 回答 2

0

是的,可以使用描述符以多个名称或别名部署相同的 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 而无需重新编译

于 2014-03-10T16:22:29.480 回答
0

根据 EJB 3.0 规范:

申报时:

姓名

注释元素名称定义了 bean “名称”,默认为 bean 类的非限定名称。bean 名称在包含 EJB的模块范围内必须是唯一的

引用 EJB:

豆名

beanName 元素指定bean“名称”,如在@Stateful 和@Stateless 注释中通过name 元素或在部署描述符中通过该元素声明的那样。当多个 EJB 在应用程序中实现相同的业务接口时,beanName 元素最有用:beanName 让开发人员可以引用特定模块中的特定 EJB

所以,是的,你可以,但 ejb 必须打包在不同的模块中,然后通过 beanName 指向它。

不像春天。,可能有方法,但这是特定于供应商的,不可移植。

于 2013-10-10T18:36:46.990 回答