Uso Spring @Autowired

218

¿Cuáles son los pros y los contras de usar @Autowired en una clase que estará conectada por Spring?

Solo para aclarar, estoy hablando específicamente de la anotación @Autowired , no del cableado automático en XML.

Probablemente no lo entiendo, pero para mí casi parece un antipatrón: sus clases comienzan a darse cuenta de que están vinculadas a un marco DI, en lugar de ser solo POJO. Tal vez soy un glotón para el castigo, pero me gusta tener la configuración XML externa para beans, y me gusta tener conexiones explícitas, así que sé exactamente qué está conectado dónde.

Andy White
fuente
44
También estoy interesado en este tema: configurar su aplicación MVC a través de anotaciones en lugar de XML parece que llevaría a una gran búsqueda de "¿qué clase está asignada a esta URL?" "¿Quién está manejando esto?". Me gusta tener una sola fuente de configuración
matt b
66
el término "@Autowiring" parece ser engañoso aquí. Como también puede realizar el cableado automático con configuración XML, la pregunta original debe reformularse como "Pros y contras del uso de anotaciones Spring". La respuesta proporcionada se centra más en los aspectos del cableado automático y menos en los aspectos del uso de anotaciones.
Neeme Praks
Posible duplicado de Understanding Spring @ Uso
automático

Respuestas:

253

Durante mucho tiempo creí que había un valor en tener una "configuración centralizada y declarativa" como los archivos xml que todos solíamos usar. Entonces me di cuenta de que la mayoría de las cosas en los archivos no eran configuración , nunca cambiaron en ningún lugar después del desarrollo, nunca. Entonces me di cuenta de que "centralizado" solo tiene valor en sistemas bastante pequeños: solo en sistemas pequeños podrá alguna vez asimilar un archivo de configuración en su conjunto . ¿Y cuál es realmente el valor de entender el cableado en su conjunto, cuando los mismos "cables" se duplican principalmente por dependencias en el código? Entonces, lo único que he guardado son los metadatos (anotaciones), que todavía son un poco declarativos. Estos nunca cambian en tiempo de ejecución y nunca datos de "configuración" que alguien cambiará sobre la marcha, así que creo que mantenerlo en el código es bueno.

Utilizo el cableado automático completo tanto como puedo. Me encanta. No volveré a la primavera antigua a menos que me amenacen a punta de pistola. Mis razones para preferir completamente @Autowiredhan cambiado con el tiempo.

En este momento, creo que la razón más importante para usar el cableado automático es que hay una abstracción menos en su sistema para realizar un seguimiento. El "nombre del bean" desapareció efectivamente. Resulta que el nombre del bean solo existe debido a xml. Entonces, una capa completa de indirecciones abstractas (donde conectarías el nombre del frijol "foo" en la "barra" del frijol) ha desaparecido. Ahora conecto la interfaz "Foo" directamente a mi bean, y la implementación se elige por perfil de tiempo de ejecución. Esto me permite trabajar con código al rastrear dependencias e implementaciones. Cuando veo una dependencia con conexión automática en mi código, puedo presionar la tecla "ir a implementación" en mi IDE y aparece la lista de implementaciones conocidas. En la mayoría de los casos, solo hay una implementación y estoy directamente en la clase. Poder' qué implementación se está utilizando (afirmo que lo contrario está más cerca de la verdad con el cableado xml, ¡es curioso cómo cambia su perspectiva!)

Ahora se podría decir que es solo una capa muy simple, pero cada capa de abstracción que agregamos a nuestros sistemas aumenta la complejidad. Realmente no creo que el xml haya agregado ningún valor real a ningún sistema con el que he trabajado.

La mayoría de los sistemas con los que he trabajado solo tienen una configuración del entorno de tiempo de ejecución de producción. Puede haber otras configuraciones para la prueba, etc.

Diría que el cableado automático completo es el rubí sobre rieles de la primavera: abarca la noción de que hay un patrón de uso normal y común que la mayoría de los casos de uso siguen. Con la configuración XML usted permite una gran cantidad de uso de configuración coherente / inconsistente que puede / no ser intencionado. He visto tanta configuración xml exagerada con inconsistencias: ¿se refactoriza junto con el código? Pensé que no. ¿Están esas variaciones allí por alguna razón? Usualmente no.

Apenas usamos calificadores en nuestra configuración, y encontramos otras formas de resolver estas situaciones. Esta es una clara "desventaja" que encontramos: hemos cambiado ligeramente la forma en que codificamos para que interactúe de manera más fluida con el cableado automático: un repositorio de clientes ya no implementa la Repository<Customer>interfaz genérica , pero creamos una interfaz CustomerRepositoryque se extiende Repository<Customer>. A veces también hay uno o dos trucos cuando se trata de subclasificar. Pero por lo general, solo nos apunta en la dirección de una escritura más fuerte, lo que creo que casi siempre es una mejor solución.

Pero sí, usted está atando a un estilo particular de DI que la mayoría de la primavera hace. Ya ni siquiera hacemos setters públicos para dependencias (por lo que podría argumentar que estamos en +1 en el departamento de encapsulación / ocultación de información) Todavía tenemos algo de xml en nuestro sistema, pero el xml básicamente solo contiene las anomalías. El cableado automático completo se integra muy bien con xml.

Lo único que necesitamos ahora es para el @Component, @Autowiredy el resto a ser incluidos en un JSR (como JSR-250 ), por lo que no tenemos para empatar con la primavera. Esta es la forma en que las cosas han estado sucediendo en el pasado (las java.util.concurrentcosas me vienen a la mente), por lo que no me sorprendería por completo si esto sucediera nuevamente.

krosenvold
fuente
55
Javax.annotation / javax.inject es compatible con spring, por lo que no es necesario que el código dependa de Spring.
Michael Wiles
26

Para mí, esto es lo que me gusta / no me gusta de Spring y el cableado automático.

Pros:

  • El cableado automático elimina la configuración XML desagradable.
  • Anotaciones mucho más fáciles de usar que le permiten inyectar directamente usando campos, métodos de establecimiento o constructores. También le permite anotar y 'calificar' sus granos inyectados.

Contras:

  • El uso del cableado automático y las anotaciones lo hacen dependiente de las bibliotecas de Spring donde, al igual que con la configuración XML, puede elegir ejecutar con o sin Spring. Como dijiste, te atas a un marco DI.
  • Al mismo tiempo, me gusta poder 'calificar' los beans, para mí esto hace que el código sea realmente desordenado. Si necesita inyectar el mismo bean en varios lugares, he visto el mismo nombre de cadena repetido por todas partes. Para mí, esto parece tener el potencial de errores.

Comencé a usar el cableado automático casi exclusivamente en el trabajo porque de todos modos dependemos tanto de la integración de Spring que el problema de dependencia es discutible. Trabajé en un proyecto Spring MVC que usaba mucho el cableado automático y era un poco difícil de entender.

Creo que el cableado automático es un gusto adquirido, una vez que te acostumbras te das cuenta de lo poderoso, fácil y mucho menos dolor de cabeza que es trabajar que la configuración XML.

Jared Knipp
fuente
3
la configuración de xml se vuelve mucho menos desagradable si usa Springsource Tool Suite, que presenta autocompletado, gráficos de frijoles, etc.
Sean Patrick Floyd
¡Estoy totalmente de acuerdo con usted en que el cableado automático se vuelve desordenado y depende de las bibliotecas de Spring! Nunca he usado la configuración XML y estoy pensando que tal vez debería ir por ese camino.
James111
15

Estamos cambiando de @Autowire a la configuración XML en nuestro gran proyecto. El problema es un rendimiento de arranque muy bajo. El escáner de cableado automático carga todas las clases de la ruta de clase de búsqueda de cableado automático, por lo que muchas clases se cargan ansiosamente durante la inicialización de Spring.

Masterhard
fuente
1
Descubrí que javaconfig podría incluso ser una mejor solución para iniciar contextos parciales, lo cual es una gran victoria. Pero puede combinarlos con bastante facilidad usando @ Autowired / @ Inject en constructores (en otras palabras, cambie a inyección de constructor).
krosenvold
6

Ha habido muy poca discusión sobre el cambio de entornos. La mayoría de los proyectos en los que he trabajado fue un problema real para inyectar dependencias dependiendo del entorno en el que estamos trabajando. Con la configuración xml es bastante sencillo con Spring EL, y no conozco ninguna solución agradable con anotaciones. Acabo de descubrir uno:

    @Value("#{${env} == "production" ? realService : dummyService}")
    private SomeService service;

Debería estar funcionando, pero no es una buena solución en mi humilde opinión.

BTakacs
fuente
Abrí un hilo separado sobre esto, y hay una solución con Spring @Profilesy @Configuration: blog.springsource.org/2011/02/14/… Vea también el otro hilo: stackoverflow.com/questions/13490393/…
BTakacs
4

Me he cambiado a @Autowire. Mantener la configuración XML en cualquier cosa que no sea un proyecto pequeño se convirtió en una tarea en sí misma y la comprensión se degradó rápidamente.

IntelliJ proporciona un buen soporte (no perfecto) para las anotaciones de Spring.

Paul McKenzie
fuente
3

Mi opinión sobre este tema es que la configuración xml reduce la claridad del código, especialmente en sistemas grandes.

Anotaciones como @Component empeoran aún más las cosas. Dirige a los desarrolladores a hacer que los objetos sean mutables, ya que las dependencias ya no se pueden hacer definitivas, dado que se deben proporcionar los constructores predeterminados. Las dependencias deben ser inyectadas a través de setter público o no controladas a través de @Autowired. [aún peor, la inyección de dependencias se ve comprometida con clases que crean instancias de sus dependencias, ¡todavía veo esto en el código recién escrito!]. Por no controlado, quiero decir, en sistemas grandes, cuando hay disponibles múltiples implementaciones (o hijos) del tipo, se involucra mucho más entender cuál de las implementaciones era @Autowired, una complejidad que hace que la investigación de errores sea mucho más difícil. También significa que, supuestamente, tiene un perfil para el entorno de prueba y otro para la producción,

Me quedo en el punto medio donde declaro mi (s) clase (s) de configuración (configuración de Spring basada en Java usando @Configuration)

Declaro todos mis beans explícitamente en las clases de configuración. Solo uso @Autowired en la (s) clase (s) de configuración, el propósito es limitar la dependencia de Spring a la (s) clase (s) de configuración

La @Configuration reside en un paquete específico, ese es el único lugar donde se ejecuta la exploración de primavera. (Eso acelera el tiempo de inicio sustancialmente en grandes proyectos)

Me esfuerzo por hacer que todas mis clases sean inmutables, especialmente el objeto de datos, JPA, Hibernate y Spring, así como muchas bibliotecas de serialización parecen socavar esto. Me alejo de cualquier cosa que me obligue a proporcionar setters, o elimine la palabra clave final de mi declaración de propiedad.

La reducción de las posibilidades de cambiar los objetos después de su creación, reduce sustancialmente los errores en el sistema grande y reduce el tiempo para encontrar un error cuando existe.

También parece que obliga al desarrollador a diseñar mejor la interacción entre las diferentes partes del sistema. Los problemas y errores se vuelven cada vez más errores de compilación, lo que reduce el tiempo perdido y mejora la productividad.

Charbel
fuente
1

Estas son algunas de las ventajas de la experiencia

  • Hace que sea más fácil de configurar porque solo podemos usar la anotación @Autowire
  • No quiero usar métodos de establecimiento, por lo que la clase será más limpia

Contras

  • Apretar el archivo xml aunque estemos usando DI
  • Implementación difícil de encontrar (pero si estás usando buenas ideas como intellij, seguro puedes deshacerte de esto)

A partir de mis experiencias personales, no utilicé mucho la anotación @AutoWire, sino en casos de prueba.

Rajith Delantha
fuente
1

Realmente me encanta escribir con anotaciones, en lugar de XML. Según el manual de Spring y las últimas versiones, XML y Annotation lograron el mismo resultado.

Esta es mi lista

Pro:

  • Eliminar línea inútil de xml
  • Simplifique la depuración del código: cuando abre una clase, puede leer lo que tiene en la clase
  • ¿Desarrollo más rápido, un proyecto con 400 o más líneas de XML es legible?

Contras:

  • No es una implementación estándar de Java, pero puede cambiar para usar @Inject, que es una API estándar de Java, por lo que el bean sigue siendo un Pojo
  • No se puede usar simplemente en todas partes, conexión db, etc., pero es solo una opinión, prefiero tener un lugar donde leer toda la configuración.
Luca Preziati
fuente
0

Según tengo entendido, @Autowired es el mejor para usar mientras se hace referencia a la referencia de interfaz y utiliza sus funciones de anulación, pero solo encuentro un problema con esto es que a veces se asigna a nulo en tiempo de ejecución.

Shubham Kapoor
fuente