Estoy desarrollando una aplicación usando Spring. Estoy obligado a usar la @Service
anotación. Tengo ServiceI
y ServiceImpl
tal que ServiceImpl implements ServiceI
. Aquí estoy confundido sobre dónde debo guardar la @Service
anotación.
¿Debo anotar la interfaz o la implementación con @Service
? ¿Cuáles son las diferencias entre estos dos enfoques?
Respuestas:
Nunca puse
@Component
(o@Service
...) en una interfaz, porque esto hace que la interfaz sea inútil. Déjame explicarte por qué.reclamo 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 implementarse mediante varias implementaciones. En el otro lado tienes tu punto de inyección (
@Autowired
). Tener solo una interfaz y solo una clase que lo implemente, es (en mi humilde opinión) inútil, y viola YAGNI .hecho: cuando pones:
@Component
(o@Service
...) en una interfaz,entonces obtendrá y
NoUniqueBeanDefinitionException
(o tiene una configuración de configuraciones muy especial, con Entorno, Perfiles o Calificadores ...)Conclusión: Si usa
@Component
(o@Service
...) en una interfaz, entonces debe violar al menos una de las dos claves. Por lo tanto, creo que no es útil (excepto algunos escenarios raros) poner@Component
a nivel de interfaz.Las interfaces Spring-Data-JPA Repository son algo completamente diferente
fuente
@Transactional
es uno de los ejemplos en los que se usa un proxy para un bean. AOP es otro.Básicamente, las anotaciones como @Service , @Repository , @Component , etc. todas tienen el mismo propósito:
Desde mi experiencia, siempre estoy usando
@Service
anotaciones en las interfaces o clases abstractas y anotaciones como@Component
y@Repository
para su implementación.@Component
anotación que estoy usando en esas clases que sirve para propósitos básicos, simples Spring beans, nada más.@Repository
anotación que estoy usando en laDAO
capa, por ejemplo, si tengo que comunicarme a la base de datos, realizar algunas transacciones, etc.Por lo tanto, sugeriría anotar su interfaz con las
@Service
capas y otras dependiendo de la funcionalidad.fuente
Solía
@Component
,@Service
,@Controller
y@Repository
las anotaciones sólo en las clases de implementación y no en la interfaz. Pero la@Autowired
anotación con Interfaces todavía funcionó para mí.fuente
La ventaja de poner anotaciones en @Service es que da una pista de que es un servicio. No sé si alguna clase implementadora heredará esta anotación por defecto.
El lado negativo es que está acoplando su interfaz con un marco específico, es decir, Spring, mediante el uso de anotaciones específicas de Spring. Como se supone que las interfaces deben estar desacopladas de la implementación, no sugeriría usar Anotaciones específicas del marco o parte del objeto de su interfaz.
fuente
Un beneficio de spring es cambiar fácilmente la implementación del Servicio (u otra). Para esto, debe realizar anotaciones en la interfaz y declarar variables como esta:
y no :
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, debe refactorizar todo su código (la implementación de la nueva 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 crean instancias al inicio de la aplicación porque el tipo de tiempo de ejecución se conoce por adelantado, a diferencia de los proxies CGlib.
fuente
@Service
una implementación y conectar automáticamente la interfaz. Spring verificará cualquier objeto que implemente esta interfaz.Pondría
@Service
en su clase, pero puse el nombre de la interfaz como parámetro de la anotación, por ejemploAl hacerlo, obtienes todos los beneficios y aún puedes inyectar la interfaz, pero obtienes la clase
Por lo tanto, su interfaz no está vinculada a Spring Framework y puede cambiar la clase en cualquier momento y no tener que actualizar todos sus puntos de inyección.
Entonces, si quisiera cambiar la clase de implementación, podría simplemente anotar la nueva clase y eliminarla de la primera, pero eso es todo lo que se debe cambiar. Si inyecta la clase, podría tener mucho trabajo cuando quiera cambiar la clase impl.
fuente
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 persistencia capa.
@Component es una anotación de estereotipo genérico utilizada para indicarle 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 caso de camello.
fuente
Hay 5 anotaciones que podrían usarse para hacer frijoles de primavera. Enumere a continuación las respuestas.
¿Realmente necesitas una interfaz? Si va a tener una implementación para cada interfaz de servicio, simplemente evítela, use solo la clase. Por supuesto, si no tiene RMI o cuando se requiere un 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 deba usar la anotación @Transactional para la gestión de transacciones de db.
@Controller: utilícelo para sus controladores de capa frontend, como los beans administrados por JSF que se inyectan como beans spring.
@RestController: utilícelo para los controladores de reposo de resorte, esto lo ayudaría a evitar cada vez que incluya anotaciones @ResponseBody y @RequestBody en sus métodos de descanso.
@Component: utilícelo en cualquier otro caso cuando necesite inyectar spring bean que no sea controlador, servicio o clase dao
fuente