poner - setbounds java
¿Cómo funciona el cableado automático en primavera? (8)
Estoy un poco confundido en cuanto a cómo funciona la inversión de control ( IoC
) en Spring
.
Digamos que tengo una clase de servicio llamada UserServiceImpl
que implementa la interfaz UserService
.
¿Cómo sería esto @Autowired
?
Y en mis Controllers
, ¿cómo instantiate
una instance
de este servicio?
¿Haría lo siguiente?
UserService userService = new UserServiceImpl();
¿Cómo funciona @Autowired internamente?
Ex -
class EnglishGreeting {
private Greeting greeting;
//setter and getter
}
class Greeting {
private String message;
//setter and getter
}
archivo .xml se verá igual si no usa @Autowired
<bean id="englishGreeting" class="com.bean.EnglishGreeting">
<property name="greeting" ref="greeting"/>
</bean>
<bean id="greeting" class="com.bean.Greeting">
<property name="message" value="Hello World"/>
</bean>
Si está utilizando @Autowired entonces
class EnglishGreeting {
@Autowired //so automatically based on the name it will identify the bean and inject.
private Greeting greeting;
//setter and getter
}
archivo .xml se verá igual si no usa @Autowired
<bean id="englishGreeting" class="com.bean.EnglishGreeting"></bean>
<bean id="greeting" class="com.bean.Greeting">
<property name="message" value="Hello World"/>
</bean>
Si aún tiene alguna duda, pase por debajo de la demostración en vivo.
Depende de si ha elegido la ruta de anotaciones o la ruta de definición XML de bean.
Digamos que tenía los beans definidos en su applicationContext.xml
:
<beans ...>
<bean id="userService" class="com.foo.UserServiceImpl"/>
<bean id="fooController" class="com.foo.FooController"/>
</beans>
El autowiring ocurre cuando se inicia la aplicación. Entonces, en fooController
, que para argumentos quiere usar la clase UserServiceImpl
, lo UserServiceImpl
la siguiente manera:
public class FooController {
// You could also annotate the setUserService method instead of this
@Autowired
private UserService userService;
// rest of class goes here
}
Cuando vea @Autowired
, Spring buscará una clase que coincida con la propiedad en el @Autowired
aplicación, y la inyectará automáticamente. Si tiene más de 1 bean UserService, entonces tendrá que calificar cuál debería usar.
Si haces lo siguiente:
UserService service = new UserServiceImpl();
No recogerá el @Autowired a menos que lo configure usted mismo.
La inyección de dependencia de primavera lo ayuda a eliminar el acoplamiento de sus clases. En lugar de crear un objeto como este
UserService userService = new UserServiceImpl();
Lo usarás después de introducir DI
@Autowired
private UserService userService;
Para lograr esto, necesita crear un bean de su servicio en su archivo de configuración de servicio. Después de eso, debe importar la clase ServiceConfiguration a su clase WebApplicationConfiguration para poder encender automáticamente ese bean en su controlador de esta manera.
public class AccController {
@Autowired
private UserService userService;
}
Puedes encontrar un example POC basado en configuración java aquí
Primero, y lo más importante, todos los Spring Beans se gestionan: "viven" dentro de un contenedor, llamado "contexto de aplicación".
Segundo, 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 es bootstrapped y todos los beans - autowired. En aplicaciones web esto puede ser un oyente de inicio.
El cableado automático ocurre al colocar una instancia de un bean en el campo deseado en una instancia de otro bean. Ambas clases deberían ser beans, es decir, deberían 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 una instancia de los objetos, no tú. Es decir, nunca hace un new UserServiceImpl()
: el contenedor encuentra cada punto de inyección y establece una instancia allí.
En tus controladores, solo tienes 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 habilitar<context:component-scan>
para que las clases se@Controller
para las@Controller
,@Service
, etc. - 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 sucede detrás de la escena.
-
UserServiceImpl
también debe definirse como bean, ya sea utilizando<bean id=".." class="..">
o usando la anotación@Service
. Dado que será el único implementador deUserService
, será inyectado. - Además de la anotación
@Autowired
, Spring puede usar el cableado automático configurable por XML. En ese caso, todos los campos que tengan un nombre o un tipo que coincida con un bean existente obtendrán automáticamente un bean inyectado. De hecho, esa fue la idea inicial de la conexión automática: tener campos inyectados con dependencias sin ninguna configuración. También se pueden utilizar otras anotaciones como@Inject
,@Resource
.
Solo necesita anotar su clase de servicio UserServiceImpl con anotación
@Service("userService")
Spring Contain se hará cargo del ciclo de vida de esta clase cuando se registre como servicio.
Luego, en su controlador puede cablearlo (crear una instancia) y usar su funcionalidad.
@Autowired
UserService userService;
Tenga en cuenta que debe habilitar la anotación @Autowired agregando el elemento <context:annotation-config/>
en el archivo de configuración de Spring. Esto registrará el AutowiredAnnotationBeanPostProcessor que se encarga del procesamiento de la anotación.
Y luego puede autorizar su servicio utilizando el método de inyección de campo.
public class YourController{
@Autowired
private UserService userService;
}
Encontré esto en el post Spring @autowired anotación
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 realiza anotaciones en la clase con la anotación adecuada (por ejemplo, @Service
) Spring creará automáticamente una instancia del objeto para usted. Si no está familiarizado con las anotaciones, también puede utilizar el archivo XML. Sin embargo, no es una mala idea crear instancias de las clases manualmente (con la new
palabra clave) en pruebas unitarias cuando no desea cargar todo el contexto de Spring.
@Autowired
es una anotación introducida en Spring 2.5, y se usa solo para inyección.
Por ejemplo:
class A {
private int id;
// With setter and getter method
}
class B {
private String name;
@Autowired // Here we are injecting instance of Class A into class B so that you can use ''a'' for accessing A''s instance variables and methods.
A a;
// With setter and getter method
public void showDetail() {
System.out.println("Value of id form A class" + a.getId(););
}
}