Integrationshandbuch für Spring und EJB
1. Überblick
In diesem Artikel zeigen wir, wie manintegrate Spring and remote Enterprise Java Beans (EJB) macht.
Zu diesem Zweck erstellen wir einige EJBs und die erforderlichen Remote-Schnittstellen und führen sie dann in einem JEE-Container aus. Danach starten wir unsere Spring-Anwendung und instanziieren mithilfe der Remote-Schnittstellen unsere Beans, damit sie Remote-Aufrufe ausführen können.
Wenn Zweifel darüber bestehen, was EJBs sind oder wie sie funktionieren, haben wir bereits einen Einführungsartikel zum Themahere veröffentlicht.
2. EJB-Setup
Wir müssen unsere Remote-Schnittstellen und unsere EJB-Implementierungen erstellen. Um sie nutzbar zu machen, benötigen wir außerdem einen Container zum Halten und Verwalten von Bohnen.
2.1. EJB Remote-Schnittstellen
Beginnen wir mit der Definition von zwei sehr einfachen Bohnen - einer zustandslosen und einer zustandsbehafteten.
Wir beginnen mit ihren Schnittstellen:
@Remote
public interface HelloStatefulWorld {
int howManyTimes();
String getHelloWorld();
}
@Remote
public interface HelloStatelessWorld {
String getHelloWorld();
}
2.2. EJB-Implementierung
Lassen Sie uns nun unsere Remote-EJB-Schnittstellen implementieren:
@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!";
}
}
Wenn zustandsbehaftete und zustandslose Bohnen ungewohnt klingen, könnenthis intro article nützlich sein.
2.3. EJB Container
Wir können unseren Code in jedem JEE-Container ausführen, aber aus praktischen Gründen verwenden wir Wildfly und dascargo Maven-Plugin, um das schwere Heben für uns zu erledigen:
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. Ausführen der EJBs
Mit diesen Einstellungen können wir den Container direkt über die Maven-Befehlszeile ausführen:
mvn clean package cargo:run -Pwildfly-standalone
Wir haben jetzt eine funktionierende Instanz von Wildfly, die unsere Bohnen hostet. Wir können dies durch die Protokollzeilen bestätigen:
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. Federkonfiguration
Nachdem wir unseren JEE-Container eingerichtet und unsere EJBs bereitgestellt haben, können wir unsere Spring-Anwendung starten. Wir verwendenspring-boot-web, um das manuelle Testen zu vereinfachen, dies ist jedoch für den Fernaufruf nicht obligatorisch.
3.1. Maven-Abhängigkeiten
Um eine Verbindung zu den Remote-EJBs herstellen zu können, benötigen wir dieWildfly EJB Client-Bibliothek und unsere Remote-Schnittstelle:
org.wildfly
wildfly-ejb-client-bom
10.1.0.Final
pom
com.example.spring.ejb
ejb-remote-for-spring
1.0.1
ejb
Die letzte Version vonwildfly-ejb-client-bom isthere.
3.2. Namensstrategie-Kontext
Mit diesen Abhängigkeiten im Klassenpfad können wirinstantiate a javax.naming.Context to do the lookup of our remote beans. Wir erstellen dies als Spring Bean, damit wir es bei Bedarf automatisch verdrahten können:
@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);
}
Die Eigenschaften sind zuinform both the remote URL and the naming strategy context notwendig.
3.3. JNDI-Muster
Bevor wir unsere Remote-Bohnen im Spring-Container verdrahten können, müssen wir wissen, wie wir sie erreichen können. Dafür verwenden wir ihre JNDI-Bindungen. Sehen wir uns das Standardmuster für diese Bindungen an:
${appName}/${moduleName}/${distinctName}/${beanName}!${viewClassName}
Beachten Sie, dasssince 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. Es gibt weitere Details zu unserenEJB Intro article, falls etwas seltsam erscheint.
Wir werden dieses Muster verwenden, um unsere entfernten Bohnen an unsere Frühlingsbohnen zu binden.
3.4. Bauen Sie unsere Frühlingsbohnen
To reach our EJBs, we’ll use the aforementioned JNDI. Erinnern Sie sich an Protokollzeilen, mit denen wir überprüft haben, ob unsere Enterprise-Beans bereitgestellt wurden?
Diese Informationen werden jetzt verwendet:
@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, oder der Kontext kann die Remote-EJB nicht erreichen und die erforderliche zugrunde liegende Infrastruktur erstellen.
Beachten Sie, dass die Methodelookup vonContextNamingException auslöst, falls die gewünschte Bean nicht gefunden wird.
4. Integration
Wenn alles vorhanden ist, können wirinject our beans in a controller, damit wir testen können, ob die Verkabelung richtig ist:
@RestController
public class HomeEndpoint {
// ...
@GetMapping("/stateless")
public String getStateless() {
return helloStatelessWorld.getHelloWorld();
}
@GetMapping("/stateful")
public String getStateful() {
return helloStatefulWorld.getHelloWorld()
+ " called " + helloStatefulWorld.howManyTimes() + " times";
}
}
Starten wir unseren Spring-Server und überprüfen einige Protokolle. Die folgende Zeile zeigt an, dass alles in Ordnung ist:
EJBCLIENT000013: Successful version handshake completed
Testen wir nun unsere zustandslose Bohne. Wir können einigecurl-Befehle ausprobieren, um zu überprüfen, ob sie wie erwartet funktionieren:
curl http://localhost:8081/stateless
Hello Stateless World!
Und lassen Sie uns unseren Status überprüfen:
curl http://localhost:8081/stateful
Hello Stateful World called 1 times
curl http://localhost:8081/stateful
Hello Stateful World called 2 times
5. Fazit
In diesem Artikel haben wir gelernt, wie Sie Spring in EJB integrieren und Remote-Aufrufe an den JEE-Container senden. Wir haben zwei entfernte EJB-Schnittstellen erstellt und konnten diese mithilfe von Spring Beans auf transparente Weise aufrufen.
Obwohl Spring weit verbreitet ist, sind EJBs in Unternehmensumgebungen immer noch beliebt. In diesem kurzen Beispiel haben wir gezeigt, dass es möglich ist, sowohl die verteilten Vorteile von JavaEE als auch die Benutzerfreundlichkeit von Spring-Anwendungen zu nutzen.
Wie immer kann der Codeover on GitHub gefunden werden.