
![[8.5.5.6 oder höher]](../ng_v8556.gif)
JAX-RS 2.0-Integration mit EJB und CDI
Enterprise JavaBeans (EJB) und Contexts and Dependency Injection (CDI) können in JAR-RS 2.0 in Liberty integriert werden.
Damit JAX-RS 2.0 für Enterprise-Beans funktioniert, müssen Sie die Annotation @Path für die Klasse einer Bean verwenden und sie in eine Stammressourcenklasse konvertieren.
Wenn Sie EJB integrieren, können Sie die Enterprise JavaBeans mit Annotationen versehen und sie als REST-Endpunkte zugänglich machen. Sie können auch die JTA und die Sicherheitsfunktionen von EJB verwenden. JAX-RS 2.0 in Liberty unterstützt die Verwendung von statusunabhängigen und Singleton-Session-Beans als Stammressourcenklassen, Provider und Anwendungsunterklassen. Wenn Sie CDI integrieren, können Sie CDI-Beans oder Managed Beans als REST-Endpunkte annotieren und CDI für Web-Services nutzen. JAX-RS 2.0 in Liberty unterstützt Beans nach CDI-Art als Stammressourcenklassen, Provider und Anwendungsunterklassen. Provider und Anwendungsunterklassen müssen Singletons sein oder den Anwendungsbereich verwenden. Die CDI-Spezifikation vereinfacht die Integration von Java™-EE-Komponenten verschiedener Arten. Sie stellt einen allgemeinen Mechanismus für das Injizieren von Komponenten wie EJBs oder Managed Beans in andere Komponenten, z. B. in JSPs oder EJBs, bereit.
- Verwenden Sie für eine Stateless Session-Bean die Annotation @Stateless
wie im folgenden Beispiel:
@Stateless @Path("stateless-bean") public class StatelessResource {...}
- Verwenden Sie für eine Singleton-Bean die Annotation @Singleton
wie im folgenden Beispiel:
@Singleton @Path("singleton-bean") public class SingletonResource {...}
@ApplicationScoped
@Path("/ApplicationScopedResource")
public class ApplicationScopedResource {
private @Inject
SimpleBean injected;
...
}
Einschränkungen in JAX-RS 2.0 mit EJB und CDI
Nachfolgend sind die Einschränkungen für JAX-RS 2.0 in Liberty aufgeführt:
- Wenn Sie EJB als JAX-RS-Ressource, -Provider oder -Anwendung verwenden, können Sie @Context nicht in den Konstruktor der Enterprise JavaBean injizieren. Dies liegt daran, dass die EJB mit Standardkonstruktor nur gemäß der EJB- und der JAX-RS-Spezifikation für JAX-RS verwendet werden kann.
- Wenn Sie die EJB- oder CDI-Annotation in einer Java-Klasse verwenden, das Liberty-Feature für EJB (z. B. ejbLite-3.2) oder CDI (z. B. cdi-1.0) aber nicht in der Datei server.xml konfiguriert ist, gibt es keine EJB- oder CDI-Unterstützung in der Liberty-Laufzeitumgebung, sodass die JAX-RS-2.0-Engine die Java-Klasse als POJO-Klasse verwendet.
- Wenn eine Anwendungsklasse keine Schnittstelle implementiert oder mit der Annotation
@Localbean versehen ist, wird sie als EJB betrachtet. Implementiert die Anwendungsklasse lokale oder
POJO-Schnittstellen, wird sie nicht als EJB betrachtet.
- Provider:
- Wenn eine Klasse POJO-Providerschnittstellen ausschließlich ohne die Annotation @Local implementiert, wird sie als gültiger EJB-Provider betrachtet.
- Wenn eine Klasse mit der Annotation @LocalBean versehen ist und die POJO-Providerschnittstelle implementiert, wird sie als gültiger EJB-Provider betrachtet.
- Wen eine Klasse die lokale Schnittstelle mit der Annotation @Local hat, ist die lokale Schnittstelle eine Providerschnittstelle. Implementiert diese Klasse die Providerschnittstelle, ist sie ein gültiger EJB-Provider.
- Wen eine Klasse eine lokale Schnittstelle mit der Annotation @Local hat und die lokale Schnittstelle keine Providerschnittstelle ist,
ist die Klasse kein gültiger Provider.
Dies liegt daran, dass der EJB-Container in diesem Fall nur einen EJB-Stub für die lokale Schnittstelle und nicht für die POJO-Providerschnittstelle generieren kann.
- Wenn eine Klasse nur mit der Annotation @Local versehen ist, die auf eine Providerschnittstelle verweist, diese Providerschnittstelle jedoch nicht implementiert, ist die Klasse gemäß der Spezifikation JAX-RS 2.0 kein gültiger Provider. In der Spezifikation heißt es: Ein Provider ist eine Klasse, die JAX-RS-Schnittstellen implementiert, die in dieser Spezifikation beschrieben sind und zur automatischen Erkennung mit der Annotation @Provider versehen werden können.
- Ressourcen:
- Wenn eine EJB-basierte Ressource keine Schnittstelle implementiert, sind alle in dieser Klasse deklarierten Methoden als JAX-RS-Ressourcen verfügbar.
- Wenn eine EJB-basierte Ressource eine Schnittstelle (lokal oder POJO) implementiert, sind alle in dieser Schnittstelle deklarierten Methoden als JAX-RS-Ressourcen verfügbar.
- Wenn eine EJB-basierte Ressource mehrere Schnittstellen implementiert,
- Wenn alle Schnittstellen POJO-Schnittstellen ohne die Annotation @Local sind, sind alle in der Schnittstelle deklarierten Methoden als JAX-RS-Ressourcen verfügbar.
- Wenn alle Schnittstellen lokale Schnittstellen mit der Annotation @Local sind, sind alle in der Schnittstelle deklarierten Methoden als JAX-RS-Ressourcen verfügbar.
- Wenn einige Schnittstellen lokale Schnittstellen mit der Annotation @Local sind und eine keine lokalen Schnittstellen sind, sind nur in den lokalen Schnittstellen deklarierte Methoden als JAX-RS-Ressourcen verfügbar. Dies liegt daran, dass der EJB-Container in diesem Szenario nur einen EJB-Stub für lokale Schnittstellen generieren kann.
- Wenn die EJB-basierte Ressource mit der Annotation @LocalBean versehen ist, sind alle in der Klasse deklarierten Methoden als JAX-RS-Ressourcen verfügbar.
- Wenn eine EJB-basierte Ressource eine Schnittstelle implementiert, muss die JAX-RS-Ressourcenmethode in der Schnittstelle deklariert sein. Ist die Schnittstelle ein Provider, der nicht modifiziert werden kann, müssen Sie eine neue Schnittstelle für die Ressourcenklasse erstellen, um die Ressourcenmethode hinzuzufügen. Andernfalls wird sie nicht als EJB-Ressource betrachtet.
- Provider:
- Wenn eine Ressourcenklasse mit der Annotation @Path eine JAX-RS-Providerschnittstelle implementiert oder mit der Annotation @Provider deklariert, funktioniert diese Klasse als Ressource und als Provider. Die JAX-RS-2.0-Engine verwendet in diesem Fall standardmäßig nur die Instanz dieser Klasse, die von der Ressource und dem Provider gemeinsam genutzt wird. Der Lebenszyklus der Instanz ist ein Singleton.
- Wenn eine Klasse in den Methoden getClasses und getSingletons der Anwendungsklasse registriert ist, verwendet die JAX-RS-2.0-Engine standardmäßig die Instanz der Methode getSingletons und ignoriert die Registrierung in der Methode getClasses.
- Wenn eine REST-konforme Ressource gleichzeitig eine CDI-verwaltete Bean mit dem Bereich javax.enterprise.context.Dependent ist, kann die Methode PreDestroy aufgrund der CDI-Beschränkung nicht aufgerufen werden.
Asynchrone Verarbeitung
Sie können das asynchrone Verarbeitungsverfahren in JAX-RS 2.0 verwenden, um Threads zu verarbeiten. Die asynchrone Verarbeitung wird sowohl von der Client-API als auch von der Server-API unterstützt. Weitere Informationen zur asynchronen Verarbeitung finden Sie in Kapitel 8 von JSR-339 Java API for RESTful ("Spezifikation").
Der folgende Code veranschaulicht die asynchrone Verarbeitung in der Client-API:
Client client = ClientBuilder.newClient();
WebTarget target = client.target("http://example.org/customers/{id}");
target.resolveTemplate("id", 123).request().async().get(
new InvocationCallbackCustomer() {
@Override
public void completed(Customer customer) {
// Aktionen ausführen...
}
@Override
public void failed(Throwable throwable) {
// Fehler verarbeiten
}
});
Der folgende Code veranschaulicht die asynchrone Verarbeitung in der Server-API:
@Path("/async")
public class MyResource{
@GET
public void getAsync(@Suspended final AsyncResponse asyncResponse){
CompletionCallback callBack = new CompletionCallback(){
@Override
public void onComplete(Throwable throwable) {
...
}
};
asyncResponse.register(callBack);
asyncResponse.resume("some Response");
}
}
@Stateless
@Path("/")
class EJBResource {
@GET @Asynchronous
public void longRunningOp(@Suspended AsyncResponse ar) {
executeLongRunningOp();
ar.resume("Hello async world!");
}
}
Ein explizites Thread-Management ist in diesem Fall nicht nötig, weil es vom EJB-Container gesteuert wird. Die Antwort wird erzeugt, indem für die
injizierte AsyncResponse "resume" aufgerufen wird. Der Rückgabetyp von longRunningOp ist daher "void".Lebenszyklus von JAX-RS-2.0-Beans und Enterprise JavaBeans
Anwendung | JAX-RS 2.0 | EJB | Ergebnis |
---|---|---|---|
Ressource | perRequest | Stateless | Stateless |
perRequest | Singleton | Singleton | |
Singleton | Stateless | Stateless | |
Singleton | Singleton | Singleton | |
Provider | Singleton | Stateless | Stateless |
Singleton | Singleton | Singleton |
Lebenszyklus des Bereichs für JAX-RS 2.0 und für CDI
Anwendung | Bereich für JAX-RS 2.0 | Bereichsannotation für CDI | Ergebnis |
---|---|---|---|
Ressource | perRequest | @ApplicationScoped | Singleton |
perRequest | @RequestScoped | perRequest | |
perRequest | @Dependent | perRequest | |
perRequest | @SessionScoped | Session | |
perRequest | perRequest | ||
Singleton | @ApplicationScoped | Singleton | |
Singleton | @RequestScoped | perRequest | |
Singleton | @Dependent | Singleton | |
Singleton | @SessionScoped | Session | |
Singleton | Singleton | ||
Provider | Singleton | @ApplicationScoped | Singleton |
Singleton | @RequestScoped | Singleton | |
Singleton | @Dependent | Singleton | |
Singleton | @SessionScoped | Singleton | |
Singleton | Singleton |
Nachrichten bei einem Konflikt des Bereichslebenszyklus von JAX-RS 2.0 und CDI
Wenn der Bereichslebenszyklus von JAX-RS 2.0 und CDI einen Konflikt erzeugt, werden die folgenden Warnungen angezeigt, die keine Aktionen erfordern.
Diese Nachricht wird angezeigt, wenn der JAX-RS-2.0-Ressourcenbereich nicht mit dem CDI-Bereich übereinstimmt und die Ressourceninstanz in CDI vorhanden ist, sodass Liberty die Ressourceninstanz aus CDI abruft. Wenn die Instanz aus JAX-RS stammt, schließt sie keine CDI-Injektion ein.CWWKW1001W: The scope {1} of JAXRS-2.0 Resource {0} does not match the CDI scope {2}. Liberty gets resource instance from {3}.
Diese Nachricht wird angezeigt, weil die Providerinstanz ein Singleton ist. Liberty ruft die Providerinstanz von CDI ab, wenn der Provider den Bereich Dependent oder ApplicationScoped hat. Wenn die Instanz aus JAX-RS stammt, schließt sie keine CDI-Injektion ein.CWWKW1002W: The CDI scope of JAXRS-2.0 Provider {0} is {1}. Liberty gets the provider instance from {2}.