Guide d'intégration pour Spring et EJB

1. Vue d'ensemble

Dans cet article, nous montrerons comment intégrer Spring et les Enterprise Java Beans (EJB) distants .

Pour ce faire, nous allons créer des EJB et les interfaces distantes nécessaires, puis nous les exécuterons dans un conteneur JEE. Après cela, nous allons démarrer notre application Spring et, à l'aide des interfaces distantes, instancier nos beans afin qu'ils puissent exécuter des appels distants.

En cas de doute sur ce que sont les EJB ou comment ils fonctionnent, nous avons déjà publié un article d'introduction sur le sujet ici.

2. Configuration EJB

Nous devrons créer nos interfaces distantes et nos implémentations EJB. Pour les rendre utilisables, nous aurons également besoin d'un conteneur pour contenir et gérer les beans.

2.1. Interfaces distantes EJB

Commençons par définir deux beans très simples - un sans état et un avec état.

Nous allons commencer par leurs interfaces:

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

2.2. Implémentation EJB

Maintenant, implémentons nos interfaces EJB distantes:

@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!"; } } 

Si les beans avec état et sans état ne vous semblent pas familiers, cet article d'introduction peut être utile.

2.3. Conteneur EJB

Nous pouvons exécuter notre code dans n'importe quel conteneur JEE, mais pour des raisons pratiques, nous utiliserons Wildfly et le plugin cargo Maven pour faire le gros du travail pour nous:

 org.codehaus.cargo cargo-maven2-plugin 1.6.1   wildfly10x   //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. Exécution des EJB

Avec ceux-ci configurés, nous pouvons exécuter le conteneur directement à partir de la ligne de commande Maven:

mvn clean package cargo:run -Pwildfly-standalone

Nous avons maintenant une instance fonctionnelle de Wildfly hébergeant nos beans. Nous pouvons le confirmer par les lignes de journal:

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. Configuration du printemps

Maintenant que notre conteneur JEE est opérationnel et que nos EJB sont déployés, nous pouvons démarrer notre application Spring. Nous utiliserons spring-boot-web pour faciliter le test manuel, mais ce n'est pas obligatoire pour l'appel à distance.

3.1. Dépendances de Maven

Pour pouvoir se connecter aux EJB distants, nous aurons besoin de la bibliothèque Wildfly EJB Client et de notre interface distante:

 org.wildfly wildfly-ejb-client-bom 10.1.0.Final pom   com.baeldung.spring.ejb ejb-remote-for-spring 1.0.1 ejb 

La dernière version de wildfly-ejb-client-bom peut être trouvée ici.

3.2. Contexte de la stratégie de dénomination

Avec ces dépendances dans le classpath, nous pouvons instancier un javax.naming.Context pour faire la recherche de nos beans distants . Nous allons le créer en tant que Spring Bean afin de pouvoir le connecter automatiquement lorsque nous en avons besoin:

@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); }

Les propriétés sont nécessaires pour informer à la fois l' URL distante et le contexte de la stratégie de dénomination .

3.3. Modèle JNDI

Avant de pouvoir câbler nos beans distants à l'intérieur du conteneur Spring, nous devons savoir comment les atteindre. Pour cela, nous utiliserons leurs liaisons JNDI. Voyons le modèle standard pour ces liaisons:

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

Gardez à l'esprit que, puisque nous avons déployé un simple jar au lieu d'une oreille et que nous n'avons pas explicitement configuré de nom, nous n'avons pas d' appName et de distinctName . Il y a plus de détails dans notre article EJB Intro au cas où quelque chose semble étrange.

Nous utiliserons ce modèle pour lier nos beans distants à nos beans Spring.

3.4. Construire nos haricots de printemps

Pour atteindre nos EJB, nous utiliserons le JNDI susmentionné. Vous vous souvenez des lignes de journal que nous utilisions pour vérifier si nos beans entreprise étaient déployés?

Nous verrons ces informations utilisées maintenant:

@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; }

Nous devons faire très attention à la liaison JNDI complète correcte, sinon le contexte ne pourra pas atteindre l'EJB distant et créer l'infrastructure sous-jacente nécessaire.

Gardez à l'esprit que la recherche de méthode à partir de Context lancera une exception NamingException au cas où elle ne trouverait pas le bean dont vous avez besoin.

4. Intégration

Avec tout en place, nous pouvons injecter nos beans dans un contrôleur , afin de pouvoir tester si le câblage est correct:

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

Commençons notre serveur Spring et vérifions quelques journaux. Nous verrons la ligne suivante, indiquant que tout va bien:

EJBCLIENT000013: Successful version handshake completed

Maintenant, testons notre bean sans état. Nous pouvons essayer quelques commandes curl pour vérifier qu'elles fonctionnent comme prévu:

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

Et vérifions notre état:

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

5. Conclusion

Dans cet article, nous avons appris à intégrer Spring à EJB et à effectuer des appels à distance vers le conteneur JEE. Nous avons créé deux interfaces EJB distantes, et nous avons pu appeler celles utilisant Spring Beans de manière transparente.

Même si Spring est largement adopté, les EJB sont toujours populaires dans les environnements d'entreprise, et dans cet exemple rapide, nous avons montré qu'il est possible d'utiliser à la fois les gains distribués de Jakarta EE et la facilité d'utilisation des applications Spring.

Comme toujours, le code peut être trouvé sur GitHub.