Primero, y lo más importante, todos los beans de Spring se administran, "viven" dentro de un contenedor, llamado "contexto de aplicación".
En segundo lugar, cada aplicación tiene un punto de entrada a ese contexto. Las aplicaciones web tienen un Servlet, JSF usa un el-resolver, etc. Además, hay un lugar donde el contexto de la aplicación está arrancado y todos los beans tienen conexión automática. En aplicaciones web, esto puede ser un escucha de inicio.
El cableado automático ocurre colocando una instancia de un bean en el campo deseado en una instancia de otro bean. Ambas clases deben ser beans, es decir, deben definirse para vivir en el contexto de la aplicación.
¿Qué es "vivir" en el contexto de la aplicación? Esto significa que el contexto crea instancias de los objetos, no de usted. Es decir, nunca se hace new UserServiceImpl()
, el contenedor encuentra cada punto de inyección y establece una instancia allí.
En sus controladores, solo tiene lo siguiente:
@Controller // Defines that this class is a spring bean
@RequestMapping("/users")
public class SomeController {
// Tells the application context to inject an instance of UserService here
@Autowired
private UserService userService;
@RequestMapping("/login")
public void login(@RequestParam("username") String username,
@RequestParam("password") String password) {
// The UserServiceImpl is already injected and you can use it
userService.login(username, password);
}
}
Algunas notas
- En su
applicationContext.xml
debe activar el <context:component-scan>
modo que las clases se analizan en busca de la @Controller
, @Service
, etc. anotaciones.
- El punto de entrada para una aplicación Spring-MVC es el DispatcherServlet, pero está oculto para usted y, por lo tanto, la interacción directa y el arranque del contexto de la aplicación ocurre detrás de escena.
UserServiceImpl
también debe definirse como bean, ya sea usando <bean id=".." class="..">
o usando la @Service
anotación. Como será el único implementador de UserService
, se inyectará.
- Además de la
@Autowired
anotación, Spring puede usar cableado automático configurable por XML. En ese caso, todos los campos que tengan un nombre o tipo que coincida con un bean existente se inyectarán automáticamente. De hecho, esa fue la idea inicial del cableado automático: inyectar campos con dependencias sin ninguna configuración. Otras anotaciones como @Inject
, @Resource
también se pueden utilizar.
Depende de si desea la ruta de anotaciones o la ruta de definición XML del bean.
Digamos que tenía los frijoles definidos en su
applicationContext.xml
:El cableado automático ocurre cuando se inicia la aplicación. Entonces, en
fooController
, por razones de argumentos, quiere usar laUserServiceImpl
clase, la anotaría de la siguiente manera:Cuando vea
@Autowired
, Spring buscará una clase que coincida con la propiedad en elapplicationContext
, y la inyectará automáticamente. Si tiene más de unUserService
bean, entonces deberá calificar cuál debe usar.Si haces lo siguiente:
No recogerá el a
@Autowired
menos que lo configure usted mismo.fuente
bean id
enapplicationContext.xml
. Tendremos que definir lauserService
variable conUserService
tipo. Entonces, ¿por qué hacer una entrada en elxml
archivo?@Autowired
es una anotación introducida en Spring 2.5, y se usa solo para inyección.Por ejemplo:
fuente
@Autowired
no significa que "puede usar todas las funciones (método) y variables enB
clase de claseA
". Lo que hace es traer una instancia deA
en instancias deB
, por lo que puede hacera.getId()
desdeB
.¿Cómo
@Autowired
funciona internamente?Ejemplo:
archivo .xml se verá igual si no usa
@Autowired
:Si está usando
@Autowired
entonces:archivo .xml se verá igual si no usa
@Autowired
:Si todavía tiene alguna duda, vaya a la demostración en vivo a continuación
¿Cómo funciona internamente @Autowired?
fuente
Solo necesita anotar su clase de servicio
UserServiceImpl
con anotaciones:Spring container se encargará del ciclo de vida de esta clase a medida que se registre como servicio.
Luego, en su controlador, puede cablearlo automáticamente (instanciarlo) y usar su funcionalidad:
fuente
La inyección de dependencia de Spring te ayuda a eliminar el acoplamiento de tus clases. En lugar de crear objetos como este:
Lo usará después de introducir DI:
Para lograr esto, necesita crear un bean de su servicio en su
ServiceConfiguration
archivo. Después de eso, debe importar esaServiceConfiguration
clase a suWebApplicationConfiguration
clase para poder conectar automáticamente ese bean a su Controlador de la siguiente manera:Puede encontrar un POC basado en la configuración de Java aquí, por ejemplo .
fuente
Forma estándar:
Interfaz de servicio de usuario:
Clase UserServiceImpl:
Salida:
Example test UserServiceImpl
Ese es un gran ejemplo de clases estrechamente acopladas, mal ejemplo de diseño y habrá problemas con las pruebas (PowerMockito también es malo).
Ahora echemos un vistazo a la inyección de dependencia SpringBoot, un buen ejemplo de acoplamiento flojo:
La interfaz sigue siendo la misma.
Clase principal:
Clase ServiceUserImpl:
Salida:
Example test UserServiceImpl
y ahora es fácil escribir prueba:
Mostré
@Autowired
anotaciones en el constructor pero también se puede usar en setter o campo.fuente
Todo el concepto de inversión de control significa que está libre de una tarea para instanciar objetos manualmente y proporcionar todas las dependencias necesarias. Cuando anota una clase con la anotación adecuada (por ejemplo
@Service
) Spring creará automáticamente una instancia de objeto para usted. Si no está familiarizado con las anotaciones, también puede usar el archivo XML. Sin embargo, no es una mala idea crear instancias de clases manualmente (con lanew
palabra clave) en pruebas unitarias cuando no desea cargar todo el contexto de primavera.fuente
Tenga en cuenta que debe habilitar la
@Autowired
anotación agregando elementos<context:annotation-config/>
al archivo de configuración de Spring. Esto registrará elAutowiredAnnotationBeanPostProcessor
que se encarga del procesamiento de la anotación.Y luego puede conectar automáticamente su servicio utilizando el método de inyección de campo.
Encontré esto en la publicación Spring @autowired annotation
fuente
Hay 3 formas de crear una instancia usando
@Autowired
.1.
@Autowired
en PropiedadesLa anotación se puede usar directamente en las propiedades, eliminando así la necesidad de getters y setters:
En el ejemplo anterior, Spring busca e inyecta
userService
cuandoUserController
se crea.2.
@Autowired
en settersLa
@Autowired
anotación se puede utilizar en métodos de establecimiento. En el ejemplo a continuación, cuando la anotación se utiliza en el método setter, se llama al método setter con la instancia deuserService
cuándoUserController
se crea:3.
@Autowired
sobre constructoresLa
@Autowired
anotación también se puede usar en constructores. En el ejemplo a continuación, cuando la anotación se usa en un constructor, una instancia deuserService
se inyecta como un argumento para el constructor cuandoUserController
se crea:fuente
En palabras simples, Autowiring, el cableado de enlaces automáticamente, ahora viene la pregunta de quién hace esto y qué tipo de cableado. La respuesta es: el contenedor hace esto y el tipo de cableado secundario es compatible, las primitivas deben hacerse manualmente.
Pregunta: ¿Cómo sabe el contenedor qué tipo de cableado?
Respuesta: Lo definimos como byType, byName, constructor.
Pregunta: ¿Hay alguna forma en que no definamos el tipo de cableado automático?
Respuesta: Sí, está ahí haciendo una anotación, @Autowired.
Pregunta: ¿Pero cómo sabe el sistema que necesito elegir este tipo de datos secundarios?
Respuesta: Proporcionará esos datos en su archivo spring.xml o mediante anotaciones de esterotipo a su clase para que el contenedor pueda crear los objetos por usted mismo.
fuente