Ich entwickle eine Anwendung mit Spring. Ich muss die @Service
Anmerkung verwenden. Ich habe ServiceI
und ServiceImpl
so das ServiceImpl implements ServiceI
. Ich bin hier verwirrt, wo ich die @Service
Anmerkung aufbewahren soll.
Soll ich die Schnittstelle oder die Implementierung mit kommentieren @Service
? Was sind die Unterschiede zwischen diesen beiden Ansätzen?
Antworten:
Ich habe nie
@Component
(oder@Service
...) an eine Schnittstelle gesetzt, weil dies die Schnittstelle unbrauchbar macht. Lassen Sie mich erklären, warum.Anspruch 1: Wenn Sie eine Schnittstelle haben, möchten Sie diese Schnittstelle für den Injektionspunkttyp verwenden.
Anspruch 2: Der Zweck einer Schnittstelle besteht darin, einen Vertrag zu definieren, der von mehreren Implementierungen implementiert werden kann. Auf der anderen Seite haben Sie Ihren Injektionspunkt (
@Autowired
). Nur eine Schnittstelle und nur eine Klasse zu haben, die sie implementiert, ist (IMHO) nutzlos und verstößt gegen YAGNI .Tatsache: Wenn Sie setzen:
@Component
(oder@Service
...) an einer Schnittstelle,dann erhalten Sie und
NoUniqueBeanDefinitionException
(oder Sie haben ein ganz spezielles Konfigurationssetup mit Umgebung, Profilen oder Qualifikationsmerkmalen ...)Schlussfolgerung: Wenn Sie an einer Schnittstelle
@Component
(oder@Service
...) verwenden, müssen Sie mindestens eine der beiden Clains verletzen. Daher denke ich, dass es nicht nützlich ist (mit Ausnahme einiger seltener Szenarien),@Component
auf Schnittstellenebene zu setzen .Spring-Data-JPA-Repository-Schnittstellen sind etwas völlig anderes
quelle
@Transactional
ist eines der Beispiele, bei denen ein Proxy für eine Bean verwendet wird. AOP ist eine andere.Grundsätzlich dienen Anmerkungen wie @Service , @Repository , @Component usw. demselben Zweck:
Aus meiner Erfahrung verwende ich immer
@Service
Annotationen auf den Schnittstellen oder abstrakten Klassen und Annotationen wie@Component
und@Repository
für deren Implementierung.@Component
Anmerkung, die ich für jene Klassen verwende, die grundlegenden Zwecken dienen, einfache Frühlingsbohnen, nichts weiter.@Repository
Anmerkung, die ich in derDAO
Ebene verwende, z. B. wenn ich mit der Datenbank kommunizieren muss, einige Transaktionen habe usw.Daher würde ich vorschlagen, Ihre Benutzeroberfläche
@Service
je nach Funktionalität mit den und anderen Ebenen zu versehen .quelle
Früher habe ich
@Component
,@Service
,@Controller
und@Repository
Annotationen nur auf den Implementierungsklassen und nicht auf der Schnittstelle. Aber die@Autowired
Annotation mit Interfaces hat bei mir immer noch funktioniert.quelle
Das Hinzufügen von Anmerkungen zu @Service hat den Vorteil, dass es einen Hinweis darauf gibt, dass es sich um einen Dienst handelt. Ich weiß nicht, ob eine implementierende Klasse diese Annoation standardmäßig erbt.
Der Nachteil ist, dass Sie Ihre Schnittstelle mit einem bestimmten Framework, z. B. Spring, koppeln, indem Sie eine federspezifische Anmerkung verwenden. Da Schnittstellen von der Implementierung entkoppelt werden sollen, würde ich nicht empfehlen, Framework-spezifische Anmerkungen oder Objektteile Ihrer Schnittstelle zu verwenden.
quelle
Ein Vorteil der Feder besteht darin, dass die Service- (oder andere) Implementierung einfach gewechselt werden kann. Dazu müssen Sie die Schnittstelle mit Anmerkungen versehen und die Variable wie folgt deklarieren:
und nicht :
Wie im ersten Fall können Sie die zu injizierende Implementierung ab dem Moment aktivieren, in dem sie eindeutig ist (nur eine Klasse implementiert die Schnittstelle). Im zweiten Fall müssen Sie Ihren gesamten Code umgestalten (die neue Klassenimplementierung hat einen anderen Namen). Infolgedessen muss sich die Anmerkung so weit wie möglich auf der Schnittstelle befinden. Darüber hinaus sind JDK-Proxys dafür gut geeignet: Sie werden beim Start der Anwendung erstellt und instanziiert, da der Laufzeittyp im Gegensatz zu CGlib-Proxys im Voraus bekannt ist.
quelle
@Service
einer Implementierung Anmerkungen machen und die Schnittstelle automatisch verdrahten. Spring sucht nach Objekten, die diese Schnittstelle implementieren.Ich würde
@Service
Ihre Klasse anlegen, aber den Namen der Schnittstelle als Parameter für die Anmerkung angeben, zAuf diese Weise erhalten Sie alle Vorteile und können die Schnittstelle trotzdem einspeisen, aber die Klasse erhalten
Ihre Schnittstelle ist also nicht an das Federgerüst gebunden, und Sie können die Klasse jederzeit ändern, ohne alle Injektionspunkte aktualisieren zu müssen.
Wenn ich also die Implementierungsklasse ändern wollte, konnte ich die neue Klasse einfach mit Anmerkungen versehen und aus der ersten entfernen, aber das ist alles, was geändert werden muss. Wenn Sie die Klasse injizieren, können Sie viel Arbeit haben, wann immer Sie die impl-Klasse ändern möchten.
quelle
Einfach gesagt:
@Service ist eine Stereotype-Annotation für die Service- Schicht.
@Repository ist ein Klischee Annotation für die Persistenz Schicht.
@Component ist eine generische stereotype Annotation, mit der Spring angewiesen wird , eine Instanz des Objekts im Anwendungskontext zu erstellen. Es ist möglich, einen beliebigen Namen für die Instanz zu definieren. Der Standardwert ist der Klassenname als Kamelfall.
quelle
Es gibt 5 Anmerkungen, die zur Herstellung von Frühlingsbohnen verwendet werden können. Liste der Antworten unten.
Benötigen Sie wirklich eine Schnittstelle? Wenn Sie für jede Serviceschnittstelle eine Implementierung haben möchten, vermeiden Sie diese einfach und verwenden Sie nur die Klasse. Natürlich, wenn Sie kein RMI haben oder wenn ein Schnittstellen-Proxy erforderlich ist.
@Repository - Zum Injizieren Ihrer Dao-Layer-Klassen.
@Service - Zum Einfügen Ihrer Service-Layer-Klassen. In der Service-Schicht müssen Sie möglicherweise auch die @ Transactional-Annotation für die Datenbank-Transaktionsverwaltung verwenden.
@Controller - Wird für Ihre Frontend-Layer-Controller verwendet, z. B. JSF-verwaltete Beans, die als Spring Beans injiziert werden.
@RestController - Wird für Federruhe-Steuerungen verwendet. Dies würde Ihnen helfen, jedes Mal zu vermeiden, dass @ResponseBody- und @RequestBody-Anmerkungen in Ihre Ruhemethoden eingefügt werden.
@Component - Verwenden Sie es in jedem anderen Fall, wenn Sie Spring Bean injizieren müssen, bei dem es sich nicht um eine Controller-, Service- oder Dao-Klasse handelt
quelle