¿Dónde se debe mantener la anotación @Service? Interfaz o implementación?

Estoy desarrollando aplicaciones usando Spring. Estoy obligado a usar la anotación @Service . Tengo ServiceI y ServiceImpl manera que ServiceImpl implements ServiceI . Estoy confundido aquí sobre dónde debo guardar la anotación @Service .

¿Debo anotar la interfaz o la implementación con la anotación @Service ? ¿Cuáles son las diferencias entre estos dos enfoques?

Básicamente, anotaciones como @Service , @Repository , @Component , etc., todas tienen el mismo objective:

autodetección cuando se utiliza la configuración basada en anotaciones y el escaneo de classpath.

Según mi experiencia, siempre @Service anotación @Service en las interfaces o clases abstractas y anotaciones como @Component y @Repository para su implementación. Anotación de @Component que estoy usando en esas clases que sirve propósitos básicos, simples frijoles de spring, nada más. @Repository Anotación de @Repository que estoy usando en la capa DAO , por ejemplo, si tengo que comunicarme con la base de datos, tener algunas transacciones, etc.

Así que sugeriría anotar su interfaz con @Service y otras capas, dependiendo de la funcionalidad.

Nunca coloco @Component (o @Service , …) en una interfaz, porque esto hace que la interfaz sea inútil. Déjame explicar por qué.

reivindicación 1: si tiene una interfaz, entonces desea usar esa interfaz para el tipo de punto de inyección.

Reclamo 2: El propósito de una interfaz es que defina un contrato que pueda ser implementado por varias implementaciones. En el otro lado, tienes tu punto de inyección ( @Autowired ). Tener solo una interfaz y solo una clase que la implemente, es (en mi humilde opinión) inútil, y viola a YAGNI .

hecho: cuando pones:

  • @Component (o @Service , …) en una interfaz,
  • tener múltiples clases que lo implemente,
  • al menos dos clases se convierten en Spring Beans, y
  • tener un punto de inyección que use la interfaz para la inyección basada en tipo,

entonces obtendrá y NoUniqueBeanDefinitionException (o tendrá una configuración de configuraciones muy especial, con Entorno, Perfiles o Calificadores …)

Conclusión: si usa @Component (o @Service , …) en una interfaz, debe violar al menos una de las dos clanes. Por lo tanto, creo que no es útil (excepto en algunos casos excepcionales) poner @Component al nivel de la interfaz.


Las interfaces Spring-Data-JPA Repository son algo completamente diferente

Utilicé las anotaciones @Component, @Service, @Controller y @Repository solo en las clases de implementación y no en la interfaz. Pero la anotación @Autowired con interfaces todavía funcionaba para mí.

Las ventajas de poner una anotación en @Service es que da una pista de que es un servicio. No sé si alguna clase implementadora heredará esta anotación por defecto.

Lo bueno es que está acoplando su interfaz con un marco específico, es decir, Spring, mediante el uso de anotaciones específicas de spring. Dado que se supone que las interfaces deben estar desacopladas de la implementación, no recomendaría el uso de Anotaciones específicas del marco o parte del objeto de su interfaz.

Para hacerlo mas simple:

@Service es una anotación de estereotipo para la capa de servicio .

@Repository es una anotación de estereotipo para la capa de persistencia .

@Component es una anotación de estereotipo genérica que se usa para indicar a Spring que cree una instancia del objeto en el contexto de la aplicación. Es posible definir cualquier nombre para la instancia, el valor predeterminado es el nombre de la clase como camel case.

Un beneficio de la spring es cambiar fácilmente la implementación del Servicio (u otra). Para esto, debe anotar en la interfaz y declarar una variable como esta:

 @Autowired private MyInterface myVariable; 

y no :

 @Autowired private MyClassImplementationWhichImplementsMyInterface myVariable; 

Como en el primer caso, puede activar qué implementación inyectar desde el momento en que es única (solo una clase implementa la interfaz). En el segundo caso, necesita refactorizar todo su código (la nueva implementación de clase tiene otro nombre). Como consecuencia, la anotación debe estar en la interfaz tanto como sea posible. Además, los proxys JDK son adecuados para esto: se crean y se crean instancias al inicio de la aplicación porque el tipo de tiempo de ejecución se conoce por adelantado, al contrario que los proxies CGlib.

Hay 5 anotaciones que podrían usarse para hacer frijoles spring. Haga una lista debajo de las respuestas.

¿Realmente necesitas una interfaz? Si va a tener una implementación para cada interfaz de servicio, simplemente evítela, use solo clase. Por supuesto, si no tiene RMI o si se requiere proxy de interfaz.

@Repository: utilícelo para inyectar sus clases de capa dao.

@Service: utilícelo para inyectar sus clases de capa de servicio. En la capa de servicio también es posible que necesite usar la anotación @Transactional para la gestión de transacciones db.

@Controller: utilícelo para los controladores de capa frontend, como los beans administrados JSF que se inyectan como beans de spring.

@RestController: utilícelo para los controladores de reposo de la spring, esto le ayudaría a evitar cada vez que coloque las anotaciones @ResponseBody y @RequestBody en sus métodos de descanso.

@Component: úsalo en cualquier otro caso cuando necesites Inyectar Spring Bean que no sea controlador, servicio o clase dao