Je développe une application avec Spring. Je suis obligé d'utiliser l' @Service
annotation. J'ai ServiceI
et ServiceImpl
tel que ServiceImpl implements ServiceI
. Je ne sais pas où dois-je conserver l' @Service
annotation.
Dois-je annoter l'interface ou l'implémentation avec @Service
? Quelles sont les différences entre ces deux approches?
Réponses:
Je n'ai jamais mis
@Component
(ou@Service
, ...) sur une interface, car cela rend l'interface inutile. Laissez-moi vous expliquer pourquoi.revendication 1: si vous avez une interface, vous souhaitez utiliser cette interface pour le type de point d'injection.
revendication 2: Le but d'une interface est de définir un contrat qui peut être implémenté par plusieurs implémentations. De l'autre côté, vous avez votre point d'injection (
@Autowired
). Avoir juste une interface et une seule classe qui l'implémente, est (IMHO) inutile et viole YAGNI .fait: Lorsque vous mettez:
@Component
(ou@Service
, ...) à une interface,alors vous obtiendrez et
NoUniqueBeanDefinitionException
(ou vous avez une configuration de configurations très spéciale, avec environnement, profils ou qualificatifs ...)Conclusion: Si vous utilisez
@Component
(ou@Service
, ...) sur une interface, vous devez violer au moins l'un des deux clains. Par conséquent je pense qu'il n'est pas utile (sauf quelques rares scénarios) de le mettre@Component
au niveau de l'interface.Les interfaces Spring-Data-JPA Repository sont quelque chose de complètement différent
la source
@Transactional
est l'un des exemples d'utilisation d'un proxy vers un bean. AOP en est un autre.Fondamentalement, des annotations telles que @Service , @Repository , @Component , etc., elles ont toutes le même objectif:
D'après mon expérience, j'utilise toujours des
@Service
annotations sur les interfaces ou des classes abstraites et des annotations comme@Component
et@Repository
pour leur implémentation.@Component
annotation que j'utilise sur ces classes qui servent des objectifs basiques, de simples Spring beans, rien de plus.@Repository
annotation que j'utilise dans laDAO
couche, par exemple si je dois communiquer avec la base de données, effectuer des transactions, etc.Je suggérerais donc d'annoter votre interface avec les
@Service
couches et d'autres en fonction de la fonctionnalité.la source
Je
@Component
,@Service
,@Controller
et les@Repository
annotations que sur les classes de mise en œuvre et non pas sur l'interface. Mais l'@Autowired
annotation avec les interfaces fonctionnait toujours pour moi.la source
L'avantage de mettre une annotation sur @Service est que cela donne un indice qu'il s'agit d'un service. Je ne sais pas si une classe d'implémentation héritera par défaut de cette annoation.
L'inconvénient est que vous associez votre interface à un cadre spécifique, à savoir Spring, en utilisant une annotation spécifique au ressort. Comme les interfaces sont censées être découplées de l'implémentation, je ne suggérerais pas d'utiliser des annotations spécifiques au framework ou une partie objet de votre interface.
la source
L'un des avantages du ressort est de changer facilement la mise en œuvre du service (ou autre). Pour cela, vous devez annoter sur l'interface et déclarer une variable comme ceci:
et pas :
Comme dans le premier cas, vous pouvez activer quelle implémentation injecter à partir du moment où elle est unique (une seule classe implémente l'interface). Dans le second cas, vous devez refactoriser tout votre code (la nouvelle implémentation de classe a un autre nom). En conséquence, l'annotation doit être autant que possible sur l'interface. De plus, les proxies JDK sont bien adaptés pour cela: ils sont créés et instanciés au démarrage de l'application car le type d'exécution est connu d'avance, contrairement aux proxies CGlib.
la source
@Service
une implémentation et activer automatiquement l'interface. Spring recherchera tout objet implémentant cette interface.Je mettrais
@Service
votre classe mais mettre le nom de l'interface comme paramètre de l'annotation par exempleEn faisant cela, vous obtenez tous les avantages et pouvez toujours injecter l'interface mais obtenir la classe
Ainsi, votre interface n'est pas liée au framework Spring et vous pouvez changer de classe à tout moment et ne pas avoir à mettre à jour tous vos points d'injection.
Donc, si je voulais changer la classe d'implémentation, je pourrais simplement annoter la nouvelle classe et supprimer de la première, mais c'est tout ce qu'il faut changer. Si vous injectez la classe, vous pourriez avoir beaucoup de travail quand vous voulez changer la classe impl.
la source
Pour le dire simplement:
@Service est une annotation Stéréotype pour la couche de service .
@Repository est une annotation de stéréotype pour la persistance couche.
@Component est une annotation stéréotype générique utilisée pour indiquer à Spring de créer une instance de l'objet dans le contexte d'application. Il est possible de définir n'importe quel nom pour l'instance, la valeur par défaut est le nom de la classe comme cas camel.
la source
Il y a 5 annotations qui pourraient être utilisées pour faire des haricots de printemps. Liste ci-dessous des réponses.
Avez-vous vraiment besoin d'une interface? Si vous prévoyez d'avoir une implémentation pour chaque interface de service, évitez-la, utilisez uniquement la classe. Bien sûr, si vous n'avez pas RMI ou lorsqu'un proxy d'interface est requis.
@Repository - à utiliser pour injecter vos classes de couche DAO.
@Service - à utiliser pour injecter vos classes de couche de service. Dans la couche de service, vous devrez peut-être également utiliser l'annotation @Transactional pour la gestion des transactions db.
@Controller - à utiliser pour vos contrôleurs de couche frontale, tels que les beans gérés JSF injectés en tant que beans spring.
@RestController - à utiliser pour les contrôleurs de repos à ressort, cela vous aiderait à éviter à chaque fois de mettre des annotations @ResponseBody et @RequestBody dans vos méthodes de repos.
@Component - utilisez-le dans tous les autres cas lorsque vous avez besoin d'injecter un haricot de printemps qui n'est pas une classe de contrôleur, de service ou de DAO
la source