¿Cómo Autowiring trabajo en la primavera?
-
01-10-2019 - |
Pregunta
Estoy un poco confundido en cuanto a cómo el inversión de control (IoC
) trabaja en Spring
.
Decir que tengo una clase de servicio denominada UserServiceImpl
que implementa la interfaz UserService
.
¿Cómo sería esto @Autowired
?
Y en mi Controllers
, ¿cómo me instantiate
un instance
de este servicio?
¿Me acaba de hacer lo siguiente?
UserService userService = new UserServiceImpl();
Solución
En primer lugar, y más importante - todos los granos de la primavera se gestionan -. "Viven" dentro de un recipiente, 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 utiliza un EL-resolver, etc. Además, hay un lugar en el contexto de aplicación se bootstrap y todos los granos - autowired. En las aplicaciones web que esto puede ser un oyente inicio.
Autowiring sucede mediante la colocación de una instancia de un grano en el campo deseado en una instancia de otro bean. Ambas clases deben ser granos, es decir, que deben definirse vivir en el contexto de aplicación.
¿Qué es la "vida" en el contexto de la aplicación? Esto significa que los Contexto crea una instancia de los objetos, no tú. Es decir. - nunca se hace new UserServiceImpl()
-. El contenedor se encuentra cada punto de inyección y establece una instancia existe
En los controladores, que acaba de tener 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
que debería permitir a la<context:component-scan>
de modo que las clases se analizan en busca de la@Controller
,@Service
, etc. anotaciones. - El punto de entrada para una aplicación Primavera-MVC es la DispatcherServlet, pero es oculto, y por lo tanto la interacción directa y arranque del contexto de aplicación que sucede detrás de la escena.
-
UserServiceImpl
también debe definirse como frijol - ya sea usando<bean id=".." class="..">
o el uso de la anotación@Service
. Puesto que será la única implementador deUserService
, se inyecta. - Además de la anotación
@Autowired
, primavera puede utilizar autowiring XML-configurable. En ese caso todos los campos que tienen un nombre o tipo que se ajuste con un bean existente obtendrá automáticamente un grano inyectados. De hecho, esa fue la idea inicial de autowiring - tener campos inyectados con dependencias sin ninguna configuración. Otras anotaciones como@Inject
,@Resource
también se pueden utilizar.
Otros consejos
Depende de si usted fue la ruta anotaciones o la ruta de definición XML de frijol.
Supongamos 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 sucede cuando se inicia la aplicación. Así, en fooController
, que por argumentos bien quiere utilizar la clase UserServiceImpl
, que le anotaciones de 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 se ve @Autowired
, Primavera buscará una clase que coincide con la propiedad en el applicationContext
, e inyectar automáticamente. Si usted tiene más de un grano de UserService
, entonces usted tiene que calificar de cuál se debe utilizar.
Si lo hace lo siguiente:
UserService service = new UserServiceImpl();
No va a recoger el @Autowired
a menos que establezca por sí mismo.
@Autowired
es una anotación introducido en la primavera de 2,5, y se usa sólo 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(););
}
}
¿Cómo funciona internamente @Autowired
?
Ejemplo:
class EnglishGreeting {
private Greeting greeting;
//setter and getter
}
class Greeting {
private String message;
//setter and getter
}
.xml que se verá igual si no se 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
a continuación:
class EnglishGreeting {
@Autowired //so automatically based on the name it will identify the bean and inject.
private Greeting greeting;
//setter and getter
}
.xml que se verá igual si no se 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 todavía tiene alguna duda, a continuación, pasar por debajo de demostración en vivo
Sólo tiene que anotar su UserServiceImpl
clase de servicio con la anotación:
@Service("userService")
contenedor de primavera se hará cargo del ciclo de vida de esta clase, ya que se registra como servicio.
A continuación, en su controlador que pueda auto del alambre (instantiate) y utilizar su funcionalidad:
@Autowired
UserService userService;
Primavera dependencia inyectar ayuda a eliminar el acoplamiento de sus clases. En lugar de crear el objeto de la siguiente manera:
UserService userService = new UserServiceImpl();
Usted va a utilizar esto después de la introducción de DI:
@Autowired
private UserService userService;
Para lograr esto es necesario crear un grano de su servicio en el archivo de ServiceConfiguration
. Después de que es necesario importar la clase ServiceConfiguration
a su clase WebApplicationConfiguration
para que pueda Autowire que el frijol en el controlador de la siguiente manera:
public class AccController {
@Autowired
private UserService userService;
}
Puede encontrar un POC a base de configuración de Java aquí ejemplo .
Todo el concepto de inversión de medios de control que están libres de una tarea a instancias de objetos de forma manual y proporcionar todas las dependencias necesarias.
Cuando annotate clase con anotación apropiada (por ejemplo @Service
) primavera objeto automáticamente instantiate para usted. Si no está familiarizado con las anotaciones también se puede utilizar el archivo XML en su lugar. Sin embargo, no es una mala idea para crear instancias de clases de forma manual (con la palabra clave new
) en las pruebas de unidad cuando no se desea cargar todo el contexto de la primavera.
Hay 3 manera se puede crear una instancia utilizando @Autowired
.
1. @Autowired
en Propiedades
La anotación se puede utilizar directamente en las propiedades, por lo tanto eliminando la necesidad de captadores y definidores:
@Component("userService")
public class UserService {
public String getName() {
return "service name";
}
}
@Component
public class UserController {
@Autowired
UserService userService
}
En el ejemplo anterior, la apariencia de primavera para e inyecta userService
cuando se crea UserController
.
2. @Autowired
a los organismos de
La anotación @Autowired
se puede utilizar en métodos setter. En el siguiente ejemplo, cuando se usa la anotación en el método setter, el método setter se llama con el ejemplo de userService
cuando se crea UserController
:
public class UserController {
private UserService userService;
@Autowired
public void setUserService(UserService userService) {
this.userService = userService;
}
}
3. @Autowired
de Constructores
La anotación @Autowired
también se puede utilizar en constructores. En el siguiente ejemplo, cuando se usa la anotación en un constructor, una instancia de userService
se inyecta como un argumento para el constructor cuando se crea UserController
:
public class UserController {
private UserService userService;
@Autowired
public UserController(UserService userService) {
this.userService= userService;
}
}
Tenga en cuenta que debe habilitar la anotación @Autowired
añadiendo elemento <context:annotation-config/>
en el archivo de configuración del resorte. Esto registrará el AutowiredAnnotationBeanPostProcessor
que se encarga del procesamiento de anotación.
Y entonces usted puede Autowire su servicio utilizando el método de inyección de campo.
public class YourController{
@Autowired
private UserService userService;
}
He encontrado este del poste primavera @autowired anotación