Estou desenvolvendo um aplicativo usando o Spring. Eu sou obrigado a usar a @Service
anotação. Eu tenho ServiceI
e ServiceImpl
tal que ServiceImpl implements ServiceI
. Estou confuso aqui sobre onde devo guardar a @Service
anotação.
Devo anotar a interface ou a implementação @Service
? Quais são as diferenças entre essas duas abordagens?
Respostas:
Eu nunca coloco
@Component
(ou@Service
...) em uma interface, porque isso torna a interface inútil. Deixe-me explicar o porquê.reivindicação 1: se você possui uma interface, deseja usá-la para o tipo de ponto de injeção.
reivindicação 2: O objetivo de uma interface é definir um contrato que pode ser implementado por várias implementações. Por outro lado, você tem seu ponto de injeção (
@Autowired
). Ter apenas uma interface e apenas uma classe que a implementa é (IMHO) inútil e viola o YAGNI .fato: Quando você coloca:
@Component
(ou@Service
...) em uma interface,você receberá e
NoUniqueBeanDefinitionException
(ou você terá uma configuração muito especial, com Ambiente, Perfis ou Qualificadores ...)Conclusão: Se você usa
@Component
(ou@Service
...) em uma interface, deve violar pelo menos um dos dois clains. Portanto, acho que não é útil (exceto alguns cenários raros) colocar@Component
no nível da interface.As interfaces Spring-Data-JPA Repository são algo completamente diferentes
fonte
@Transactional
é um dos exemplos em que um proxy para um bean é usado. AOP é outro.Basicamente, anotações como @Service , @Repository , @Component etc., todas elas têm o mesmo objetivo:
Pela minha experiência, estou sempre usando
@Service
anotações nas interfaces ou classes abstratas e anotações como@Component
e@Repository
para sua implementação.@Component
anotação que estou usando nessas classes que servem a propósitos básicos, simples Spring beans, nada mais.@Repository
anotação que estou usando naDAO
camada, por exemplo, se eu tiver que me comunicar com o banco de dados, ter algumas transações, etc.Então, sugiro anotar sua interface com as
@Service
outras camadas, dependendo da funcionalidade.fonte
Eu costumava
@Component
,@Service
,@Controller
e@Repository
anotações apenas nas classes de implementação e não na interface. Mas a@Autowired
anotação com Interfaces ainda funcionava para mim.fonte
Prós de colocar anotações no @Service é que ele dá uma dica de que é um serviço. Não sei se alguma classe de implementação herdará por padrão essa anotação.
O lado negativo é que você está acoplando sua interface a uma estrutura específica, ou seja, Spring, usando anotações específicas da mola. Como as interfaces devem ser dissociadas da implementação, eu não sugeriria o uso de nenhuma anotação específica da estrutura ou parte do objeto da sua interface.
fonte
Um benefício da primavera é alternar facilmente a implementação do Serviço (ou outro). Para isso, é necessário anotar na interface e declarar variáveis assim:
e não :
Como o primeiro caso, você pode ativar qual implementação injetar a partir do momento em que é exclusiva (apenas uma classe implementa a interface). No segundo caso, você precisa refatorar todo o seu código (a nova implementação de classe tem outro nome). Como conseqüência, a anotação precisa estar na interface o máximo possível. Além disso, os proxies JDK são adequados para isso: eles são criados e instanciados na inicialização do aplicativo porque o tipo de tempo de execução é conhecido antecipadamente, ao contrário dos proxies CGlib.
fonte
@Service
uma implementação e conectar automaticamente a interface. O Spring verificará qualquer objeto que implemente essa interface.Eu colocaria
@Service
na sua classe, mas colocaria o nome da interface como parâmetro na anotação, por exemploAo fazer isso, você obtém todos os benefícios e ainda pode injetar a interface, mas obtém a classe
Portanto, sua interface não está vinculada à estrutura da primavera e você pode alterar a classe a qualquer momento e não precisa atualizar todos os seus pontos de injeção.
Portanto, se eu quisesse alterar a classe de implementação, poderia apenas anotar a nova classe e removê-la da primeira, mas isso é tudo o que precisa ser alterado. Se você injetar a classe, poderá ter muito trabalho sempre que quiser alterar a classe impl.
fonte
Simplificando:
@Service é uma anotação de estereótipo para a camada de serviço .
@Repository é uma anotação estereótipo para a persistência camada.
@Component é uma anotação de estereótipo genérico usada para dizer ao Spring para criar uma instância do objeto no Contexto do Aplicativo. É possível definir qualquer nome para a instância, o padrão é o nome da classe como case camel.
fonte
Existem 5 anotações que podem ser usadas para fazer feijões de primavera. Listar abaixo das respostas.
Você realmente precisa de uma interface? Se você tiver uma implementação para cada interface de serviço, evite-a, use apenas classe. Obviamente, se você não possui RMI ou quando o proxy da interface é necessário.
@Repository - use para injetar suas classes de camadas dao.
@ Service - use para injetar suas classes de camada de serviço. Na camada de serviço também pode ser necessário usar a anotação @Transactional para o gerenciamento de transações do banco de dados.
@ Controlador - use para seus controladores de camada de front-end, como beans gerenciados por JSF, injetando como beans de primavera.
@RestController - use para controladores de descanso de primavera, isso ajudará você a evitar sempre colocar anotações @ResponseBody e @RequestBody em seus métodos de descanso.
@Component - use-o em qualquer outro caso, quando você precisar injetar Spring Bean, que não é da classe controller, service ou dao
fonte