Quelle est la différence entre les annotations @Component, @Repository et @Service au printemps?


2105

Can @Component, @Repositoryet les @Serviceannotations sont utilisés de façon interchangeable au printemps ou ils fournissent une fonctionnalité particulière en plus d' agir en tant que dispositif de notation?

En d'autres termes, si j'ai une classe Service et que je change l'annotation de @Serviceen @Component, est-ce qu'elle se comportera toujours de la même manière?

Ou l'annotation influence-t-elle également le comportement et la fonctionnalité de la classe?


8
En tant que développeur ayant des antécédents Microsoft, je me souviens de la définition sémantique des services dans l'ancien cadre MS SmartClientSoftwareFactory (désormais un cadre complexe obsolète pour les applications de bureau distribuées). Cette définition ( bien documentée par Rich Newman) définissait les services comme des objets réutilisables sans état, de préférence avec une portée singleton, qui sont utilisés pour effectuer des opérations de logique métier sur d'autres objets passés en arguments. J'ai tendance à voir les services du printemps de la même manière
Ivaylo Slavov

3
Peu importe !! Tout ce qui fonctionne pour vous :) J'ai toujours détesté cela à propos de Spring, car ils ont toujours tendance à définir des "règles" pour vous, ce qui n'ajoute qu'une valeur triviale à votre application. Sans oublier que Spring est livré avec une énorme pile qui lui est propre.
TriCore

30
@TriCore Sprting est un framework, définir des "règles" pour vous c'est son métier :)
Walfrat

Réponses:


1503

De la documentation Spring :

L' @Repositoryannotation est un marqueur pour toute classe qui remplit le rôle ou le stéréotype d'un référentiel (également appelé objet d'accès aux données ou DAO). Parmi les utilisations de ce marqueur se trouve la traduction automatique des exceptions, comme décrit dans la traduction des exceptions .

Spring fournit des annotations plus stéréotypées: @Component, @Serviceet @Controller. @Componentest un stéréotype générique pour tout composant géré par Spring. @Repository,, @Serviceet @Controllersont des spécialisations de @Componentpour des cas d'utilisation plus spécifiques (dans les couches de persistance, de service et de présentation, respectivement). Par conséquent, vous pouvez annoter vos classes de composants avec @Component, mais, en les annotant avec @Repository, @Serviceou à la @Controller place, vos classes sont plus adaptées au traitement par des outils ou à l'association avec des aspects.

Par exemple, ces annotations de stéréotypes constituent des cibles idéales pour les coupes de points. @Repository, @Serviceet @Controllerpeut également contenir des sémantiques supplémentaires dans les futures versions de Spring Framework. Ainsi, si vous choisissez entre utiliser @Componentou @Servicepour votre couche de service, @Servicec'est clairement le meilleur choix. De même, comme indiqué précédemment, @Repositoryest déjà pris en charge comme marqueur pour la traduction automatique des exceptions dans votre couche de persistance.

┌──────────────┬─────────────────────────────────────────────────────┐
 Annotation    Meaning                                             
├──────────────┼─────────────────────────────────────────────────────┤
  @Component   generic stereotype for any Spring-managed component 
  @Repository  stereotype for persistence layer                    
  @Service     stereotype for service layer                        
  @Controller  stereotype for presentation layer (spring-mvc)      
└──────────────┴─────────────────────────────────────────────────────┘

6
Serait-il judicieux d'ajouter @Controller (ou @Component) à un @WebServlet? Ce n'est pas un contrôleur Spring MVC, mais c'est la correspondance conceptuellement la plus proche. Qu'en est-il des filtres de servlet?
Rick

1
"@Repository est déjà pris en charge comme marqueur pour la traduction automatique des exceptions dans votre couche de persistance." signifier?
Jack

9
Cela fait référence au fait que ces annotations sont de bonnes cibles pour AOP, et bien que les autres annotations ne définissent pas encore de point, elles pourraient le faire à l'avenir. D'un autre côté, @Repository est déjà une cible pour un pointcut actuellement. Ce point est utilisé pour les traductions d'exceptions, c'est-à-dire la traduction d'exceptions spécifiques à la technologie à des exceptions plus génériques basées sur Spring, pour éviter un couplage serré.
stivlo

3
@stivlo: J'ai vraiment essayé de comprendre le terme «stéréotype», je ne comprends toujours pas. Pourriez-vous m'aider à comprendre cette terminologie? Cela aide beaucoup et merci beaucoup
Premraj

2
@xenoterracide Il n'y a pratiquement pas beaucoup de différence. Quelque chose annoté avec @Service est aussi un @Component(car l' @Serviceannotation elle-même est annotée avec @Component). Pour autant que je sache, rien dans le cadre de Spring n'utilise explicitement le fait que quelque chose est un @Service, donc la différence n'est vraiment que conceptuelle.
Jesper

802

Comme de nombreuses réponses indiquent déjà à quoi servent ces annotations, nous nous concentrerons ici sur quelques différences mineures entre elles.

D'abord la similitude

Le premier point à souligner de nouveau est qu'en ce qui concerne la détection automatique de scan et l'injection de dépendances pour BeanDefinition, toutes ces annotations (à savoir, @Component, @Service, @Repository, @Controller) sont les mêmes. Nous pouvons en utiliser un à la place d'un autre et nous pouvons toujours nous déplacer.


Différences entre @Component, @Repository, @Controller et @Service

@Composant

Il s'agit d'une annotation de stéréotype à usage général indiquant que la classe est un composant ressort.

La particularité de @Component
<context:component-scan> analyse uniquement@Componentet ne recherche pas@Controller,@Serviceet@Repositoryen général. Ils sont scannés car ils sont eux-mêmes annotés@Component.

Il suffit de jeter un oeil à @Controller, @Serviceet les @Repositorydéfinitions d'annotation:

@Component
public @interface Service {
    ….
}

 

@Component
public @interface Repository {
    ….
}

 

@Component
public @interface Controller {
    
}

Ainsi, il n'est pas faux de dire cela @Controller, @Serviceet ce @Repositorysont des types spéciaux d' @Componentannotation. <context:component-scan>les récupère et enregistre leurs classes suivantes en tant que beans, comme si elles étaient annotées avec @Component.

Les annotations de type spécial sont également analysées, car elles-mêmes sont annotées avec des @Componentannotations, ce qui signifie qu'elles sont également des @Components. Si nous définissons notre propre annotation personnalisée et l'annotons avec @Component, elle sera également analysée avec<context:component-scan>


@Dépôt

Ceci indique que la classe définit un référentiel de données.

Quelle est la particularité de @Repository?

En plus de souligner qu'il s'agit d'une configuration basée sur des annotations , @Repositoryle travail consiste à intercepter les exceptions spécifiques à la plate-forme et à les renvoyer comme l'une des exceptions unifiées non contrôlées de Spring. Pour cela, nous sommes fournis avec PersistenceExceptionTranslationPostProcessor, que nous sommes tenus d'ajouter dans notre contexte d'application de Spring comme ceci:

<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>

Ce post-processeur de bean ajoute un conseiller à tout bean annoté @Repositoryafin que toutes les exceptions spécifiques à la plate-forme soient interceptées puis renvoyées comme l'une des exceptions d'accès aux données non contrôlées de Spring.


@Manette

L' @Controllerannotation indique qu'une classe particulière joue le rôle d'un contrôleur. L' @Controllerannotation agit comme un stéréotype pour la classe annotée, indiquant son rôle.

Quelle est la particularité de @Controller?

Nous ne pouvons pas changer cette annotation avec une autre comme @Serviceou @Repository, même si elles se ressemblent. Le répartiteur analyse les classes annotées @Controlleret détecte les méthodes annotées avec des @RequestMappingannotations en leur sein. Nous pouvons utiliser @RequestMappingle / uniquement dans les méthodes dont les classes sont annotés avec @Controlleret il sera PAS travailler avec @Component, @Service, @Repositoryetc ...

Remarque: Si une classe est déjà enregistrée en tant que bean via une autre méthode, comme les annotations through @Beanou through @Component, @Serviceetc ..., elle @RequestMappingpeut être sélectionnée si la classe est également annotée avec @RequestMappingannotation. Mais c'est un scénario différent.


@Un service

@Service Les beans contiennent la logique métier et les méthodes d'appel dans la couche de référentiel.

Quelle est la particularité de @Service?

Mis à part le fait qu'il est utilisé pour indiquer, qu'il détient la logique métier, il n'y a rien d'autre visible dans cette annotation; mais qui sait, le printemps pourrait ajouter d'autres exceptionnels à l'avenir.


Quoi d'autre?

Similaire ci - dessus, dans le futur printemps peut ajouter des fonctionnalités spéciales pour @Service, @Controlleret en @Repositoryfonction de leurs conventions de stratification. Par conséquent, c'est toujours une bonne idée de respecter la convention et de l'utiliser en ligne avec les calques.


'PersistenceExceptionTranslationPostProcessor' sera automatiquement enregistré si JPA est détecté.
Olga

21
Explication fantastique. Vous avez dissipé beaucoup de mes malentendus. Venant d'une université où nous avons construit tous nos projets de bas en haut, j'ai eu du mal à comprendre pourquoi Spring Applications fonctionnait tout simplement même si vous ne liez pas explicitement le programme vous-même. Les annotations ont beaucoup de sens maintenant, merci!
NodziGames

Alors, que signifie l'annotation @Service pour Hibernate (couche de persistance), outre la fonctionnalité DI, qu'en est-il du proxy de couche de persistance pour la récupération et le mappage d'une sorte d'entité vers le DTO respectif? Cette couche est très importante pour le dynamisme de la couche Persistance. Si quelqu'un sait profondément comment cela affecte JPA, ce serait très très utile)))
Musa

1
Il y a quelques petites informations erronées sur l' @Controllerannotation. Il n'est pas requis si la classe est annotée avec @RequestMappinget que le bean de cette classe est créé de quelque manière que ce soit. Tout bean annoté avec @Controller OR @RequestMapping participera aux mappages de demandes de Spring MVC. Cela peut être utile, par exemple, pour créer des contrôleurs par programmation (par exemple en utilisant des @Beanméthodes) et en même temps pour empêcher Spring d'essayer de les créer par analyse de package (si le package ne peut pas être exclu de l'analyse).
Ruslan Stelmachenko

1
cela devrait être la réponse la mieux notée - répond à toutes les questions et va assez loin. @stivlo n'a pas beaucoup expliqué la première question OP - les différences techniques.
kiedysktos

430

Ils sont presque les mêmes - tous signifient que la classe est un haricot de printemps. @Service, @RepositoryEt @Controllersont spécialisés @Components. Vous pouvez choisir d'effectuer des actions spécifiques avec eux. Par exemple:

  • @Controller les haricots sont utilisés par spring-mvc
  • @Repository les beans sont éligibles pour la traduction d'exception de persistance

Une autre chose consiste à désigner sémantiquement les composants sur différentes couches.

Une chose qui @Componentoffre est que vous pouvez annoter d'autres annotations avec lui, puis les utiliser de la même manière que @Service.

Par exemple récemment j'ai fait:

@Component
@Scope("prototype")
public @interface ScheduledJob {..}

Ainsi, toutes les classes annotées @ScheduledJobsont des haricots de printemps et, en plus de cela, sont enregistrées comme emplois de quartz. Il vous suffit de fournir du code qui gère l'annotation spécifique.


1
@Component signifie un haricot à ressort uniquement, y a-t-il un autre but?
kapil

21
Les grains @Component sont détectables automatiquement par le conteneur à ressort. Vous n'avez pas besoin de définir le bean dans le fichier de configuration, il sera automatiquement détecté au moment de l'exécution d'ici Spring.
Akash5288

1
J'aime beaucoup le @Component générique ... surtout en combo avec @Scope (proxyMode = ScopedProxyMode.//MODE)
Eddie B

366

@Component est équivalent à

<bean>

@Service, @Controller, @Repository = {@Component + quelques fonctionnalités plus spéciales}

Cela signifie que le service, le contrôleur et le référentiel sont identiques sur le plan fonctionnel.

Les trois annotations sont utilisées pour séparer les "couches" dans votre application,

  • Les contrôleurs font juste des choses comme la répartition, le transfert, les méthodes de service d'appel, etc.
  • Service Hold Logic, calculs, etc.
  • Le référentiel sont les DAO (Data Access Objects), ils accèdent directement à la base de données.

Maintenant, vous pouvez demander pourquoi les séparer: (Je suppose que vous connaissez la programmation orientée AOP)

Supposons que vous souhaitiez surveiller l'activité du calque DAO uniquement. Vous allez écrire une classe Aspect (classe A) qui effectue une journalisation avant et après que chaque méthode de votre DAO soit invoquée, vous pouvez le faire en utilisant AOP car vous avez trois couches distinctes et n'êtes pas mélangées.

Vous pouvez donc faire la journalisation de DAO "autour", "avant" ou "après" les méthodes DAO. Vous pourriez le faire parce que vous aviez un DAO en premier lieu. Ce que vous venez de réaliser, c'est la séparation des préoccupations ou des tâches.

Imaginez s'il n'y avait qu'une seule annotation @Controller, alors ce composant aura la répartition, la logique métier et l'accès à la base de données tous mélangés, donc du code sale!

Ce qui est mentionné ci-dessus est un scénario très courant, il existe de nombreux autres cas d'utilisation pour lesquels utiliser trois annotations.


7
J'ai une question fondamentale - les annotations sont-elles utilisées par le mécanisme à ressort ou sont-elles juste pour que le programmeur se souvienne de ce que font ces morceaux de code?
user107986

26
@ user107986 Il s'agit principalement pour le programmeur de se souvenir des couches dans l'application. Cependant a @Respositoryégalement une fonction de traduction d'exception automatique. Comme lorsqu'une exception se produit dans un, @Repositoryil existe généralement un gestionnaire pour cette exception et il n'est pas nécessaire d'ajouter des blocs try catch dans la classe DAO. Il est utilisé avec PersistenceExceptionTranslationPostProcessor
Oliver

pouvez-vous s'il vous plaît écrire un exemple de code comment écrire un Joint points pour toute la classe "@Repository". Soit nous utilisons des expressions, soit le nom du bean, mais comment dire que ce conseil s'appliquera à toutes les classes "@Repository". J'essayais d'en obtenir un exemple mais je n'ai pas pu le trouver. Votre aide est vraiment appréciée.
Moni

De plus, bien que les annotations fonctionnent actuellement toutes de la même manière, il est possible que des fonctionnalités spécifiques pour un attribut donné soient ajoutées à l'avenir.
Cod3Citrus

224

Au printemps @Component, @Service, @Controlleret @Repositorysont des annotations Stéréotype qui sont utilisés pour:

@Controller:où votre mappage de demande à partir de la page de présentation est fait, c'est-à-dire que la couche de présentation n'ira pas vers un autre fichier, il va directement à la @Controllerclasse et vérifie le chemin demandé dans l' @RequestMappingannotation qui a été écrit avant les appels de méthode si nécessaire.

@Service: Toute la logique métier est ici, c'est-à-dire les calculs liés aux données et tout. Cette annotation de la couche métier dans laquelle notre utilisateur n'appelle pas directement la méthode de persistance donc il appellera cette méthode en utilisant cette annotation. Il demandera @Repository selon la demande de l'utilisateur

@Repository: Il s'agit de la couche de persistance (couche d'accès aux données) de l'application qui permet d'obtenir les données de la base de données. c'est-à-dire que toutes les opérations liées à la base de données sont effectuées par le référentiel.

@Component - Annotez vos autres composants (par exemple les classes de ressources REST) ​​avec un stéréotype de composant.

Indique qu'une classe annotée est un " composant ". Ces classes sont considérées comme des candidats à la détection automatique lors de l'utilisation de la configuration basée sur des annotations et de l'analyse du chemin de classe.

D'autres annotations au niveau de la classe peuvent également être considérées comme identifiant un composant, généralement un type spécial de composant: par exemple l'annotation @Repository ou l'annotation @Aspect d'AspectJ.

entrez la description de l'image ici


24
ces réponses sont toutes agréables et toutes, mais je suis presque sûr que ce que la plupart d'entre nous voulons, ce sont des exemples de code des fonctionnalités que des composants comme le service offre que nous pouvons mettre plus concrètement en tête plutôt qu'une simple description générale comme la "logique métier". cet objet. sinon, nous supposons toujours "oh c'est super et tout, mais je peux toujours appliquer le même code au composant"
dtc

2
Pas tous la logique métier devrait aller dans les services! Les services, en termes de DDD, ne devraient contenir que la logique de domaine qui affecte plus d'une entité. Voir la réponse stackoverflow.com/a/41358034/238134
deamon

@deamon Oui mais cela dépend de l'approche des développeurs
Harshal Patil

4
@HarshalPatil Vous pourriez bien sûr écrire une application avec toute la logique métier dans les services, mais cela conduirait à un modèle de domaine anémique et rendrait inutile la mise en place de contraintes et de cohérence sur les entités.
Deamon

1
Bien sûr, cela dépend de l'approche du développeur. Tout fait. Si vous abordez le problème de manière incorrecte, c.-à-d. Écrivez tout ce que vous voulez sans structure et dites que c'est "votre approche" - cela ne le fait pas bien. "Bien" et "mal", bien sûr, utilisés comme termes pour décrire les bonnes pratiques de développement logiciel telles que SOLID et d'autres principes, par rapport aux mauvaises pratiques logicielles telles que "Je veux juste que ce soit comme ça pour l'instant" et similaires.
milosmns

71

Spring 2.5 introduit d'autres annotations de stéréotypes: @Component, @Service et @Controller. @Component sert de stéréotype générique pour tout composant géré par Spring; tandis que @Repository, @Service et @Controller servent de spécialisations de @Component pour des cas d'utilisation plus spécifiques (par exemple, dans les couches de persistance, de service et de présentation, respectivement). Cela signifie que vous pouvez annoter vos classes de composants avec @Component, mais en les annotant avec @Repository, @Service ou @Controller à la place, vos classes sont plus adaptées au traitement par des outils ou à l'association avec des aspects. Par exemple, ces annotations de stéréotypes constituent des cibles idéales pour les coupes de points. Bien sûr, il est également possible que @Repository, @Service et @Controller puissent transporter des sémantiques supplémentaires dans les futures versions de Spring Framework. Donc, si vous décidez d'utiliser @Component ou @Service pour votre couche de service, @Service est clairement le meilleur choix. De même, comme indiqué ci-dessus, @Repository est déjà pris en charge comme marqueur pour la traduction automatique des exceptions dans votre couche de persistance.

@Component  Indicates a auto scan component.
@Repository  Indicates DAO component in the persistence layer.
@Service  Indicates a Service component in the business layer.
@Controller  Indicates a controller component in the presentation layer.

référence: - Documentation Spring - Analyse des chemins de classe, composants gérés et écriture des configurations à l'aide de Java


48

Techniquement @Controller, @Service, @Repositorysont tous identiques. Tous s'étendent @Component.

À partir du code source de Spring:

Indique qu'une classe annotée est un "composant". Ces classes sont considérées comme des candidats à la détection automatique lors de l'utilisation de la configuration basée sur des annotations et de l'analyse du chemin de classe.

Nous pouvons utiliser directement @Componentpour chaque haricot, mais pour une meilleure compréhension et la maintenabilité d'une grande application, nous utilisons @Controller, @Service, @Repository.

Objectif de chaque annotation:

  1. @Controller-> Les classes annotées avec cela, sont destinées à recevoir une demande du côté client. La première demande est envoyée au Dispatcher Servlet, d'où il transmet la demande au contrôleur particulier à l'aide de la valeur d' @RequestMappingannotation.
  2. @Service-> Les classes annotées avec cela, sont destinées à manipuler des données que nous recevons du client ou récupérons de la base de données. Toute la manipulation des données doit être effectuée dans cette couche.
  3. @Repository-> Les classes annotées avec cela, sont destinées à se connecter à la base de données. Il peut également être considéré comme une couche DAO (Data Access Object). Cette couche doit être limitée aux opérations CRUD (créer, récupérer, mettre à jour, supprimer) uniquement. Si une manipulation est requise, les données doivent être envoyées et renvoyées à la couche @Service.

Si nous échangeons leur place (utilisation @Repositoryà la place de @Controller), notre application fonctionnera bien.

L'objectif principal de l'utilisation de trois différents @annotationsest de fournir une meilleure modularité à l'application d'entreprise.


2
que voulez-vous dire par remplacer les lieux d'échange? controller and repository
Ashish Kamble

46

L'utilisation @Serviceet les @Repositoryannotations sont importantes du point de vue de la connexion à la base de données.

  1. Utiliser @Servicepour tous vos types de connexions de base de données de service Web
  2. Utilisez @Repositorypour toutes vos connexions de base de données proc stockées

Si vous n'utilisez pas les annotations appropriées, vous pouvez être confronté à des exceptions de validation remplacées par des transactions d'annulation. Vous verrez des exceptions lors du test de charge de stress liées à la restauration des transactions JDBC.


@Repository peut-il être utilisé pour les appels RestAPI au lieu des opérations de base de données?
Nayeem

@Nayeem techniquement, vous pouvez annoter des services en tant que contrôleurs et des référentiels en tant que services, l'injection de dépendance fonctionnerait tout de même. Mais pourquoi voudriez-vous jamais faire ça? S'il ne fonctionne pas avec les entités de base de données - ce n'est pas un référentiel et @Repositoryest spécifiquement conçu pour fonctionner avec la couche de persistance. Si vous travaillez avec l'api de repos - vous travaillez avec des DTO, pas des DAO.
Ben

28

@Repository @Service et @Controller servent de spécialisation de @Component pour une utilisation plus spécifique sur cette base, vous pouvez remplacer @Service par @Component mais dans ce cas, vous perdez la spécialisation.

1. **@Repository**   - Automatic exception translation in your persistence layer.
2. **@Service**      - It indicates that the annotated class is providing a business service to other layers within the application.

27

toutes ces annotations sont de type d'annotation de type stéréo, la différence entre ces trois annotations est

  • Si nous ajoutons le @Component, il indique que le rôle de la classe est une classe de composants, cela signifie que c'est une classe constituée d'une logique, mais il ne dit pas si une classe contenant une logique métier ou de persistance ou de contrôleur spécifique, donc nous n'utilisons pas directement cette annotation @Component
  • Si nous ajoutons l'annotation @Service, cela indique qu'un rôle de classe consiste en une logique métier
  • Si nous ajoutons @Repository au-dessus de la classe, cela indique qu'une classe consistant en une logique de persistance
  • Ici, @Component est une annotation de base pour les annotations @ Service, @ Repository et @Controller

par exemple

package com.spring.anno;
@Service
public class TestBean
{
    public void m1()
    {
       //business code
    }
}

package com.spring.anno;
@Repository
public class TestBean
{
    public void update()
    {
       //persistence code
    }
}
  • chaque fois que nous ajoutons l' annotation @Serviceor @Repositroyou @Controllerpar défaut, l' @Componentannotation va exister au-dessus de la classe

23

Spring propose quatre types différents d'annotations d'analyse automatique des composants @Component, à savoir @Service, @Repositoryet @Controller. Techniquement, il n'y a pas de différence entre eux, mais chaque annotation de balayage de composant automatique doit être utilisée dans un but spécial et dans la couche définie.

@Component: Il s'agit d'une annotation de balayage automatique de composant de base, cela indique que la classe annotée est un composant de balayage automatique.

@Controller: La classe annotée indique qu'il s'agit d'un composant contrôleur et principalement utilisé au niveau de la couche de présentation.

@Service: Il indique que la classe annotée est un composant de service dans la couche de gestion.

@Repository: Vous devez utiliser cette annotation dans la couche de persistance, cela agit comme un référentiel de base de données.

On devrait choisir une forme plus spécialisée de @Componenttout en annotant leur classe car cette annotation peut contenir un comportement spécifique à l'avenir.


20

Nous pouvons y répondre selon la norme java

En se référant à JSR-330, qui est désormais pris en charge par Spring, vous ne pouvez utiliser que @Namedpour définir un bean (d'une manière ou d'une autre @Named=@Component). Ainsi , selon cette norme, il semble qu'il n'y a aucune utilité pour définir des stéréotypes (comme @Repository, @Service, @Controller) aux catégories de haricots.

Mais l'utilisateur de printemps ces différentes annotations différentes pour l'utilisation spécifique, par exemple:

  1. Aidez les développeurs à définir une meilleure catégorie pour les personnes compétentes. Cette catégorisation peut devenir utile dans certains cas. (Par exemple, lorsque vous utilisez aspect-oriented, ceux-ci peuvent être un bon candidat pour pointcuts)
  2. @Repository l'annotation ajoutera des fonctionnalités à votre bean (une traduction d'exception automatique à votre couche de persistance du bean).
  3. Si vous utilisez Spring MVC, le @RequestMappingne peut être ajouté qu'aux classes annotées par @Controller.

Concernant votre 3ème point. Ce n'est pas vrai. Je peux également ajouter l'annotation @RequestMapping aux méthodes sous classe de service (je veux dire les classes annotées avec @Service).
Rahul Gupta

19

Annotez d'autres composants avec @Component, par exemple les classes de ressources REST.

@Component
public class AdressComp{
    .......
    ...//some code here    
}

@Component est un stéréotype générique pour tout composant géré par Spring.

@Controller, @Service et @Repository sont des spécialisations de @Component pour des cas d'utilisation spécifiques.

@Component au printemps

"Spécialisation des composants"


18

Il n'y a pas de différence entre @Component, @Service, @Controller, @Repository. @Componentest l'annotation générique pour représenter le composant de notre MVC. Mais il y aura plusieurs composants dans le cadre de notre application MVC comme les composants de la couche de service, les composants de la couche de persistance et les composants de la couche de présentation. Donc, pour les différencier, Spring a également donné les trois autres annotations.

  • Pour représenter les composants de la couche de persistance: @Repository
  • Pour représenter les composants de la couche de service: @Service
  • Pour représenter les composants de la couche de présentation: @Controller
  • ou bien vous pouvez les utiliser @Componentpour tous.

17

Même si nous échangeons @Component ou @Repository ou @service

Il se comportera de la même manière, mais un aspect est qu'ils ne pourront pas intercepter une exception spécifique liée à DAO au lieu du référentiel si nous utilisons un composant ou un service @


15

Au printemps 4, dernière version:

L'annotation @Repository est un marqueur pour toute classe qui remplit le rôle ou le stéréotype d'un référentiel (également appelé objet d'accès aux données ou DAO). Parmi les utilisations de ce marqueur se trouve la traduction automatique des exceptions comme décrit dans Section 20.2.2, «Traduction des exceptions».

Spring fournit d'autres annotations de stéréotypes: @Component, @Service et @Controller. @Component est un stéréotype générique pour tout composant géré par Spring. @Repository, @Service et @Controller sont des spécialisations de @Component pour des cas d'utilisation plus spécifiques, par exemple, dans les couches de persistance, de service et de présentation, respectivement. Par conséquent, vous pouvez annoter vos classes de composants avec @Component, mais en les annotant avec @Repository, @Service ou @Controller à la place, vos classes sont plus adaptées au traitement par des outils ou à l'association avec des aspects. Par exemple, ces annotations de stéréotypes constituent des cibles idéales pour les coupes de points. Il est également possible que @Repository, @Service et @Controller puissent transporter des sémantiques supplémentaires dans les futures versions de Spring Framework. Donc, si vous choisissez d'utiliser @Component ou @Service pour votre couche de service, @Service est clairement le meilleur choix. De même, comme indiqué ci-dessus, @Repository est déjà pris en charge comme marqueur pour la traduction automatique des exceptions dans votre couche de persistance.


15

@Component : vous annotez une classe @Component, il indique à hibernate qu'il s'agit d'un Bean.

@Repository : vous annotez une classe @Repository, il indique à Hibernate qu'il s'agit d'une classe DAO et la traite comme une classe DAO. Cela signifie que les exceptions non vérifiées (levées à partir des méthodes DAO) peuvent être traduites dans Spring DataAccessException.

@Service : Cela indique à hibernate qu'il s'agit d'une classe de service où vous aurez @Transactionaletc. des annotations de couche Service, donc hibernate la traite comme un composant de service.

De plus, @Servicec'est l'avance de @Component. Supposons que le nom de la classe du bean soit CustomerService, puisque vous n'avez pas choisi la méthode de configuration du bean XML, vous avez donc annoté le bean avec @Componentpour l'indiquer en tant que bean. Ainsi, lors de l'obtention de l'objet bean CustomerService cust = (CustomerService)context.getBean("customerService");Par défaut, Spring minuscule le premier caractère du composant - de «CustomerService» à «customerService». Et vous pouvez récupérer ce composant avec le nom 'customerService'. Mais si vous utilisez une @Serviceannotation pour la classe de bean, vous pouvez fournir un nom de bean spécifique en

@Service("AAA")
public class CustomerService{

et vous pouvez obtenir l'objet bean en

CustomerService cust = (CustomerService)context.getBean("AAA");

13

@Component est l'annotation générique de niveau supérieur qui rend le bean annoté à analyser et disponible dans le conteneur DI

@Repository est une annotation spécialisée et apporte la fonctionnalité de conversion de toutes les exceptions non vérifiées des classes DAO

@Serviceest une annotation spécialisée. il n'apporte aucune nouvelle fonctionnalité pour l'instant mais il clarifie l'intention du bean

@Controller est une annotation spécialisée qui rend le bean MVC conscient et permet l'utilisation d'annotations supplémentaires comme @RequestMapping celles-ci

Voici plus de détails


11

A @Servicepour citer la documentation du printemps,

Indique qu'une classe annotée est un "service", défini à l'origine par Domain-Driven Design (Evans, 2003) comme "une opération proposée comme une interface autonome dans le modèle, sans état encapsulé". Peut également indiquer qu'une classe est une "Business Service Facade" (au sens des modèles Core J2EE), ou quelque chose de similaire. Cette annotation est un stéréotype à usage général et les équipes individuelles peuvent restreindre leur sémantique et utiliser le cas échéant.

Si vous regardez la conception pilotée par domaine par Eric Evans,

Un SERVICE est une opération offerte comme une interface autonome dans le modèle, sans encapsuler l'état, comme le font les ENTITÉS et les OBJETS DE VALEUR. Les SERVICES sont un modèle courant dans les cadres techniques, mais ils peuvent également s'appliquer à la couche domaine. Le service de noms met l'accent sur la relation avec d'autres objets. Contrairement aux ENTITÉS et OBJETS DE VALEUR, il est défini uniquement en termes de ce qu'il peut faire pour un client. Un SERVICE a tendance à être nommé pour une activité, plutôt qu'une entité - un verbe plutôt qu'un nom. Un SERVICE peut toujours avoir une définition abstraite et intentionnelle; il a juste une saveur différente de la définition d'un objet. Un SERVICE doit toujours avoir une responsabilité définie, et cette responsabilité et l'interface qui le remplit doivent être définies comme faisant partie du modèle de domaine. Les noms d'opération doivent provenir de la LANGUE UBIQUITE ou y être introduits. Les paramètres et les résultats doivent être des objets de domaine. Les SERVICES doivent être utilisés judicieusement et ne pas être autorisés à dépouiller les ENTITÉS et VALEURS OBJETS de tout leur comportement. Mais lorsqu'une opération est en fait un concept de domaine important, un SERVICE fait naturellement partie d'une CONCEPTION AXÉE SUR LES MODÈLES. Déclarée dans le modèle comme un SERVICE, plutôt que comme un objet bidon qui ne représente en fait rien, l'opération autonome n'induira personne en erreur. un SERVICE fait naturellement partie d'une CONCEPTION AXÉE SUR LES MODÈLES. Déclarée dans le modèle comme un SERVICE, plutôt que comme un objet bidon qui ne représente en fait rien, l'opération autonome n'induira personne en erreur. un SERVICE fait naturellement partie d'une CONCEPTION AXÉE SUR LES MODÈLES. Déclarée dans le modèle comme un SERVICE, plutôt que comme un objet bidon qui ne représente en fait rien, l'opération autonome n'induira personne en erreur.

et un Repositorycomme par Eric Evans,

Un REPOSITORY représente tous les objets d'un certain type comme un ensemble conceptuel (généralement émulé). Il agit comme une collection, sauf avec une capacité d'interrogation plus élaborée. Les objets du type approprié sont ajoutés et supprimés, et la machinerie derrière le REPOSITORY les insère ou les supprime de la base de données. Cette définition rassemble un ensemble cohérent de responsabilités pour fournir un accès aux racines des AGRÉGATS du début du cycle de vie jusqu'à la fin.


11

Des réponses suffisamment bonnes sont là pour expliquer quelle est la différence entre les annotations de service de référentiel de composants. Je voudrais partager la différence entre@Controller & @RestController

@Controller contre RestController

@RestController:

entrez la description de l'image ici

  • Cette annotation est une version spécialisée @Controllerqui ajoute @Controlleret @ResponseBodyannote automatiquement. nous n'avons donc pas à ajouter @ResponseBodyà nos méthodes de cartographie. Cela signifie @ResponseBody valeur par défaut est active.
  • Si vous utilisez, @RestControllervous ne pouvez pas retourner une vue (en utilisant Viewresolverdans Spring / Spring-Boot)
  • @RestControllerconvertit également la réponse JSON/XML automaticallyen @ResponseBodyrendant les objets retournés en quelque chose qui pourrait être dans le corps,e.g. JSON or XML

@Controller

entrez la description de l'image ici

  • @Controllerest utilisé pour marquer les classes comme Spring MVC Controller. Cette annotation n'est qu'une version spécialisée de @Componentet elle permet aux classes de contrôleur d'être automatiquement détectées sur la base de l'analyse du chemin de classe.
  • @Controller vous pouvez renvoyer une vue dans Spring Web MVC.

Vue plus détaillée


9

Le référentiel et le service sont des enfants d' annotation de composant . Donc, tous sont des composants . Le référentiel et le service ne font que l'étendre. De quelle façon précisément? Le service n'a qu'une différence idéologique: nous l'utilisons pour les services. Le référentiel a un gestionnaire d'exceptions particulier.


6

Explication des stéréotypes:

  • @Service- Annotez toutes vos classes de service avec @Service. Cette couche connaît l'unité d'oeuvre. Toute votre logique métier sera dans les classes de service. Généralement, les méthodes de couche de service sont couvertes par la transaction. Vous pouvez effectuer plusieurs appels DAO à partir de la méthode de service, si une transaction échoue, toutes les transactions doivent être annulées.
  • @Repository- Annotez toutes vos classes DAO avec @Repository. Toute votre logique d'accès à la base de données doit être dans des classes DAO.
  • @Component - Annotez vos autres composants (par exemple les classes de ressources REST) ​​avec le stéréotype du composant.
  • @Autowired - Laissez Spring câbler automatiquement d'autres beans dans vos classes en utilisant l'annotation @Autowired.

@Componentest un stéréotype générique pour tout composant géré par Spring. @Repository,, @Serviceet @Controllersont des spécialisations de @Componentpour des cas d'utilisation plus spécifiques, par exemple, dans les couches de persistance, de service et de présentation, respectivement.

A l'origine répondu ici .


5

Différence entre les annotations @Component, @Repository, @Controller & @Service

@Component - générique et peut être utilisé dans toute l'application.
@Service - annote des classes au niveau de la couche de service.
@Controller - annote des classes au niveau des couches de présentation, principalement utilisées dans Spring MVC.
@Repository - annote des classes sur la couche de persistance, qui agira comme référentiel de base de données.

@Controller= @Component (Annotation interne) + Fonctionnalités de la couche de présentation
@Service= @Component (Annotation interne) + Fonctionnalités de la couche Service
@Component= Composants réels (Beans)
@Repository= @Component (Annotation interne) + Fonctionnalités de la couche de données (à utiliser pour gérer les beans de domaine)


3

Au printemps, le framework fournit un type particulier d'annotations, appelées annotations de stéréotypes. Ce sont les suivants: -

@RestController- Declare at controller level.
@Controller  Declare at controller level.
@Component  Declare at Bean/entity level.
@Repository  Declare at DAO level.
@Service  Declare at BO level.

les annotations déclarées ci-dessus sont spéciales car lorsque nous ajoutons <context:component-scan>dans le fichier xxx-servlet.xml, spring créera automatiquement l'objet des classes qui sont annotées avec l'annotation ci-dessus pendant la phase de création / chargement du contexte.


2

@Component, @ Repository, @ Service, @Controller:

@Componentest un stéréotype générique pour les composants gérés par Spring @Repository, @Serviceet @Controllersont des @Componentspécialisations pour des utilisations plus spécifiques de:

  • @Repository pour la persistance
  • @Service pour services et transactions
  • @Controller pour les contrôleurs MVC

Pourquoi utiliser @Repository, @Service, @Controllerplus@Component ? Nous pouvons marquer nos classes de composants avec @Component, mais si à la place nous utilisons l'alternative qui s'adapte à la fonctionnalité attendue. Nos classes sont mieux adaptées aux fonctionnalités attendues dans chaque cas particulier.

Une classe annotée avec @Repositoryune meilleure traduction et une meilleure gestion des erreurs lisibles avec org.springframework.dao.DataAccessException. Idéal pour implémenter des composants qui accèdent aux données (DataAccessObject ou DAO).

Une classe annotée avec @Controllerjoue un rôle de contrôleur dans une application Spring Web MVC

Une classe annotée avec @Servicejoue un rôle dans les services de logique métier, exemple de modèle de façade pour DAO Manager (Facade) et la gestion des transactions


2

Les réponses présentées ici sont largement correctes sur le plan technique, mais même si la liste des réponses est longue et ce sera tout en bas, j'ai pensé qu'il valait la peine de mettre une réponse réellement correcte ici aussi, juste au cas où quelqu'un tomberait dessus et apprend quelque chose de précieux à partir de il. Ce n'est pas que les autres réponses sont fausses, c'est juste qu'elles ne sont pas correctes. Et, pour arrêter les hordes de trolls, oui, je sais que techniquement ces annotations sont effectivement la même chose et les plus interchangeables jusqu'au printemps 5. Maintenant, pour la bonne réponse:

Ces trois annotations sont des choses complètement différentes et ne sont pas interchangeables. Vous pouvez le dire parce qu'il y en a trois plutôt qu'un seul. Ils ne sont pas destinés à être interchangeables, ils sont simplement mis en œuvre de cette façon par élégance et commodité.

La programmation moderne est invention, art, technique et communication, dans des proportions variables. Le bit de communication est généralement très important car le code est généralement lu beaucoup plus souvent qu'il n'est écrit. En tant que programmeur, vous essayez non seulement de résoudre le problème technique, vous essayez également de communiquer votre intention aux futurs programmeurs qui liront votre code. Ces programmeurs peuvent ne pas partager votre langue maternelle, ni votre environnement social, et il est possible qu'ils lisent votre code 50 ans dans le futur (ce n'est pas aussi improbable que vous ne le pensez). Il est difficile de communiquer efficacement aussi loin dans le futur. Par conséquent, il est essentiel que nous utilisions le langage le plus clair, le plus efficace, le plus correct et le plus communicatif qui soit à notre disposition.

Par exemple, il est essentiel de l' @Repositoryutiliser lorsque nous écrivons un référentiel, plutôt que @Component. Ce dernier est un très mauvais choix d'annotation pour un référentiel car il n'indique pas que nous examinons un référentiel. Nous pouvons supposer qu'un référentiel est également un bean de printemps, mais pas qu'un composant est un référentiel. Avec @Repositorynous sommes clairs et précis dans notre langue. Nous déclarons clairement qu'il s'agit d'un référentiel. Avec@Componentnous laissons au lecteur le soin de décider quel type de composant il lit, et il devra lire toute la classe (et éventuellement un arbre de sous-classes et d'interfaces) pour en déduire le sens. La classe pourrait alors être mal interprétée par un lecteur dans un avenir lointain comme n'étant pas un référentiel, et nous aurions été partiellement responsables de cette erreur parce que nous, qui savions très bien qu'il s'agit d'un référentiel, n'avons pas été spécifiques dans notre langue et communiquer efficacement notre intention.

Je n'entrerai pas dans les autres exemples, mais je dirai aussi clairement que possible: ces annotations sont des choses complètement différentes et doivent être utilisées de manière appropriée, conformément à leur intention. @Repositoryconcerne les référentiels de stockage et aucune autre annotation n'est correcte. @Serviceest pour les services et aucune autre annotation n'est correcte. @Componentest pour des composants qui ne sont ni des répertoires ni des services, et utiliser l'un ou l'autre à la place serait également incorrect. Il pourrait compiler, il pourrait même fonctionner et réussir vos tests, mais ce serait faux et je penserais moins à vous (professionnellement) si vous faisiez cela.

Il y en a des exemples tout au long du printemps (et de la programmation en général). Vous ne devez pas utiliser @Controllerlors de l'écriture d'une API REST, car elle @RestControllerest disponible. Vous ne devez pas utiliser @RequestMappingwhen @GetMappingest une alternative valide. Etc. Etc. Etc. Vous devez choisir la langue exacte et correcte la plus précise possible pour communiquer votre intention à vos lecteurs, sinon vous introduisez des risques dans votre système et les risques ont un coût.


bien dit et bon point!
Andy

1

Afin de simplifier cette illustration, considérons la technicité par cas d'utilisation, ces annotations sont utilisées pour être injectées et comme je l'ai dit littéralement " utilisé pour être injecté ", cela signifie, si vous savez comment utiliser l' injection de dépendance "DI" et vous Si, alors vous chercherez toujours ces annotations, et en annotant les classes avec ces types stéréo , vous informez le conteneur DI de les scanner pour qu'elles soient prêtes pour l'injection à d'autres endroits, c'est la cible pratique.

Passons maintenant à chacun; d'abord @Service , si vous construisez une logique pour un cas commercial spécifique, vous devez séparer cela dans un endroit qui contiendra votre logique métier, ce service est de classe normale ou vous pouvez l'utiliser comme interface si vous le souhaitez, et il est écrit comme cette

@Service
public class Doer {
   // Your logic 
}

// To use it in another class, suppose in Controller 
@Controller
public class XController {
 // You have to inject it like this 
 @Autowired 
 private Doer doer;
}

Tous sont de la même manière lorsque vous les injectez, @Repository c'est une interface qui applique l'implémentation du modèle de référentiel Modèle de conception de référentiel , généralement il est utilisé lorsque vous traitez avec un magasin de données ou une base de données, et vous constaterez qu'il contient plusieurs mise en œuvre prête pour que vous puissiez gérer les opérations de base de données; il peut s'agir de CrudRepository , JpaRepository etc.

// For example
public interface DoerRepository implements JpaRepository<Long, XEntity> {}

Enfin le @Component , c'est la forme générique pour les beans enregistrés au printemps, c'est le printemps qui recherche toujours le bean marqué avec @Component à enregistrer, alors @Service et @Repository sont des cas spéciaux de @Component, cependant le cas d'utilisation courant pour le composant, c'est quand vous faites quelque chose de purement technique, pas pour couvrir une analyse de rentabilité directe! comme le formatage des dates ou la remise d'un mécanisme de sérialisation de demande spéciale, etc.


0

@Component agit comme une annotation @Bean dans la classe de configuration, enregistre le bean dans le contexte du printemps. Il est également parent pour l'annotation @Service, @Repository et @Controller.

@Service , étend l'annotation @Component et n'a que la différence de dénomination.

@Repository - étend l'annotation @Component et traduit toutes les exceptions de base de données en DataAccessException .

@Controller - agit comme contrôleur dans le modèle MVC. Le répartiteur analysera ces classes annotées pour les méthodes mappées, détectant les annotations @RequestMapping.


-13
@Component
@Controller
@Repository
@Service
@RestController

Ce sont toutes des annotations StereoType. Celles-ci sont utiles pour faire nos classes comme haricots de printemps dans un conteneur IOC,

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.