Spring-Annotationen: @Component, @Repository, @Service – was ist der Unterschied?

Online Python-Trainer für Anfänger

Lernen Sie Python einfach ohne theoretische Überlastung. Lösen Sie praktische Aufgaben mit automatischer Überprüfung und schreiben Sie Code direkt im Browser.

Kurs starten

Einleitung: Warum gibt es in Spring drei Annotationen für dasselbe?

\n\n

Jeder, der mit Spring zu arbeiten begonnen hat, stellt sich früher oder später die Frage: "Warum braucht man drei verschiedene Annotationen – @Component, @Repository und @Service – wenn sie alle nur eine Bean im Kontext registrieren?".

\n\n

Diese Frage ist so beliebt, dass sie auf Stack Overflow tausende Aufrufe und Dutzende Antworten gesammelt hat. Und das ist kein Zufall. Auf den ersten Blick tun die Annotationen tatsächlich dasselbe. Aber der Teufel steckt, wie immer, im Detail.

\n\n

In diesem Artikel werden wir nicht einfach die Unterschiede auflisten. Wir werden die Philosophie von Spring analysieren, unter die Haube des Containers schauen und zeigen, wie die richtige Verwendung von Annotationen Ihr Projekt vor versteckten Bugs bewahren kann. Los geht's!

\n\n

Kurzer Crashkurs: Was sind stereotype Annotationen?

\n\n

Alle drei Annotationen gehören zu den sogenannten stereotypen Annotationen (stereotype annotations). Sie teilen Spring mit, dass die Klasse eine verwaltete Komponente (Bean) ist und beim Scannen des Classpaths automatisch gefunden werden soll.

\n\n

Die Basisannotation ist @Component. Sie ist das Fundament. @Repository, @Service und @Controller sind spezialisierte Formen von @Component, die zusätzliche Semantik und Verhalten hinzufügen.

\n\n
@Target(ElementType.TYPE)\n@Retention(RetentionPolicy.RUNTIME)\n@Documented\n@Component // Das ist der entscheidende Punkt!\npublic @interface Service {\n    // ...\n}
\n\n

Wie Sie sehen, ist @Service selbst mit @Component annotiert. Das bedeutet, dass Spring sie genauso behandelt wie ein normales @Component. Aber warum dann die Komplexität?

\n\n

@Component – der Allrounder

\n\n

@Component ist die allgemeinste Annotation. Verwenden Sie sie, wenn Ihre Klasse nicht in eine der spezifischeren Kategorien passt.

\n\n

Typische Beispiele:

\n
    \n
  • Hilfsprogramme (Utilities)
  • \n
  • Konfigurationsobjekte (nicht zu verwechseln mit @Configuration)
  • \n
  • Beliebige Klassen, die Beans sein sollen, aber keine Services, Repositories oder Controller sind
  • \n
\n\n
import org.springframework.stereotype.Component;\n\n@Component\npublic class EmailValidator {\n\n    public boolean isValid(String email) {\n        return email != null && email.contains("@");\n    }\n}
\n\n

Beachten Sie: EmailValidator führt keine Geschäftslogik aus (es ist kein @Service) und arbeitet nicht mit der Datenbank (es ist kein @Repository). Daher ist @Component die ideale Wahl.

\n\n

@Repository – der Hüter der Daten

\n\n

@Repository ist die erste spezialisierte Annotation, die echte Funktionalität hinzufügt. Neben der Bean-Registrierung erfüllt sie zwei wichtige Aufgaben:

\n\n
    \n
  1. Abfangen von Datenzugriffsausnahmen. Spring verpackt Ausnahmen von DAOs (Data Access Objects) automatisch in DataAccessException – die Ausnahmehierarchie von Spring.
  2. \n
  3. Verbesserung der Lesbarkeit des Codes. Jeder Entwickler, der @Repository sieht, versteht sofort: "Aha, hier wird mit der Datenbank gearbeitet".
  4. \n
\n\n
import org.springframework.stereotype.Repository;\nimport org.springframework.data.jpa.repository.JpaRepository;\n\n@Repository\npublic interface UserRepository extends JpaRepository<User, Long> {\n\n    User findByEmail(String email);\n}
\n\n

Wichtig: Wenn Sie Spring Data JPA verwenden und von JpaRepository erben, erstellt Spring selbst eine Proxy-Bean. Die explizite Annotation @Repository ist nicht zwingend erforderlich, wird aber zur klaren Angabe des Zwecks empfohlen.

\n\n

Das Hauptmerkmal von @Repository ist der AOP-Interceptor (PersistenceExceptionTranslationPostProcessor)

Blogs

Buchempfehlungen