Funktionsprinzip von JAX-RS MessageBodyWriter


#1

Hallo,
ich bin vor kurzem auf den JAX-RS MessageBodyWriter gestoßen. Nun hat sich mir die Frage gestellt, wie funktioniert das System um den MessageBodyWriter?

Als Entwickler kann ich einer Klasse erstellen, welche das MessageBodyWriter Interface enthält. Dann “registriere” ich die Klasse mittels @Provider irgendwo und geb mittels @Produces("…") einen Typ an. OK, soweit sogut. Aber was passiert im Hintergrund? Woher weiß meine Applikation, das meine neu erstellte Klasse jetzt die Annotation “@Provider” beinhaltet und bei der Suche nach dem richtigen MessageBodyWriter mit berücksichtigt werden muss?

Könnte mir bitte jemand die Funktionsweise erkäutern?

Danke!
Grüße Hans


#2

Der Container scannt alle Klassen und identifiziert diese per Annotation. Wenn Du Deine App also in einem Wildfly startest, sorgt der Server dafür, dass die entsprechenden Klassen in der App bekannt sind.

Beantwortet dies Deine Frage?


#3

Von der groben Theorie her beantwortet das meine Frage.
Ich würde das zum Verständnis aber gerne einmal mit einer eigenen Annotation aufbauen/nachbauen wollen.

Im Grunde müsste ich dann mit einem Classpath-Scan erst einmal alle möglichen Klassen nach meiner Annotation absuchen, um mir dann die zu merken, welche mich interessieren. Dann müsste ich bei der Verarbeitung auf die im Programm gemerkten Klassen zugreifen um zu prüfen, welche annotierte Klasse im Einzelfall relevant ist? Oder gibt es auch einen Weg ohne einen full classpath scan? Ich bin jetzt kein Java-Experte, aber ich könnte mir vorstellen, das so ein full classpath scan doch recht viel Zeit in Anspruch nimmt.


#4

Einen vollständigen Scan kann man nur vermeiden, wenn man die Klassen registriert. Das kann man über Konfigurationsdateien machen (z. B. ServiceLoader / ServiceProvider) oder über Konfigurationsannotationen / Konfigurationsklassen mit denen man die Services angibt. Außerdem kann man, wie bei AppServern üblich, bestimmte Klassenpfade oder Jars ausschließen.

Ein Scan des Classpath hat übrigens auch zur Folge, dass statische Initialisatoren aufgerufen werden. Das verbraucht Zeit und Speicher und kann im ungünstigsten Fall zu Seiteneffekten führen.


#5

Wie cmrudolph schon geschrieben hat.

Hier ist zum Beispiel beschrieben wie das bei Jax-RS aussieht.

https://docs.oracle.com/javaee/7/tutorial/jaxrs002.htm

Speziell 29.2.7