SpringとEJBの統合ガイド
1. 概要
この記事では、integrate Spring and remote Enterprise Java Beans (EJB)を実行する方法を示します。
これを行うには、いくつかのEJBと必要なリモートインターフェースを作成してから、それらをJEEコンテナー内で実行します。 その後、Springアプリケーションを起動し、リモートインターフェースを使用して、Beanをインスタンス化し、リモート呼び出しを実行できるようにします。
EJBとは何か、またはEJBがどのように機能するかについて疑問がある場合は、トピックhereに関する紹介記事をすでに公開しています。
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がなじみのないように聞こえる場合は、this intro articleが役立つ場合があります。
2.3. EJBコンテナ
コードは任意のJEEコンテナーで実行できますが、実用性を高めるために、WildflyとcargoMavenプラグインを使用して手間のかかる作業を行います。
org.codehaus.cargo
cargo-maven2-plugin
1.6.1
wildfly10x
http://download.jboss.org/wildfly/10.1.0.Final/wildfly-10.1.0.Final.zip
127.0.0.1
standalone-full
9990
testUser:admin1234!
2.4. EJBの実行
これらを設定すると、Mavenコマンドラインから直接コンテナーを実行できます。
mvn clean package cargo:run -Pwildfly-standalone
これで、BeanをホストするWildflyの作業インスタンスができました。 これはログ行で確認できます。
java:global/ejb-remote-for-spring/HelloStatefulWorld!com.example.ejb.tutorial.HelloStatefulWorld
java:app/ejb-remote-for-spring/HelloStatefulWorld!com.example.ejb.tutorial.HelloStatefulWorld
java:module/HelloStatefulWorld!com.example.ejb.tutorial.HelloStatefulWorld
java:jboss/exported/ejb-remote-for-spring/HelloStatefulWorld!com.example.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.example.ejb.tutorial.HelloStatelessWorld
java:app/ejb-remote-for-spring/HelloStatelessWorld!com.example.ejb.tutorial.HelloStatelessWorld
java:module/HelloStatelessWorld!com.example.ejb.tutorial.HelloStatelessWorld
java:jboss/exported/ejb-remote-for-spring/HelloStatelessWorld!com.example.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ライブラリとリモートインターフェイスが必要です。
org.wildfly
wildfly-ejb-client-bom
10.1.0.Final
pom
com.example.spring.ejb
ejb-remote-for-spring
1.0.1
ejb
wildfly-ejb-client-bomの最後のバージョンはhereにあります。
3.2. ネーミング戦略のコンテキスト
クラスパスにこれらの依存関係があると、instantiate a javax.naming.Context to do the lookup of our remote beansを実行できます。 これをSpringBeanとして作成し、必要なときに自動配線できるようにします。
@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);
}
プロパティはinform both the remote URL and the naming strategy contextに必要です。
3.3. JNDIパターン
Springコンテナ内にリモートBeanを配線する前に、それらに到達する方法を知る必要があります。 このために、JNDIバインディングを使用します。 これらのバインディングの標準パターンを見てみましょう。
${appName}/${moduleName}/${distinctName}/${beanName}!${viewClassName}
since we deployed a simple jar instead of an ear and didn’t explicitly set up a name, we don’t have an appName and a distinctNameであることに注意してください。 何かがおかしいと思われる場合に備えて、EJB Intro articleに詳細があります。
このパターンを使用して、リモートBeanをSpringBeanにバインドします。
3.4. SpringBeansの構築
To reach our EJBs, we’ll use the aforementioned 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;
}
We need to be very careful about the correct full JNDI bindingを指定しないと、コンテキストがリモートEJBに到達して、必要な基盤となるインフラストラクチャを作成できなくなります。
Contextのメソッドlookupは、必要なBeanが見つからない場合に、NamingExceptionをスローすることに注意してください。
4. 統合
すべてが整ったら、inject our beans in a controllerを実行できるので、配線が正しいかどうかをテストできます。
@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サーバーを起動して、いくつかのログを確認しましょう。 次の行が表示され、すべてがOKであることを示します。
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 Beanを使用してそれらを透過的に呼び出すことができました。
Springは広く採用されていますが、EJBは依然としてエンタープライズ環境で人気があります。この簡単な例では、JavaEEの分散ゲインとSpringアプリケーションの使いやすさの両方を利用できることを示しました。
いつものように、コードはover on GitHubで見つけることができます。