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.xmldebe 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.
UserServiceImpltambién debe definirse como bean, ya sea usando <bean id=".." class="..">o usando la @Serviceanotación. Como será el único implementador de UserService, se inyectará.
- Además de la
@Autowiredanotació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, @Resourcetambié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 laUserServiceImplclase, 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 unUserServicebean, entonces deberá calificar cuál debe usar.Si haces lo siguiente:
No recogerá el a
@Autowiredmenos que lo configure usted mismo.fuente
bean idenapplicationContext.xml. Tendremos que definir lauserServicevariable conUserServicetipo. Entonces, ¿por qué hacer una entrada en elxmlarchivo?@Autowiredes una anotación introducida en Spring 2.5, y se usa solo para inyección.Por ejemplo:
fuente
@Autowiredno significa que "puede usar todas las funciones (método) y variables enBclase de claseA". Lo que hace es traer una instancia deAen instancias deB, por lo que puede hacera.getId()desdeB.¿Cómo
@Autowiredfunciona internamente?Ejemplo:
archivo .xml se verá igual si no usa
@Autowired:Si está usando
@Autowiredentonces: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
UserServiceImplcon 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
ServiceConfigurationarchivo. Después de eso, debe importar esaServiceConfigurationclase a suWebApplicationConfigurationclase 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 UserServiceImplEse 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 UserServiceImply ahora es fácil escribir prueba:
Mostré
@Autowiredanotaciones 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 lanewpalabra clave) en pruebas unitarias cuando no desea cargar todo el contexto de primavera.fuente
Tenga en cuenta que debe habilitar la
@Autowiredanotación agregando elementos<context:annotation-config/>al archivo de configuración de Spring. Esto registrará elAutowiredAnnotationBeanPostProcessorque 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.
@Autowireden 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
userServicecuandoUserControllerse crea.2.
@Autowireden settersLa
@Autowiredanotació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 deuserServicecuándoUserControllerse crea:3.
@Autowiredsobre constructoresLa
@Autowiredanotació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 deuserServicese inyecta como un argumento para el constructor cuandoUserControllerse 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