知識庫 / Spring RSS 訂閱

Spring 和 EJB 集成指南

Jakarta EE,Spring
HongKong
2
02:08 PM · Dec 06 ,2025

1. 概述

本文將演示如何集成 Spring 和遠程企業 JavaBean(EJB)。

為了實現這一點,我們將創建一些 EJB 以及必要的遠程接口,然後將在 JEE 容器中運行它們。之後,我們將啓動我們的 Spring 應用程序,並使用遠程接口實例化我們的 Bean,以便它們可以執行遠程調用。

如果您對 EJB 的含義或其工作原理有任何疑問,我們之前已經發布過一篇關於該主題的入門文章,您可以參考一下。

2. EJB 設置

我們需要創建遠程接口和 EJB 實現。為了使它們可用,我們還需要一個容器來託管和管理 Bean。

2.1. EJB 遠程接口

讓我們先定義兩個簡單的 Bean——一個無狀態 Bean和一個狀態 Bean。

我們將從它們的接口開始:

@Remote
public interface HelloStatefulWorld {
    int howManyTimes();
    String getHelloWorld();
}

@Remote
public interface HelloStatelessWorld {
    String getHelloWorld();
}

2.2. EJB 實現

現在,讓我們實現我們的遠程 EJB 接口:

@Stateful(name = "HelloStatefulWorld")
public class HelloStatefulWorldBean implements HelloStatefulWorld {

    private int howManyTimes = 0;

    public int howManyTimes() {
        return howManyTimes;
    }

    public String getHelloWorld() {
        howManyTimes++;
        return "Hello Stateful World";
    }
}

@Stateless(name = "HelloStatelessWorld")
public class HelloStatelessWorldBean implements HelloStatelessWorld {

    public String getHelloWorld() {
        return "Hello Stateless World!";
    }
}

如果狀態型和無狀態 Bean 聽起來不熟悉,這篇文章可能會對您有所幫助。

2.3. EJB容器

我們將使用一個專門的Wildfly實例運行我們的應用程序。 如果您想設置自己的實例,這篇文章可能會有所幫助。 您可以配置一個配置文件,將應用程序部署到安裝的Wildfly實例。

<profile>
 <id>wildfly-runtime</id>
 <plugin>
     <groupId>org.wildfly.plugins</groupId>
     <artifactId>wildfly-maven-plugin</artifactId>
     <version>1.1.0.Alpha5</version>
     <configuration>
                <hostname>127.0.0.1</hostname>
                <port>9990</port>
                <username>9990</username>
                <password>admin1234!</password>
                <filename>${project.build.finalName}.jar</filename>
     </configuration>
 </plugin>
</profile>

2.4. 運行 EJBs

配置完成後,我們可以直接從 Maven 命令行運行容器:

mvn clean package cargo:run -Pwildfly-runtime

我們現在擁有一個運行實例的 Wildfly 正在託管我們的 Bean。我們可以通過日誌行來確認這一點:

java:global/ejb-remote-for-spring/HelloStatefulWorld!com.baeldung.ejb.tutorial.HelloStatefulWorld
java:app/ejb-remote-for-spring/HelloStatefulWorld!com.baeldung.ejb.tutorial.HelloStatefulWorld
java:module/HelloStatefulWorld!com.baeldung.ejb.tutorial.HelloStatefulWorld
java:jboss/exported/ejb-remote-for-spring/HelloStatefulWorld!com.baeldung.ejb.tutorial.HelloStatefulWorld
java:global/ejb-remote-for-spring/HelloStatefulWorld
java:app/ejb-remote-for-spring/HelloStatefulWorld
java:module/HelloStatefulWorld

java:global/ejb-remote-for-spring/HelloStatelessWorld!com.baeldung.ejb.tutorial.HelloStatelessWorld
java:app/ejb-remote-for-spring/HelloStatelessWorld!com.baeldung.ejb.tutorial.HelloStatelessWorld
java:module/HelloStatelessWorld!com.baeldung.ejb.tutorial.HelloStatelessWorld
java:jboss/exported/ejb-remote-for-spring/HelloStatelessWorld!com.baeldung.ejb.tutorial.HelloStatelessWorld
java:global/ejb-remote-for-spring/HelloStatelessWorld
java:app/ejb-remote-for-spring/HelloStatelessWorld
java:module/HelloStatelessWorld

3. Spring 部署

現在我們已經啓動了 JEE 容器,並部署了 EJBs,就可以開始我們的 Spring 應用。我們將使用 spring-boot-web 以簡化手動測試,但這並非遠程調用所必需。

3.1. Maven 依賴

為了連接到遠程 EJBs,我們需要 Wildfly EJB 客户端 庫和我們的遠程接口:

<dependency>
    <groupId>org.wildfly</groupId>
    <artifactId>wildfly-ejb-client-bom</artifactId>
    <version>10.1.0.Final</version>
    <type>pom</type>
</dependency>
<dependency>
    <groupId>com.baeldung.spring.ejb</groupId>
    <artifactId>ejb-remote-for-spring</artifactId>
    <version>1.0.1</version>
    <type>ejb</type>
</dependency>

wildfly-ejb-client-bom的最新版本可以在 這裏 找到。

3.2. 命名策略上下文

有了這些依賴項在 classpath 中,我們可以實例化一個javax.naming.Context 來進行我們遠程 Bean 的查找。我們將它創建為 Spring Bean,以便在需要時自動注入它:

@Bean   
public Context context() throws NamingException {
    Properties jndiProps = new Properties();
    jndiProps.put("java.naming.factory.initial", 
      "org.jboss.naming.remote.client.InitialContextFactory");
    jndiProps.put("jboss.naming.client.ejb.context", true);
    jndiProps.put("java.naming.provider.url", 
      "http-remoting://localhost:8080");
    return new InitialContext(jndiProps);
}

這些屬性是用於告知遠程 URL 以及命名策略上下文的。

3.3. JNDI 模式

為了在 Spring 容器中連接我們的遠程 Bean,我們需要知道如何訪問它們。為此,我們將使用它們的 JNDI 綁定。下面是這些綁定的標準模式:

${appName}/${moduleName}/${distinctName}/${beanName}!${viewClassName}

請注意,由於我們部署了一個簡單的 jar 而不是 ear,並且沒有顯式設置名稱,因此我們沒有 appNamedistinctName。有關更多詳細信息,請參閲我們的 EJB 簡介文章,以防出現任何不一致的情況。

我們將使用這種模式將我們的遠程 Bean 與 Spring Bean 綁定。

3.4. 構建我們的 Spring Bean

為了訪問我們的 EJB,我們將使用之前提到的 JNDI。 記得我們之前用來檢查企業 Bean 是否部署的日誌行嗎?

我們現在將看到這些信息的使用情況:

@Bean
public HelloStatelessWorld helloStatelessWorld(Context context) 
  throws NamingException {
 
    return (HelloStatelessWorld) 
      context.lookup(this.getFullName(HelloStatelessWorld.class));
}
@Bean
public HelloStatefulWorld helloStatefulWorld(Context context) 
  throws NamingException {
 
    return (HelloStatefulWorld) 
      context.lookup(this.getFullName(HelloStatefulWorld.class));
}
private String getFullName(Class classType) {
    String moduleName = "ejb-remote-for-spring/";
    String beanName = classType.getSimpleName();
    String viewClassName = classType.getName();
    return moduleName + beanName + "!" + viewClassName;
}

我們必須非常小心地進行正確的 JNDI 綁定,否則上下文將無法訪問遠程 EJB 並創建必要的底層基礎設施。

請注意,從 Context 對象中調用 lookup 方法,如果在找不到您需要的 Bean 時將會拋出 NamingException

4. 集成

一切準備就緒後,我們可以在控制器中注入我們的 Bean,以便測試連接是否正確:

@RestController
public class HomeEndpoint {
 
    // ...
 
    @GetMapping("/stateless")
    public String getStateless() {
        return helloStatelessWorld.getHelloWorld();
    }
    
    @GetMapping("/stateful")
    public String getStateful() {
        return helloStatefulWorld.getHelloWorld()
          + " called " + helloStatefulWorld.howManyTimes() + " times";
    }
}

讓我們啓動我們的 Spring 服務器並檢查一些日誌。 我們會看到以下行,指示一切正常:

EJBCLIENT000013: Successful version handshake completed

現在,讓我們測試我們的無狀態 Bean。我們可以嘗試使用 curl 命令來驗證它們是否按預期運行:

curl http://localhost:8081/stateless
Hello Stateless World!

讓我們檢查一下我們的狀態化版本:

curl http://localhost:8081/stateful
Hello Stateful World called 1 times

curl http://localhost:8081/stateful
Hello Stateful World called 2 times

5. 結論

在本文中,我們學習瞭如何將 Spring 集成到 EJB 中,並向 JEE 容器進行遠程調用。我們創建了兩個遠程 EJB 接口,並且能夠通過 Spring Bean 以透明的方式調用它們。

儘管 Spring 得到了廣泛的應用,但在企業環境中,EJB 仍然很受歡迎。在這個快速示例中,我們展示瞭如何同時利用 Jakarta EE 的分佈式優勢以及 Spring 應用程序的易用性。

user avatar
0 位用戶收藏了這個故事!
收藏

發佈 評論

Some HTML is okay.