Qual è la differenza tra le annotazioni @Component, @Repository e @Service in primavera?


2104

Can @Component, @Repositorye @Servicele annotazioni essere usati in modo intercambiabile in primavera o non forniscono alcuna funzionalità particolare oltre a fungere da dispositivo di notazione?

In altre parole, se ho una classe di servizio e cambio l'annotazione da @Servicea @Component, si comporterà comunque allo stesso modo?

O l'annotazione influenza anche il comportamento e la funzionalità della classe?


8
Essendo uno sviluppatore con background Microsoft, ricordo la definizione semantica di servizi nel vecchio framework MS SmartClientSoftwareFactory (ora un framework complesso a lungo deprecato per le app desktop distribuite). Tale definizione ( ben documentata da Rich Newman) ha definito i servizi come oggetti riutilizzabili senza stato, preferibilmente con ambito singleton, che vengono utilizzati per eseguire operazioni di logica aziendale su altri oggetti passati come argomenti. Tendo a vedere i servizi primaverili allo stesso modo
Ivaylo Slavov il

3
Non importa !! Qualunque cosa funzioni per te :) Ho sempre odiato questo riguardo a Spring che tendono sempre a definire "regole" per te, che aggiungono solo un valore banale alla tua applicazione. Per non parlare della primavera, con un enorme stack a parte.
TriCore,

30
@TriCore Sprting è un framework, definire "regole" per te è il suo lavoro :)
Walfrat,

Risposte:


1502

Dalla documentazione di primavera :

L' @Repositoryannotazione è un marcatore per qualsiasi classe che soddisfa il ruolo o lo stereotipo di un repository (noto anche come Data Access Object o DAO). Tra gli usi di questo marcatore c'è la traduzione automatica delle eccezioni, come descritto nella traduzione delle eccezioni .

Primavera fornisce ulteriori annotazioni stereotipo: @Component, @Service, e @Controller. @Componentè uno stereotipo generico per qualsiasi componente gestito da Spring. @Repository, @Servicee @Controllersono specializzazioni @Componentper casi d'uso più specifici (rispettivamente nei livelli di persistenza, servizio e presentazione). Pertanto, è possibile annotare le vostre classi di componenti con @Component, ma, da loro indicandoli con @Repository, @Serviceo@Controller invece, le vostre classi sono più propriamente adatti per la lavorazione con strumenti o associandosi con aspetti.

Ad esempio, queste annotazioni stereotipate sono obiettivi ideali per i tagli di punti. @Repository, @Servicee @Controllerpuò anche contenere semantica aggiuntiva nelle versioni future di Spring Framework. Pertanto, se si sceglie tra l'utilizzo @Componento @Serviceper il proprio livello di servizio, @Serviceè chiaramente la scelta migliore. Allo stesso modo, come affermato in precedenza, @Repositoryè già supportato come indicatore per la traduzione automatica delle eccezioni nel livello di persistenza.

┌──────────────┬─────────────────────────────────────────────────────┐
 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
Avrebbe senso aggiungere @Controller (o @Component) a un @WebServlet? Non è un controller Spring MVC, ma questa è la corrispondenza concettualmente più vicina. Che dire dei filtri servlet?
Rick,

1
cosa significa "@Repository è già supportato come marker per la traduzione automatica delle eccezioni nel livello di persistenza". significare?
Jack,

9
Si riferisce al fatto che queste annotazioni sono buoni obiettivi per AOP, e mentre le altre annotazioni non definiscono ancora un punto preciso, potrebbero farlo in futuro. D'altra parte, al momento @Repository è già una destinazione per un punto. Questo punto viene utilizzato per le traduzioni delle eccezioni, ovvero la traduzione di eccezioni specifiche per la tecnologia in più generiche basate su Spring, per evitare un accoppiamento stretto.
Stavlo

3
@stivlo: ho davvero cercato di capire il termine "stereotipo", ancora non capisco. La prego di aiutarmi a capire questa terminologia? Aiuta molto e grazie mille
Premraj,

2
@xenoterracide Non c'è praticamente molta differenza. Anche qualcosa annotato @Service è un @Component(perché l' @Serviceannotazione stessa è annotata con @Component). Per quanto ne so, nulla nel framework Spring fa esplicito uso del fatto che qualcosa è un @Service, quindi la differenza è davvero solo concettuale.
Jesper,

801

Poiché molte delle risposte indicano già a cosa servono queste annotazioni, qui ci concentreremo su alcune differenze minori tra loro.

Innanzitutto la somiglianza

Il primo punto da sottolineare è che per quanto riguarda la rilevazione automatica della scansione e l'iniezione di dipendenza per BeanDefinition tutte queste annotazioni (vale a dire, @Component, @Service, @Repository, @Controller) sono le stesse. Possiamo usarne uno al posto di un altro e possiamo ancora spostarci.


Differenze tra @Component, @Repository, @Controller e @Service

@Componente

Questa è un'annotazione stereotipata per uso generico che indica che la classe è un componente spring.

La particolarità di @Component
<context:component-scan> scansiona@Componente non cerca@Controller,@Servicee@Repositoryin generale. Vengono scansionati perché sono essi stessi annotati@Component.

Basta dare un'occhiata a @Controller, @Servicee @Repositoryle definizioni della nota:

@Component
public @interface Service {
    ….
}

 

@Component
public @interface Repository {
    ….
}

 

@Component
public @interface Controller {
    
}

Così, non è sbagliato dire che @Controller, @Servicee @Repositorysono particolari tipi di @Componentannotazione. <context:component-scan>le raccoglie e registra le loro seguenti classi come bean, proprio come se fossero annotate @Component.

Anche le annotazioni di tipo speciale vengono scansionate, poiché sono esse stesse annotate con @Componentannotazione, il che significa che sono anche @Components. Se definiamo la nostra annotazione personalizzata e la annotiamo con @Component, verrà scansionata anche con<context:component-scan>


@Repository

Questo per indicare che la classe definisce un repository di dati.

Cosa c'è di speciale in @Repository?

Oltre a sottolineare che si tratta di una configurazione basata su annotazioni , @Repositoryil compito è quello di catturare le eccezioni specifiche della piattaforma e rilanciarle come una delle eccezioni unificate non controllate di Spring. Per questo, ci viene fornito PersistenceExceptionTranslationPostProcessor, che ci viene richiesto di aggiungere nel nostro contesto applicativo di Spring in questo modo:

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

Questo post processor del bean aggiunge un advisor a qualsiasi bean annotato in @Repositorymodo tale che vengano rilevate eventuali eccezioni specifiche della piattaforma e quindi rilanciate come una delle eccezioni di accesso ai dati non controllate di Spring.


@Controller

L' @Controllerannotazione indica che una particolare classe svolge il ruolo di controller. L' @Controllerannotazione funge da stereotipo per la classe annotata, indicandone il ruolo.

Cosa c'è di speciale in @Controller?

Non possiamo cambiare questa annotazione con altri simili @Serviceo @Repository, anche se sembrano uguali. Il dispatcher esegue la scansione delle classi annotate @Controllere rileva i metodi annotati con @RequestMappingannotazioni al loro interno. Possiamo usare @RequestMappingil / nel solo quei metodi le cui classi sono annotati con @Controllere sarà NON lavorare con @Component, @Service, @Repositoryecc ...

Nota: se una classe è già registrata come bean tramite qualsiasi metodo alternativo, come attraverso @Beano attraverso @Component, @Serviceecc ... annotazioni, allora @RequestMappingpuò essere scelta se la classe è anche annotata con @RequestMappingannotazione. Ma questo è uno scenario diverso.


@Servizio

@Service i bean contengono la logica aziendale e chiamano i metodi nel livello repository.

Cosa c'è di speciale in @Service?

A parte il fatto che è usato per indicare, che sta trattenendo la logica aziendale, non c'è nient'altro evidente in questa annotazione; ma chissà, la primavera potrebbe aggiungere ulteriori eccezionali in futuro.


Cos'altro?

Simile a sopra, in futuro primavera può aggiungere funzionalità speciali per i @Service, @Controllere @Repositoryin base alle loro convenzioni di stratificazione. Quindi, è sempre una buona idea rispettare la convenzione e usarla in linea con i livelli.


"PersistenceExceptionTranslationPostProcessor" verrà registrato automaticamente se viene rilevato l'APP.
Olga,

21
Spiegazione fantastica. Hai chiarito molte delle mie incomprensioni. Venendo da un'università in cui abbiamo costruito tutti i nostri progetti dal basso verso l'alto, ho avuto difficoltà a capire perché Spring Applications ha funzionato, anche se non stai collegando esplicitamente il programma da solo. Le annotazioni ora hanno molto senso, grazie!
NodziGames il

Quindi cosa significa l'annotazione @Service per Hibernate (Persistence Layer), oltre alla funzione DI per quanto riguarda il Proxy Layer di persistenza per il recupero e la mappatura di una sorta di Entity al rispettivo DTO? Questo livello è molto importante per il dinamismo nel livello di persistenza. Se qualcuno sa profondamente come influisce sull'APP, sarebbe molto utile)))
Musa,

1
C'è qualche piccola disinformazione @Controllersull'annotazione. Non è richiesto se la classe è annotata @RequestMappinge il bean di questa classe viene creato in alcun modo. Qualsiasi bean annotato con @Controller OR @RequestMapping parteciperà ai mapping delle richieste di Spring MVC. Ciò può essere utile, ad esempio, per creare programmatori di controller a livello di codice (ad es. Utilizzando @Beanmetodi) e allo stesso tempo per impedire a Spring di provare a crearli tramite la scansione del pacchetto (se il pacchetto non può essere escluso dalla scansione).
Ruslan Stelmachenko,

1
questa dovrebbe essere la risposta più votata - risponde a tutte le domande e va abbastanza in profondità. @stivlo non ha spiegato molto sulla prima domanda di OP: differenze tecniche.
kiedysktos,

430

Sono quasi uguali - tutti significano che la classe è un fagiolo di primavera. @Service, @RepositoryE @Controllersono specializzati @Components. Puoi scegliere di eseguire azioni specifiche con loro. Per esempio:

  • @Controller i fagioli sono usati da spring-mvc
  • @Repository i bean sono idonei per la traduzione delle eccezioni di persistenza

Un'altra cosa è che si designano i componenti semanticamente a diversi livelli.

Una cosa che @Componentoffre è che puoi annotare altre annotazioni con esso e quindi usarle allo stesso modo di @Service.

Ad esempio di recente ho realizzato:

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

Quindi tutte le classi annotate @ScheduledJobsono bean di primavera e in aggiunta sono registrati come lavori al quarzo. Devi solo fornire il codice che gestisce l'annotazione specifica.


1
@Component significa solo un fagiolo primaverile, c'è qualche altro scopo per questo?
Kapil das,

21
I bean @Component sono rilevabili automaticamente dal contenitore a molla. Non è necessario definire il bean nel file di configurazione, verrà rilevato automaticamente al runtime da Spring.
Akash5288,

1
Sono abbastanza affezionato al generico @Component ... specialmente in combinazione con @Scope (proxyMode = ScopedProxyMode.//MODE)
Eddie B

365

@Component è equivalente a

<bean>

@Service, @Controller, @Repository = {@Component + alcune altre funzionalità speciali}

Ciò significa che servizio, controller e repository sono funzionalmente uguali.

Le tre annotazioni vengono utilizzate per separare "Livelli" nell'applicazione,

  • I controller fanno semplicemente cose come invio, inoltro, chiamata di metodi di servizio ecc.
  • Service Hold business Logic, Calcoli ecc.
  • I repository sono i DAO (Data Access Objects), accedono direttamente al database.

Ora potresti chiederti perché separarli: (suppongo che tu sappia che AOP-Aspect Oriented Programming)

Supponiamo che desideri monitorare solo l'attività del livello DAO. Scriverai una classe Aspect (classe A) che esegue alcune registrazioni prima e dopo che è stato invocato ogni metodo del tuo DAO, puoi farlo usando AOP poiché hai tre livelli distinti e non sono mescolati.

Quindi puoi fare il logging di DAO "around", "before" o "after" i metodi DAO. Potresti farlo perché avevi un DAO in primo luogo. Quello che hai appena ottenuto è la separazione di preoccupazioni o compiti.

Immagina se ci fosse una sola annotazione @Controller, questo componente disporrà di un dispatching, di una logica aziendale e di un database di accesso tutti misti, quindi codice sporco!

Sopra menzionato è uno scenario molto comune, ci sono molti altri casi d'uso del perché usare tre annotazioni.


6
Ho una domanda fondamentale: le annotazioni sono usate dal meccanismo a molla o sono solo per il programmatore per ricordare cosa fanno quei pezzi di codice?
user107986

25
@ user107986 Sono principalmente per il programmatore per ricordare i livelli nell'applicazione. Tuttavia @Respositoryha anche la funzione di traduzione automatica delle eccezioni. Come quando si verifica un'eccezione in a, di @Repositorysolito esiste un gestore per quell'eccezione e non è necessario aggiungere blocchi try catch nella classe DAO. Viene utilizzato insieme a PersistenceExceptionTranslationPostProcessor
Oliver

puoi per favore scrivere un codice di esempio su come scrivere un punto Joint per tutta la classe "@Repository". O usiamo le espressioni o usiamo il nome del bean, ma come possiamo dire che questo consiglio si applicherà a tutte le classi "@Repository". Stavo cercando di ottenere un esempio di questo ma non sono riuscito a trovarlo. Il tuo aiuto è molto apprezzato.
Moni,

Inoltre, mentre le annotazioni funzionano tutte allo stesso modo funzionalmente, è possibile che in futuro vengano aggiunte funzionalità specifiche per un dato attributo.
Cod3Citrus

224

In primavera @Component, @Service, @Controller, e @Repositorysono le annotazioni stereotipo che sono utilizzati per:

@Controller:dove la mappatura delle richieste dalla pagina di presentazione viene eseguita, ad esempio il livello Presentazione non passa a nessun altro file, va direttamente in @Controllerclasse e verifica il percorso richiesto nell'annotazione @RequestMappingche è stata scritta prima della chiamata del metodo, se necessario.

@Service: Tutta la logica aziendale è qui, ad esempio calcoli relativi ai dati e tutti. Questa annotazione del livello aziendale in cui il nostro utente non chiama direttamente il metodo di persistenza, quindi chiamerà questo metodo utilizzando questa annotazione. Richiederà @Repository secondo la richiesta dell'utente

@Repository: Si tratta del livello di persistenza (livello di accesso ai dati) dell'applicazione utilizzato per ottenere i dati dal database. vale a dire tutte le operazioni relative al database vengono eseguite dal repository.

@Component - Annota gli altri componenti (ad esempio le classi di risorse REST) ​​con uno stereotipo del componente.

Indica che una classe annotata è un " componente ". Tali classi sono considerate candidate per il rilevamento automatico quando si utilizza la configurazione basata su annotazioni e la scansione del percorso di classe.

Altre annotazioni a livello di classe possono essere considerate come identificative di un componente, in genere un tipo speciale di componente: ad esempio l'annotazione @Repository o l'annotazione @Aspect di AspectJ.

inserisci qui la descrizione dell'immagine


24
queste risposte sono tutte belle e tutte, ma sono abbastanza sicuro che ciò che la maggior parte di noi desidera è alcuni esempi di codice delle caratteristiche che i componenti come il servizio offrono che possiamo concretamente mettere nella nostra testa piuttosto che solo una descrizione generale come "logica aziendale" appartiene questo oggetto. altrimenti, supponiamo ancora "oh, è fantastico e tutto, ma posso ancora applicare lo stesso codice al componente"
dtc,

2
Non tutte le logiche aziendali dovrebbero andare nei servizi! I servizi, in termini di DDD, dovrebbero contenere solo la logica di dominio che interessa più di un'entità. Vedi risposta stackoverflow.com/a/41358034/238134
Deamon

@deamon Sì, ma dipende dall'approccio degli sviluppatori
Harshal Patil,

4
@HarshalPatil Ovviamente potresti scrivere un'applicazione con tutte le logiche aziendali nei servizi, ma ciò porterebbe a un modello di dominio anemico e renderebbe superfluo il compito di imporre vincoli e coerenza sulle entità.
Deamon il

1
Naturalmente dipende dall'approccio dello sviluppatore. Tutto fa. Se affrontate il problema in modo errato, ovvero scrivete quello che volete senza struttura e dite che è "il vostro approccio", ma non è corretto. "Giusto" e "sbagliato", ovviamente, vengono usati come termini per descrivere le buone pratiche di sviluppo del software come SOLID e altri principi, rispetto alle cattive pratiche del software come "Lo voglio solo così per ora" e simili.
milosmns,

71

Spring 2.5 introduce ulteriori annotazioni stereotipate: @Component, @Service e @Controller. @Component funge da stereotipo generico per qualsiasi componente gestito da Spring; considerando che @Repository, @Service e @Controller servono come specializzazioni di @Component per casi d'uso più specifici (ad esempio, rispettivamente nei livelli di persistenza, servizio e presentazione). Ciò significa che puoi annotare le tue classi di componenti con @Component, ma annotandole con @Repository, @Service o @Controller, le tue classi sono più adatte per l'elaborazione da parte di strumenti o l'associazione con aspetti. Ad esempio, queste annotazioni stereotipate sono obiettivi ideali per i tagli di punti. Naturalmente, è anche possibile che @Repository, @Service e @Controller possano trasportare semantica aggiuntiva nelle versioni future di Spring Framework. Così, se stai prendendo una decisione tra l'utilizzo di @Component o @Service per il tuo livello di servizio, @Service è chiaramente la scelta migliore. Allo stesso modo, come indicato sopra, @Repository è già supportato come marker per la traduzione automatica delle eccezioni nel livello di persistenza.

@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.

riferimento: - Documentazione di primavera - Scansione di percorsi di classe, componenti gestiti e configurazioni di scrittura tramite Java


48

Tecnicamente @Controller, @Service, @Repositorysono tutti uguali. Tutti si estendono @Component.

Dal codice sorgente di Spring:

Indica che una classe annotata è un "componente". Tali classi sono considerate candidate per il rilevamento automatico quando si utilizza la configurazione basata su annotazioni e la scansione del percorso di classe.

Possiamo usare direttamente @Componentper ogni chicco, ma per una migliore comprensione e la manutenibilità di un'applicazione di grandi dimensioni, che usiamo @Controller, @Service,@Repository .

Scopo di ciascuna annotazione:

  1. @Controller-> Le classi annotate con questo, sono destinate a ricevere una richiesta dal lato client. La prima richiesta arriva al servlet Dispatcher, da dove passa la richiesta al controller specifico utilizzando il valore @RequestMappingdell'annotazione.
  2. @Service-> Le classi annotate con questo, hanno lo scopo di manipolare i dati, che riceviamo dal client o recuperiamo dal database. Tutta la manipolazione con i dati dovrebbe essere fatta in questo livello.
  3. @Repository-> Le classi annotate con questo, hanno lo scopo di connettersi con il database. Può anche essere considerato come livello DAO (Data Access Object). Questo livello deve essere limitato alle sole operazioni CRUD (creare, recuperare, aggiornare, eliminare). Se è necessaria una manipolazione, i dati devono essere inviati per essere rispediti al livello @Service.

Se scambiamo il loro posto (utilizzare @Repositoryal posto di @Controller), la nostra applicazione funzionerà perfettamente.

Lo scopo principale dell'utilizzo di tre diversi @annotationsè quello di fornire una migliore modularità all'applicazione Enterprise.


2
cosa intendi per sostituzione di luoghi interscambiabili? controller and repository
Ashish Kamble,

46

L'uso @Servicee le @Repositoryannotazioni sono importanti dal punto di vista della connessione al database.

  1. Utilizzare @Serviceper tutto il tipo di servizio Web di connessioni DB
  2. Utilizzare @Repositoryper tutte le connessioni al DB proc memorizzate

Se non si utilizzano le annotazioni appropriate, è possibile che si verifichino eccezioni di commit sovrascritte da transazioni di rollback. Durante il test del carico di stress verranno visualizzate eccezioni correlate al rollback delle transazioni JDBC.


È possibile utilizzare @Repository per le chiamate RestAPI anziché le operazioni DB?
Nayeem,

@Nayeem tecnicamente è possibile annotare i servizi come controller e repository come servizi, l'iniezione delle dipendenze funzionerebbe allo stesso modo. Ma perché mai lo faresti? Se non funziona con le entità del database, non è un repository ed @Repositoryè specificamente progettato per funzionare con il livello di persistenza. Se lavori con API di riposo, stai lavorando con DTO, non con DAO.
Ben

28

@Repository @Service e @Controller servono come specializzazione di @Component per un uso più specifico su tale base, è possibile sostituire @Service a @Component ma in questo caso si perde la specializzazione.

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

tutte queste annotazioni sono di tipo stereo tipo di annotazione, la differenza tra queste tre annotazioni è

  • Se aggiungiamo @Component, indica che il ruolo della classe è una classe componente, significa che è una classe costituita da una logica, ma non indica se una classe che contiene una logica specifica di business o di persistenza o controller, quindi non usiamo direttamente questa annotazione @Component
  • Se aggiungiamo l'annotazione @Service, questo indica che un ruolo di classe consiste nella logica aziendale
  • Se aggiungiamo @Repository in cima alla classe, allora dice che una classe consiste nella logica di persistenza
  • Qui @Component è un'annotazione di base per le annotazioni @ Service, @ Repository e @Controller

per esempio

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
    }
}
  • ogni volta che aggiungiamo @Serviceo @Repositroyo l' @Controllerannotazione per impostazione predefinita, l' @Componentannotazione diventerà in cima alla classe

23

Primavera offre quattro diversi tipi di annotazioni di scansione di componenti auto, sono @Component, @Service, @Repositorye @Controller. Tecnicamente, non vi è alcuna differenza tra loro, ma ogni annotazione di scansione dei componenti automatici deve essere utilizzata per uno scopo speciale e all'interno del livello definito.

@Component: Si tratta di un'annotazione di scansione del componente auto di base, indica che la classe annotata è un componente di scansione automatica.

@Controller: La classe annotata indica che si tratta di un componente controller e utilizzato principalmente a livello di presentazione.

@Service: Indica che la classe annotata è un componente del servizio nel livello aziendale.

@Repository: È necessario utilizzare questa annotazione all'interno del livello di persistenza, questo si comporta come un repository di database.

Si dovrebbe scegliere una forma più specializzata @Componentdurante l'annotazione della loro classe poiché questa annotazione può contenere comportamenti specifici in futuro.


20

Possiamo rispondere a questo secondo lo standard Java

Facendo riferimento a JSR-330, che ora è supportato da Spring, è possibile utilizzare solo @Namedper definire un bean (in qualche modo @Named=@Component). Quindi, secondo questo standard, ci sembra che non v'è alcuna utilità per definire gli stereotipi (come @Repository, @Service, @Controller) a fagioli categorie.

Ma primavera utente queste diverse annotazioni in diverse per l'uso specifico, ad esempio:

  1. Aiuta gli sviluppatori a definire una categoria migliore per i competenti. Questa categorizzazione può essere utile in alcuni casi. (Ad esempio quando si utilizza aspect-oriented, questi possono essere un buon candidato per pointcuts)
  2. @Repository l'annotazione aggiungerà alcune funzionalità al bean (una traduzione automatica delle eccezioni al layer di persistenza del bean).
  3. Se si utilizza Spring MVC, @RequestMappingpuò essere aggiunto solo alle classi annotate da @Controller.

Per quanto riguarda il tuo terzo punto. Non è vero. Posso aggiungere l'annotazione @RequestMapping anche ai metodi nella classe di servizio (intendo le classi annotate con @Service).
Rahul Gupta,

19

Annota altri componenti con @Component, ad esempio le classi di risorse REST.

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

@Component è uno stereotipo generico per qualsiasi componente gestito da Spring.

@Controller, @Service e @Repository sono specializzazioni di @Component per casi d'uso specifici.

@Component in Spring

"Specializzazione dei componenti"


18

Non v'è alcuna differenza tra @Component, @Service, @Controller, @Repository. @Componentè l'annotazione generica per rappresentare il componente del nostro MVC. Ma ci saranno diversi componenti come parte della nostra applicazione MVC come componenti del livello di servizio, componenti del livello di persistenza e componenti del livello di presentazione. Quindi, per differenziarli, le persone di Spring hanno dato anche le altre tre annotazioni.

  • Per rappresentare i componenti del livello di persistenza: @Repository
  • Per rappresentare i componenti del livello di servizio: @Service
  • Per rappresentare i componenti del livello di presentazione: @Controller
  • oppure puoi usarli @Componentper tutti loro.

17

Anche se scambiamo @Component o @Repository o @service

Si comporterà allo stesso modo, ma un aspetto è che non saranno in grado di rilevare alcune eccezioni specifiche relative a DAO anziché al repository se utilizziamo component o @ service


15

Nella primavera 4, ultima versione:

L'annotazione @Repository è un marcatore per qualsiasi classe che soddisfi il ruolo o lo stereotipo di un repository (noto anche come Data Access Object o DAO). Tra gli usi di questo indicatore c'è la traduzione automatica delle eccezioni come descritto nella Sezione 20.2.2, "Traduzione delle eccezioni".

Spring fornisce ulteriori annotazioni stereotipate: @Component, @Service e @Controller. @Component è uno stereotipo generico per qualsiasi componente gestito da Spring. @Repository, @Service e @Controller sono specializzazioni di @Component per casi d'uso più specifici, ad esempio nei livelli di persistenza, servizio e presentazione, rispettivamente. Pertanto, è possibile annotare le classi dei componenti con @Component, ma annotandole con @Repository, @Service o @Controller, le classi sono più adatte per l'elaborazione da parte di strumenti o l'associazione con aspetti. Ad esempio, queste annotazioni stereotipate sono obiettivi ideali per i tagli di punti. È anche possibile che @Repository, @Service e @Controller possano trasportare semantica aggiuntiva nelle versioni future di Spring Framework. Così, se si sceglie di utilizzare @Component o @Service per il proprio livello di servizio, @Service è chiaramente la scelta migliore. Allo stesso modo, come indicato sopra, @Repository è già supportato come marcatore per la traduzione automatica delle eccezioni nel livello di persistenza.


15

@Component : annoti una classe @Component, dice in letargo che è un fagiolo.

@Repository : annoti una classe @Repository, dice a ibernazione che è una classe DAO e la tratti come una classe DAO. Significa che le eccezioni non controllate (generate dai metodi DAO) possono essere tradotte in primavera DataAccessException.

@Servizio : questo dice a ibernazione che è una classe di servizio in cui si avrà @Transactionalecc. Annotazioni del livello di servizio, quindi ibernazione la tratta come un componente di servizio.

Plus @Serviceè anticipo di @Component. Supponiamo che il nome della classe del bean sia CustomerService, poiché non hai scelto il modo di configurazione del bean XML, quindi hai annotato il bean con @Componentper indicarlo come Bean. Quindi, mentre si ottiene l'oggetto bean CustomerService cust = (CustomerService)context.getBean("customerService");Per impostazione predefinita, Spring minuscola il primo carattere del componente, da "CustomerService" a "customerService". E puoi recuperare questo componente con il nome 'customerService'. Ma se si utilizza l' @Serviceannotazione per la classe bean, è possibile fornire un nome bean specifico per

@Service("AAA")
public class CustomerService{

e puoi ottenere l'oggetto bean da

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

13

@Component è l'annotazione generica di livello superiore che rende il bean annotato da scansionare e disponibile nel contenitore DI

@Repository è un'annotazione specializzata e offre la funzione di convertire tutte le eccezioni non controllate dalle classi DAO

@Serviceè un'annotazione specializzata. non porta nessuna nuova funzionalità a partire da ora ma chiarisce l'intento del bean

@Controller è un'annotazione specializzata che rende consapevole il bean MVC e consente l'utilizzo di ulteriori annotazioni simili @RequestMappinge simili

Ecco maggiori dettagli


11

A @Serviceper citare la documentazione di primavera,

Indica che una classe annotata è un "Servizio", originariamente definito da Domain-Driven Design (Evans, 2003) come "un'operazione offerta come interfaccia indipendente nel modello, senza stato incapsulato". Può anche indicare che una classe è una "Business Service Facade" (nel senso dei modelli Core J2EE) o qualcosa di simile. Questa annotazione è uno stereotipo per tutti gli usi e i singoli team possono restringere la loro semantica e utilizzare come appropriato.

Se guardi al design guidato dal dominio di eric evans,

Un SERVIZIO è un'operazione offerta come interfaccia indipendente nel modello, senza incapsulare lo stato, come fanno ENTITIES e VALUE OBJECTS. I SERVIZI sono un modello comune nei quadri tecnici, ma possono anche applicarsi a livello di dominio. Il servizio dei nomi enfatizza la relazione con altri oggetti. A differenza di ENTITIES e VALUE OBJECTS, è definito semplicemente in termini di cosa può fare per un cliente. Un SERVIZIO tende a essere nominato per un'attività, piuttosto che per un'entità: un verbo piuttosto che un sostantivo. Un SERVIZIO può ancora avere una definizione astratta e intenzionale; ha solo un sapore diverso rispetto alla definizione di un oggetto. Un SERVIZIO dovrebbe comunque avere una responsabilità definita e tale responsabilità e l'interfaccia che lo soddisfano dovrebbero essere definite come parte del modello di dominio. I nomi delle operazioni dovrebbero provenire dalla LINGUA UBIQUITOSA o essere introdotti al suo interno. I parametri e i risultati dovrebbero essere oggetti di dominio. I SERVIZI devono essere utilizzati con giudizio e non devono essere in grado di eliminare le ENTITÀ e gli VALORI OGGETTI di tutti i loro comportamenti. Ma quando un'operazione è in realtà un concetto di dominio importante, un SERVIZIO costituisce una parte naturale di un DESIGN MODELLO. Dichiarata nel modello come SERVIZIO, piuttosto che come oggetto fasullo che in realtà non rappresenta nulla, l'operazione autonoma non fuorvia nessuno. un SERVIZIO costituisce una parte naturale di un DESIGN MODELLO. Dichiarata nel modello come SERVIZIO, piuttosto che come oggetto fasullo che in realtà non rappresenta nulla, l'operazione autonoma non fuorvia nessuno. un SERVIZIO costituisce una parte naturale di un DESIGN MODELLO. Dichiarata nel modello come SERVIZIO, piuttosto che come oggetto fasullo che in realtà non rappresenta nulla, l'operazione autonoma non fuorvia nessuno.

e un Repositorysecondo Eric Evans,

Un REPOSITORY rappresenta tutti gli oggetti di un certo tipo come un insieme concettuale (solitamente emulato). Funziona come una raccolta, tranne con una capacità di query più elaborata. Vengono aggiunti e rimossi oggetti del tipo appropriato e il macchinario dietro il REPOSITORY li inserisce o li elimina dal database. Questa definizione raccoglie un insieme coerente di responsabilità per fornire l'accesso alle radici di AGGREGATES dal ciclo di vita iniziale fino alla fine.


11

Le risposte abbastanza buone sono qui per spiegare le annotazioni di che cosa è la differenza tra il componente repository-servizio. Vorrei condividere la differenza tra@Controller & @RestController

@Controller vs RestController

@RestController:

inserisci qui la descrizione dell'immagine

  • Questa annotazione è una versione specializzata di @Controllercui aggiunge @Controllere @ResponseBodyannotazione automaticamente. quindi non dobbiamo aggiungere @ResponseBodyai nostri metodi di mappatura. Questo significa @ResponseBody è attivo per impostazione predefinita.
  • Se si utilizza @RestControllernon è possibile restituire una vista (utilizzando Viewresolverin Spring / Spring-Boot)
  • @RestControllerconverte anche la risposta JSON/XML automaticallynel @ResponseBodyrendere gli oggetti restituiti in qualcosa che potrebbe essere nel corpo,e.g. JSON or XML

@Controller

inserisci qui la descrizione dell'immagine

  • @Controllerviene utilizzato per contrassegnare le classi come controller Spring MVC. Questa annotazione è solo una versione specializzata di @Componente consente di rilevare automaticamente le classi del controller in base alla scansione del percorso di classe.
  • @Controller puoi restituire una vista in Spring web MVC.

Vista più dettagliata


9

Il repository e il servizio sono elementi secondari dell'annotazione dei componenti . Quindi, sono tutti componenti . Repository and Service basta espanderlo. Come esattamente? Il servizio ha solo una differenza ideologica: lo usiamo per i servizi. Il repository ha un gestore delle eccezioni particolare.


6

Spiegazione degli stereotipi:

  • @Service- Annota tutte le tue classi di servizio con @Service. Questo livello conosce l'unità di lavoro. Tutta la tua logica aziendale sarà nelle classi di servizio. Generalmente i metodi del livello di servizio sono coperti dalla transazione. È possibile effettuare più chiamate DAO dal metodo di servizio, se una transazione non riesce tutte le transazioni dovrebbero essere ripristinate.
  • @Repository- Annota tutte le tue classi DAO con @Repository. Tutta la logica di accesso al database deve essere nelle classi DAO.
  • @Component - Annota gli altri componenti (ad esempio le classi di risorse REST) ​​con lo stereotipo del componente.
  • @Autowired - Lascia che Spring installi automaticamente altri bean nelle tue classi usando l'annotazione @Autowired.

@Componentè uno stereotipo generico per qualsiasi componente gestito da Spring. @Repository, @Servicee @Controllersono specializzazioni di @Componentcasi d'uso più specifici, ad esempio nei livelli di persistenza, servizio e presentazione, rispettivamente.

Originariamente risposto qui .


5

Differenza tra annotazioni @Component, @Repository, @Controller e @Service

@Component: generico e può essere utilizzato in tutta l'applicazione.
@Service: annota le classi a livello di livello di servizio.
@Controller: annota le classi a livello di livelli di presentazione, utilizzate principalmente in Spring MVC.
@Repository: annota le classi a livello di persistenza, che fungeranno da repository del database.

@Controller= @Component (Annotazione interna) + Funzionalità del livello di presentazione
@Service= @Component (Annotazione interna) + Funzionalità del livello di servizio
@Component= Componenti effettivi (bean)
@Repository= @Component (Annotazione interna) + Funzionalità del livello dati (utilizzare per la gestione dei bean di dominio)


3

In primavera framework fornisce alcuni tipi speciali di annotazioni, chiamate annotazioni stereotipate. Questi sono i seguenti: -

@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.

le annotazioni sopra dichiarate sono speciali perché quando aggiungiamo <context:component-scan>nel file xxx-servlet.xml, spring creerà automaticamente l'oggetto di quelle classi che sono annotate con l'annotazione sopra durante la fase di creazione / caricamento del contesto.


2

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

@Componentè uno stereotipo generico per i componenti gestiti entro la primavera @Repository, @Servicee @Controllersono @Componentspecializzazioni per altri usi specifici:

  • @Repository per persistenza
  • @Service per servizi e transazioni
  • @Controller per controller MVC

Perché usare @Repository, @Service, @Controllersopra @Component? Possiamo contrassegnare le nostre classi di componenti con @Component, ma se invece utilizziamo l'alternativa che si adatta alla funzionalità prevista. Le nostre classi sono più adatte alla funzionalità prevista in ciascun caso particolare.

Una classe annotata con @Repositoryha una traduzione migliore e una gestione degli errori leggibile con org.springframework.dao.DataAccessException. Ideale per l'implementazione di componenti che accedono ai dati (DataAccessObject o DAO).

Una classe con annotazioni @Controllersvolge un ruolo di controller in un'applicazione Spring Web MVC

Una classe con annotazioni @Servicesvolge un ruolo nei servizi di logica aziendale, ad esempio modello di facciata per DAO Manager (facciata) e gestione delle transazioni


2

Le risposte qui presentate sono in gran parte tecnicamente corrette, ma anche se l'elenco delle risposte è lungo e questo sarà in fondo, ho pensato che valesse la pena mettere anche una risposta effettivamente corretta qui, nel caso in cui qualcuno si imbattesse in esso e impari qualcosa di prezioso da esso. Non è che il resto delle risposte sia sbagliato, è solo che non sono corrette. E, per fermare le orde di troll, sì, so che tecnicamente queste annotazioni sono effettivamente la stessa cosa e le più intercambiabili fino alla primavera 5. Ora, per la risposta giusta:

Queste tre annotazioni sono cose completamente diverse e non sono intercambiabili. Puoi dirlo perché ce ne sono tre anziché uno solo. Non intendono essere intercambiabili, sono solo implementati in quel modo per eleganza e praticità.

La programmazione moderna è invenzione, arte, tecnica e comunicazione, in proporzioni diverse. Il bit di comunicazione è di solito molto importante perché il codice viene solitamente letto molto più spesso di quanto non sia scritto. Come programmatore non stai solo cercando di risolvere il problema tecnico, stai anche cercando di comunicare le tue intenzioni ai futuri programmatori che leggono il tuo codice. Questi programmatori potrebbero non condividere la tua lingua madre, né il tuo ambiente sociale, ed è possibile che possano leggere il tuo codice 50 anni in futuro (non è così improbabile come potresti pensare). È difficile comunicare in modo efficace così lontano nel futuro. Pertanto, è fondamentale utilizzare il linguaggio più chiaro, più efficiente, corretto e comunicativo a nostra disposizione.

Ad esempio, è fondamentale che @Repositoryvenga utilizzato quando stiamo scrivendo un repository, piuttosto che @Component. Quest'ultima è una pessima scelta di annotazione per un repository perché non indica che stiamo guardando un repository. Possiamo supporre che un repository sia anche un bean di primavera, ma non che un componente sia un repository. Con@Repository noi siamo chiari e specifici nella nostra lingua. Stiamo affermando chiaramente che questo è un repository. Con@Componentstiamo lasciando al lettore la scelta del tipo di componente che stanno leggendo e dovranno leggere l'intera classe (e possibilmente un albero di sottoclassi e interfacce) per dedurne il significato. La classe potrebbe quindi essere interpretata erroneamente da un lettore in un lontano futuro come non essere un repository, e saremmo stati parzialmente responsabili di questo errore perché noi, che sapevamo benissimo che si tratta di un repository, non siamo riusciti a essere specifici nella nostra lingua e comunicare efficacemente il nostro intento.

Non entrerò negli altri esempi, ma affermerò il più chiaramente possibile: queste annotazioni sono cose completamente diverse e dovrebbero essere usate in modo appropriato, secondo il loro intento. @Repositoryè per i repository di archiviazione e nessun'altra annotazione è corretta. @Serviceè per i servizi e nessun'altra annotazione è corretta. @Componentè per componenti che non sono né repository né servizi, e anche utilizzare uno di questi al suo posto sarebbe errato. Potrebbe compilarsi, potrebbe anche essere eseguito e superato i test, ma sarebbe sbagliato e penserei meno di te (professionalmente) se dovessi farlo.

Ci sono esempi di questo durante la primavera (e la programmazione in generale). Non è necessario utilizzare @Controllerquando si scrive un'API REST, perché @RestControllerè disponibile. Non è necessario utilizzare @RequestMappingquando @GetMappingè un'alternativa valida. Ecc ecc ecc Si deve scegliere la più specifica esatta e la lingua corretta possibile per comunicare l'intenzione di vostri lettori, in caso contrario, si stanno introducendo i rischi nel vostro sistema, e il rischio ha un costo.


ben detto e buon punto!
Andy,

1

Per semplificare questa illustrazione, consideriamo la tecnicità per caso d'uso, queste annotazioni vengono utilizzate per essere iniettate e, come ho detto letteralmente " Usato per essere iniettato ", ciò significa che se si sa come utilizzare l' iniezione di dipendenza "DI" e si dovresti, quindi cercherai sempre queste annotazioni e annotando le classi con questi tipi stereo , stai informando il contenitore DI per scansionarli per essere pronti per l'iniezione in altri luoghi, questo è l'obiettivo pratico.

Ora passiamo a ciascuno; prima @Servizio , se stai costruendo una logica per un caso aziendale specifico, devi separarla in un luogo che conterrà la tua logica aziendale, questo servizio è di classe normale o puoi usarlo come interfaccia se vuoi, ed è scritto come Questo

@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;
}

Tutti allo stesso modo quando li inietti, @Repository è un'interfaccia che applica l'implementazione per il modello di progettazione Repository Pattern Repository pattern , generalmente viene usato quando hai a che fare con un archivio dati o un database, e troverai che contiene più pronta implementazione per gestire le operazioni del database; può essere CrudRepository , JpaRepository ecc.

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

Finalmente @Component , questo è il modulo generico per i bean registrati in primavera, quella primavera è sempre alla ricerca del bean contrassegnato con @Component da registrare, quindi sia @Service che @Repository sono casi speciali di @Component, tuttavia il caso d'uso comune perché il componente è quando stai realizzando qualcosa di puramente tecnico non per coprire il caso aziendale diretto! come la formattazione delle date o il trasferimento del meccanismo di serializzazione delle richieste speciali e così via.


0

@Component funge da annotazione @Bean nella classe di configurazione, bean di registro nel contesto di primavera. Inoltre è genitore per le annotazioni @Service, @Repository e @Controller.

@Service , estende l'annotazione @Component e presenta solo differenze di denominazione.

@Repository : estende l'annotazione @Component e traduce tutte le eccezioni del database in DataAccessException .

@Controller - funge da controller nel modello MVC. Il dispatcher eseguirà la scansione di tali classi annotate alla ricerca di metodi mappati, rilevando le annotazioni di @RequestMapping.


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

Queste sono tutte annotazioni StereoType.Queste sono utili per rendere le nostre classi come fagioli primaverili in un contenitore di ioc,

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.