Integratiegids voor Spring en EJB

1. Overzicht

In dit artikel laten we zien hoe u dat doet integreer Spring en externe Enterprise Java Beans (EJB).

Om dit te doen, maken we enkele EJB's en de benodigde externe interfaces, en voeren we ze vervolgens uit in een JEE-container. Daarna zullen we onze Spring-applicatie starten en, met behulp van de externe interfaces, onze bonen instantiëren zodat ze externe oproepen kunnen uitvoeren.

Als er enige twijfel bestaat over wat EJB's zijn of hoe ze werken, hebben we hier al een inleidend artikel over het onderwerp gepubliceerd.

2. EJB-instellingen

We zullen onze externe interfaces en onze EJB-implementaties moeten maken. Om ze bruikbaar te maken, hebben we ook een container nodig om bonen in te bewaren en te beheren.

2.1. EJB externe interfaces

Laten we beginnen met het definiëren van twee zeer eenvoudige bonen - een staatloos en een staatloos.

We beginnen met hun interfaces:

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

2.2. EJB-implementatie

Laten we nu onze externe EJB-interfaces implementeren:

@Stateful (name = "HelloStatefulWorld") openbare klasse HelloStatefulWorldBean implementeert HelloStatefulWorld {private int howManyTimes = 0; openbare int howManyTimes () {terug howManyTimes; } openbare String getHelloWorld () {howManyTimes ++; retourneer "Hallo Stateful World"; }} 
@Stateless (name = "HelloStatelessWorld") openbare klasse HelloStatelessWorldBean implementeert HelloStatelessWorld {openbare String getHelloWorld () {return "Hallo Stateless World!"; }} 

Als stateful en staatloze bonen onbekend klinken, kan dit intro-artikel van pas komen.

2.3. EJB-container

We kunnen onze code in elke JEE-container uitvoeren, maar om praktische redenen gebruiken we Wildfly en de lading Maven-plug-in om het zware werk voor ons te doen:

 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. De EJB's uitvoeren

Als deze zijn geconfigureerd, kunnen we de container rechtstreeks vanaf de Maven-opdrachtregel uitvoeren:

mvn schone pakketlading: run -Pwildfly-standalone

We hebben nu een werkend exemplaar van Wildfly die onze bonen host. We kunnen dit bevestigen door de logregels:

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 / geëxporteerd / ejb-remote-for-spring / HelloStatefulWorld! Com.baeldung.ejb.tutorial.HelloStatefulWorld java: global / ejb-remote-java-for-spring / HelloStatefulWorld : 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: global / ejb-remote-for-spring / HelloStatelessWorld : app / ejb-remote-for-spring / HelloStatelessWorld java: module / HelloStatelessWorld

3. Lente setup

Nu we onze JEE-container in gebruik hebben en onze EJB's zijn geïmplementeerd, kunnen we onze Spring-applicatie starten. We zullen gebruiken spring-boot-web om het handmatig testen gemakkelijker te maken, maar het is niet verplicht voor de externe oproep.

3.1. Afhankelijkheden van Maven

Om verbinding te kunnen maken met de externe EJB's, hebben we de Wildfly EJB-client bibliotheek en onze externe interface:

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

De laatste versie van wildfly-ejb-client-bom vind je hier.

3.2. Naamgeving Strategie Context

Met deze afhankelijkheden in het klassenpad kunnen we instantiëren een javax.naming.Context om onze afgelegen bonen op te zoeken. We maken dit als een Spring Bean, zodat we het automatisch kunnen bedraden wanneer we het nodig hebben:

@Bean public Context context () gooit 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"); retourneer nieuwe InitialContext (jndiProps); }

De eigenschappen zijn nodig om informeer zowel de afstandsbediening URL en de naamgevingsstrategiecontext.

3.3. JNDI-patroon

Voordat we onze afgelegen bonen in de Spring-container kunnen aansluiten, moeten we weten hoe we ze kunnen bereiken. Hiervoor gebruiken we hun JNDI-bindingen. Laten we eens kijken naar het standaardpatroon voor deze bindingen:

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

Houd er rekening mee dat, sinds we een simple pot in plaats van een oor en niet expliciet een naam heeft ingesteld, hebben we geen applicatie naam en een distinctName. Er zijn meer details in ons EJB Intro-artikel voor het geval iets vreemd lijkt.

We zullen dit patroon gebruiken om onze afgelegen bonen aan onze lente-bonen te binden.

3.4. Bouwen aan onze voorjaarsbonen

Om onze EJB's te bereiken, gebruiken we de eerder genoemde JNDI. Herinner je je de logboekregels die we gebruikten om te controleren of onze enterprise-beans waren geïmplementeerd?

We zullen die informatie nu in gebruik zien:

@Bean openbaar HelloStatelessWorld helloStatelessWorld (Context context) gooit NamingException {return (HelloStatelessWorld) context.lookup (this.getFullName (HelloStatelessWorld.class)); } 
@Bean openbaar HelloStatefulWorld helloStatefulWorld (Context context) gooit NamingException {return (HelloStatefulWorld) context.lookup (this.getFullName (HelloStatefulWorld.class)); } 
private String getFullName (Class classType) {String moduleName = "ejb-remote-for-spring /"; String beanName = classType.getSimpleName (); Tekenreeks viewClassName = classType.getName (); return moduleName + beanName + "!" + viewClassName; }

We moeten heel voorzichtig zijn met de juiste volledige JNDI-binding, anders kan de context de externe EJB niet bereiken en de noodzakelijke onderliggende infrastructuur creëren.

Houd er rekening mee dat de methode opzoeken van Context zal een NamingException voor het geval het de boon die u nodig heeft niet vindt.

4. Integratie

Met alles op zijn plaats kunnen we dat injecteer onze bonen in een controller, zodat we kunnen testen of de bedrading klopt:

@RestController openbare klasse HomeEndpoint {// ... @GetMapping ("/ stateless") openbare String getStateless () {terugkeer helloStatelessWorld.getHelloWorld (); } @GetMapping ("/ stateful") openbare String getStateful () {return helloStatefulWorld.getHelloWorld () + "genaamd" + helloStatefulWorld.howManyTimes () + "times"; }}

Laten we onze Spring-server starten en enkele logboeken bekijken. We zullen de volgende regel zien, die aangeeft dat alles in orde is:

EJBCLIENT000013: Succesvolle versie-handshake voltooid

Laten we nu onze staatloze boon testen. We kunnen wat proberen krullen opdrachten om te verifiëren dat ze werken zoals verwacht:

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

En laten we onze stateful bekijken:

curl // localhost: 8081 / stateful Hallo Stateful World 1 keer gebeld curl // localhost: 8081 / stateful Hallo Stateful World 2 keer gebeld

5. Conclusie

In dit artikel hebben we geleerd hoe we Spring kunnen integreren met EJB en externe oproepen kunnen maken naar de JEE-container. We hebben twee externe EJB-interfaces gemaakt en we konden degenen die Spring Beans gebruiken op een transparante manier bellen.

Hoewel Spring algemeen wordt toegepast, zijn EJB's nog steeds populair in bedrijfsomgevingen, en in dit korte voorbeeld hebben we laten zien dat het mogelijk is om gebruik te maken van zowel de gedistribueerde voordelen van Jakarta EE als het gebruiksgemak van Spring-applicaties.

Zoals altijd is de code te vinden op GitHub.