TL; DR
La anotación @Autowired le ahorra la necesidad de realizar el cableado usted mismo en el archivo XML (o de cualquier otra manera) y simplemente encuentra lo que necesita inyectarse en dónde y lo hace por usted.
Explicación completa
La @Autowired
anotación le permite omitir configuraciones en otros lugares de qué inyectar y simplemente lo hace por usted. Suponiendo que su paquete com.mycompany.movies
tiene que poner esta etiqueta en su XML (archivo de contexto de la aplicación):
<context:component-scan base-package="com.mycompany.movies" />
Esta etiqueta hará un escaneo automático. Suponiendo que cada clase que tiene que convertirse en un bean se anota con una anotación correcta como @Component
(para bean simple) o @Controller
(para un control de servlet) o @Repository
(para DAO
clases) y estas clases están en algún lugar debajo del paquete com.mycompany.movies
, Spring encontrará todo esto y creará un frijol para cada uno Esto se realiza en 2 escaneos de las clases: la primera vez que solo busca clases que necesitan convertirse en un bean y mapea las inyecciones que necesita estar haciendo, y en el segundo escaneo inyecta los beans. Por supuesto, puede definir sus beans en el archivo XML más tradicional o con una clase @Configuration (o cualquier combinación de los tres).
La @Autowired
anotación le dice a Spring dónde debe ocurrir una inyección. Si lo pones en un método setMovieFinder
, entiende (por el prefijo set
+ la @Autowired
anotación) que se necesita inyectar un bean. En la segunda exploración, Spring busca un bean de tipo MovieFinder
y, si lo encuentra, lo inyecta a este método. Si encuentra dos de esos frijoles, obtendrá un Exception
. Para evitarlo Exception
, puede usar la @Qualifier
anotación y decirle cuál de los dos frijoles inyectar de la siguiente manera:
@Qualifier("redBean")
class Red implements Color {
// Class code here
}
@Qualifier("blueBean")
class Blue implements Color {
// Class code here
}
O si prefiere declarar los beans en su XML, se vería así:
<bean id="redBean" class="com.mycompany.movies.Red"/>
<bean id="blueBean" class="com.mycompany.movies.Blue"/>
En la @Autowired
declaración, también debe agregar el @Qualifier
para decir cuál de los dos granos de color para inyectar:
@Autowired
@Qualifier("redBean")
public void setColor(Color color) {
this.color = color;
}
Si no desea usar dos anotaciones (la @Autowired
y @Qualifier
) puede @Resource
combinar estas dos:
@Resource(name="redBean")
public void setColor(Color color) {
this.color = color;
}
El @Resource
(puede leer algunos datos adicionales al respecto en el primer comentario de esta respuesta) le ahorra el uso de dos anotaciones y en su lugar solo usa una.
Solo agregaré dos comentarios más:
- Una buena práctica sería usarlo en
@Inject
lugar de hacerlo @Autowired
porque no es específico de Spring y es parte del JSR-330
estándar .
- Otra buena práctica sería colocar
@Inject
/ @Autowired
en un constructor en lugar de un método. Si lo pones en un constructor, puedes validar que los beans inyectados no son nulos y fallan rápidamente cuando intentas iniciar la aplicación y evitar NullPointerException
cuando necesitas usar el bean.
Actualización : para completar la imagen, creé una nueva pregunta sobre la @Configuration
clase.
MovieFinder
es una interfaz, y tenemos un bean paraMovieFinderImpl
(bean id = movieFinder), ¿Spring lo inyectará automáticamente por tipo o por nombre?@Qualifier
. Si lo hace, por nombre, si no, por tipo. Por tipo funcionaría solo si tiene un solo bean de tipoMovieFinder
en su contexto. Más de 1 llevaría a una excepción.@Autowired
anotación en elprepare
método del Ejemplo 2 . Está inicializandoMovieRecommender
pero, técnicamente, NO es un setter.@Autowired
también funciona para constructores. Encuentra las dependencias requeridas y las inyecta al constructor.Nada en el ejemplo dice que las "clases implementan la misma interfaz".
MovieCatalog
es un tipo yCustomerPreferenceDao
es otro tipo. La primavera puede distinguirlos fácilmente.En Spring 2.x, el cableado de los beans se realizó principalmente a través de ID o nombres de beans. Spring 3.x todavía lo admite, pero a menudo, tendrá una instancia de un bean con un cierto tipo: la mayoría de los servicios son singletons. Crear nombres para esos es tedioso. Entonces Spring comenzó a admitir "autowire by type".
Lo que muestran los ejemplos son varias formas que puede usar para inyectar beans en campos, métodos y constructores.
El XML ya contiene toda la información que Spring necesita, ya que debe especificar el nombre de clase completo en cada bean. Sin embargo, debe tener un poco de cuidado con las interfaces:
Este cableado automático fallará:
Como Java no mantiene los nombres de los parámetros en el código de bytes, Spring ya no puede distinguir entre los dos beans. La solución es usar
@Qualifier
:fuente
prepare
, ¿qué parámetros se utilizarán para llamar a esta función?@Autowired
se inyectan los campos. Spring verá que se necesitan parámetros y utilizará las mismas reglas que se usan para la inyección de campo para encontrar los parámetros.Sí, puede configurar el archivo xml de contexto de servlet Spring para definir sus beans (es decir, clases), de modo que pueda realizar la inyección automática por usted. Sin embargo, tenga en cuenta que debe hacer otras configuraciones para tener Spring en funcionamiento y la mejor manera de hacerlo es seguir un tutorial desde cero.
Una vez que haya configurado su Spring probablemente, puede hacer lo siguiente en su archivo xml de contexto de servlet Spring para que el Ejemplo 1 anterior funcione ( reemplace el nombre del paquete de com.movies por cuál es el verdadero nombre del paquete y si se trata de un tercero) clase, luego asegúrese de que el archivo jar apropiado esté en el classpath):
o si la clase MovieFinder tiene un constructor con un valor primitivo, entonces podría hacer algo como esto,
o si la clase MovieFinder tiene un constructor que espera otra clase, entonces podrías hacer algo como esto,
... donde ' otherBeanRef ' es otro bean que tiene una referencia a la clase esperada.
fuente
@Autowired