it-swarm.com.de

Wo soll die @Service-Annotation aufbewahrt werden? Schnittstelle oder Implementierung?

Ich entwickle eine Anwendung mit Spring. Ich muss die Annotation @Service verwenden. Ich habe ServiceI und ServiceImpl, so dass ServiceImpl implements ServiceI. Ich bin hier verwirrt, wo ich die @Service-Anmerkung aufbewahren sollte.

Soll ich die Schnittstelle oder die Implementierung mit @Service versehen? Was sind die Unterschiede zwischen diesen beiden Ansätzen?

82
TheKojuEffect

Grundlegende Anmerkungen wie @Service , @Repository , @Component usw. dienen alle demselben Zweck: 

autoerkennung bei Annotation-basierter Konfiguration und Klassenpfad Scannen.

Aus meiner Erfahrung verwende ich immer @Service Annotation auf den Schnittstellen oder abstrakten Klassen und Annotationen wie @Component und @Repository für ihre Implementierung. @Component-Anmerkung Ich verwende diese Klassen, die einfachen Zwecken dienen, einfache Spring-Beans, nichts weiter. @Repository-Anmerkung, die ich in der DAO-Schicht verwende, z. Wenn ich mit der Datenbank kommunizieren muss, haben Sie einige Transaktionen usw.

Daher würde ich vorschlagen, Ihre Schnittstelle je nach Funktionalität mit dem @Service und anderen Schichten zu kommentieren.

30

Ich habe niemals @Component (oder @Service, ...) an eine Schnittstelle gesetzt, weil dies die Schnittstelle unbrauchbar macht. Lass mich erklären warum.

Anspruch 1: Wenn Sie über eine Schnittstelle verfügen, möchten Sie diese Schnittstelle für den Injektionsstellentyp verwenden.

Anspruch 2: Eine Schnittstelle dient dazu, einen Vertrag zu definieren, der von mehreren Implementierungen implementiert werden kann. Auf der anderen Seite haben Sie Ihre Injektionsstelle (@Autowired). Nur eine Schnittstelle und nur eine Klasse zu implementieren, ist (IMHO) nutzlos und verstößt gegen YAGNI .

fact: Wenn Sie setzen:

  • @Component (oder @Service, ...) an einer Schnittstelle,
  • haben mehrere Klassen, die es implementiert,
  • mindestens zwei Klassen werden zu Spring Beans und
  • einen Einspritzpunkt haben, der die Schnittstelle für die typbasierte Einspritzung verwendet, 

dann erhalten Sie und NoUniqueBeanDefinitionException (oder Sie haben eine sehr spezielle Konfigurationseinstellung mit Umgebung, Profilen oder Qualifikatoren ...) 

Fazit: Wenn Sie an einer Schnittstelle @Component (oder @Service, ...) verwenden, müssen Sie mindestens eine der beiden Klauseln verletzen. Daher halte ich es für nicht sinnvoll (mit Ausnahme einiger seltener Szenarien), @Component auf Schnittstellenebene zu setzen.


Spring-Data-JPA-Repository-Schnittstellen sind etwas völlig anderes

85
Ralph

Ich habe die Annotationen @Component, @Service, @Controller und @Repository nur für die Implementierungsklassen und nicht für die Schnittstelle verwendet. @Autowired Annotation with Interfaces hat aber trotzdem für mich funktioniert. 

11
yalkris

Ein Vorteil von Annotation bei @Service ist der Hinweis, dass es sich um einen Dienst handelt. Ich weiß nicht, ob eine implementierende Klasse diese Annoation standardmäßig erbt.

Con Seite ist, dass Sie Ihre Schnittstelle mit einem bestimmten Rahmen, d. H. Spring, koppeln, indem Sie die federabhängige Annotation verwenden. Da Schnittstellen von der Implementierung entkoppelt werden sollen, würde ich nicht die Verwendung von gerüstspezifischen Anmerkungen oder Objektteilen Ihrer Schnittstelle vorschlagen.

5
Kuldeep Tiwari

Ein Vorteil von spring ist das einfache Umschalten der Implementierung von Services (oder anderer). Dazu müssen Sie die Schnittstelle kommentieren und eine Variable wie folgt deklarieren:

@Autowired
private MyInterface myVariable;

und nicht :

@Autowired
private MyClassImplementationWhichImplementsMyInterface myVariable;

Wie im ersten Fall können Sie aktivieren, welche Implementierung von dem Moment an, an dem sie eindeutig ist (nur eine Klasse implementiert die Schnittstelle), eingefügt wird .. Im zweiten Fall müssen Sie den gesamten Code umgestalten (die neue Klassenimplementierung hat einen anderen Namen) Die Annotation muss sich daher so viel wie möglich auf der Schnittstelle befinden. Darüber hinaus sind JDK-Proxies dafür gut geeignet: Sie werden beim Start der Anwendung erstellt und instanziiert, da der Laufzeit-Typ im Gegensatz zu CGlib-Proxies vorab bekannt ist.

1
François F.

Einfach gesagt:

@Service ist eine Stereotypanmerkung für die service -Schicht.

@Repository ist eine Stereotyp-Annotation für die PersistenzSchicht.

@Component ist eine generische - Stereotypanmerkung, mit der Spring aufgefordert wird, eine Instanz des Objekts im Anwendungskontext zu erstellen. Es ist möglich, Definieren Sie einen beliebigen Namen für die Instanz. Der Standardname ist der Klassenname als Kamelfall.

0
HughParker