Guide d’intégration pour Spring et EJB

Guide d'intégration pour Spring et EJB

1. Vue d'ensemble

Dans cet article, nous allons montrer commentintegrate Spring and remote Enterprise Java Beans (EJB).

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 sujethere.

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,this intro article 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 plugincargo Maven pour faire le gros du travail à notre place:


    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. 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 de travail de Wildfly hébergeant nos haricots. Nous pouvons le confirmer par les lignes du journal:

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

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

3.1. Dépendances Maven

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


    org.wildfly
    wildfly-ejb-client-bom
    10.1.0.Final
    pom


    com.example.spring.ejb
    ejb-remote-for-spring
    1.0.1
    ejb

La dernière version dewildfly-ejb-client-bom peut être trouvéehere.

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

Avec ces dépendances dans le classpath, nous pouvonsinstantiate a javax.naming.Context to do the lookup of our remote beans. 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 pourinform both the remote URL and the naming strategy context.

3.3. Modèle JNDI

Avant de pouvoir câbler nos beans distants dans le conteneur Spring, nous devons savoir comment les atteindre. Pour cela, nous utiliserons leurs liaisons JNDI. Voyons le modèle standard de ces liaisons:

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

Gardez à l'esprit que,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. Il y a plus de détails dans nosEJB Intro article 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

To reach our EJBs, we’ll use the aforementioned JNDI. Vous souvenez-vous des lignes de journal que nous avons utilisées pour vérifier si nos beans entreprise ont été 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;
}

We need to be very careful about the correct full JNDI binding ou le contexte ne pourront pas atteindre l'EJB distant et créer l'infrastructure sous-jacente nécessaire.

Gardez à l'esprit que la méthodelookup deContext lancera unNamingException au cas où elle ne trouverait pas le bean dont vous avez besoin.

4. L'intégration

Avec tout en place, nous pouvonsinject our beans in a controller, donc nous pouvons 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 certains journaux. Nous verrons la ligne suivante, indiquant que tout va bien:

EJBCLIENT000013: Successful version handshake completed

Maintenant, testons notre haricot sans état. Nous pouvons essayer certaines commandescurl pour vérifier qu'elles fonctionnent comme prévu:

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

Et vérifions notre état avec état:

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

curl http://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 qui utilisent 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 JavaEE et la facilité d'utilisation des applications Spring.

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