1概要

この記事では、SpringとリモートのEnterprise Java Beans(EJB)を統合する方法を説明します。

これを行うには、いくつかのEJBと必要なリモートインタフェースを作成してから、それらをJEEコンテナ内で実行します。その後、Springアプリケーションを起動し、リモートインタフェースを使用して、Beanがリモート呼び出しを実行できるようにインスタンス化します。

EJBとは何か、またはEJBがどのように機能するのかについて疑問がある場合は、トピックリンク「/ejb-intro[ここ]」についての紹介記事を既に公開しています。


2 EJBセットアップ

リモートインタフェースとEJB実装を作成する必要があります。

それらを使用可能にするには、Beanを保持および管理するためのコンテナも必要です。


2.1. EJBリモートインタフェース

まず、2つの非常に単純なBean(1つはステートレス、もう1つはステートフル)を定義することから始めましょう。

私たちは彼らのインターフェースから始めます。

@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とステートレスBeanがなじみがないように思われる場合は、

この紹介記事

を読んでください。


2.3. EJBコンテナ

コードは任意のJEEコンテナで実行できますが、実用的には、Wildflyと

cargo

Mavenプラグインを使用して重い作業を行います。

<plugin>
    <groupId>org.codehaus.cargo</groupId>
    <artifactId>cargo-maven2-plugin</artifactId>
    <version>1.6.1</version>
    <configuration>
        <container>
            <containerId>wildfly10x</containerId>
            <zipUrlInstaller>
                <url>
                  http://download.jboss.org/wildfly/10.1.0.Final/wildfly-10.1.0.Final.zip
                </url>
            </zipUrlInstaller>
        </container>
        <configuration>
            <properties>
                <cargo.hostname>127.0.0.1</cargo.hostname>
                <cargo.jboss.configuration>standalone-full</cargo.jboss.configuration>
                <cargo.jboss.management-http.port>9990</cargo.jboss.management-http.port>
                <cargo.servlet.users>testUser:admin1234!</cargo.servlet.users>
            </properties>
        </configuration>
    </configuration>
</plugin>


2.4. EJBの実行

これらを設定すると、Mavenコマンドラインから直接コンテナを実行できます。

mvn clean package cargo:run -Pwildfly-standalone

これで、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春のセットアップ

JEEコンテナーを稼働させ、EJBをデプロイしたので、Springアプリケーションを起動できます。手動でテストしやすくするために

spring-boot-web

を使用しますが、リモート呼び出しには必須ではありません。


3.1. Mavenの依存関係

リモートEJBに接続するには、

Wildfly EJB Client

ライブラリとリモートインタフェースが必要です。

<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

の最新版はhttps://search.maven.org/classic/#search%7C1%7Cg%3A%22org.wildfly%22%20AND%20a%3A%22wildflyにあります。 -ejb-client-bom%22[ここ]。


3.2. 命名戦略のコンテキスト

クラスパスにこれらの依存関係があれば、

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パターン

リモートBeanをSpringコンテナ内に配線する前に、それらに到達する方法を知る必要があります。このために、私たちは彼らのJNDIバインディングを使います。

これらのバインディングの標準的なパターンを見てみましょう。

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


  • ear

    の代わりに単純な

    jar

    を展開し、明示的に名前を設定しなかったため、

    appName



    distinctName

    を持たないことに注意してください。私たちのリンクでより多くの詳細があります:/ejb-intro[EJBイントロ記事]何かがおかしいように思える場合。

このパターンを使用して、リモートBeanをSpring Beanにバインドします。


3.4. Spring Beans

を構築する

EJBに到達するために、前述のJNDIを使用します。

その情報は現在使用中です。

@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コンテナーへのリモート呼び出しを行う方法を学びました。 2つのリモートEJBインタフェースを作成し、Spring Beansを使用してそれらを透過的に呼び出すことができました。

Springは広く採用されていますが、EJBはエンタープライズ環境では依然として普及しています。この簡単な例では、JavaEEの分散型の利点とSpringアプリケーションの使いやすさの両方を利用できることを示しました。

いつものように、コードはhttps://github.com/eugenp/tutorials/tree/master/spring-ejb[over on GitHub]にあります。