¿Cómo funciona el autowiring en primavera?


Estoy un poco confundido en cuanto a cómo la inversión de control (IoC) funciona en Spring.

Digamos que tengo una clase de servicio llamada UserServiceImpl que implementa la interfaz UserService.

¿Cómo sería esto @Autowired?

Y en mi Controllers, ¿cómo haría yo instantiate un instance de este servicio?

¿Haría lo siguiente?

UserService userService = new UserServiceImpl();
Author: Mahozad, 2010-07-01

9 answers

Primero, y lo más importante - todos los granos de primavera son administrados - "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 utiliza un el-resolver, etc. También, hay un lugar donde el contexto de la aplicación es bootstrap y todos los granos - autowired. En aplicaciones web esto puede ser un oyente de inicio.

El autowiring ocurre colocando una instancia de un bean en el campo deseado en una instancia de otro bean. Ambas clases deben ser frijoles, 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 haces new UserServiceImpl() - el contenedor encuentra cada punto de inyección y establece una instancia allí.

En tus controladores, solo tienes lo siguiente: {[14]]}

@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 el <context:component-scan> para que las clases se exploren para el @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 la escena.
  • UserServiceImpl también debe definirse como frijol - ya sea usando <bean id=".." class=".."> o usando la anotación @Service. Dado que será el único implementador de UserService, será inyectar.
  • Aparte de la anotación @Autowired, Spring puede usar auto-cableado configurable XML. En ese caso, todos los campos que tienen un nombre o tipo que coincide con un frijol existente automáticamente reciben un frijol inyectado. De hecho, esa fue la idea inicial del autowiring - tener campos inyectados con dependencias sin ninguna configuración. Otras anotaciones como @Inject, @Resource también se puede utilizar.
 606
Author: Bozho,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-02-12 18:32:32

Depende de si fue a la ruta de anotaciones o a la ruta de definición XML de bean.

Digamos que tienes los frijoles definidos en tu 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 por argumentos quiere usar la clase UserServiceImpl, lo anotarías 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 vea @Autowired, Spring buscará una clase que coincida con la propiedad en ApplicationContext, y la inyectará automáticamente. Si tiene más de 1 UserService bean, entonces tendrá que calificar cuál debe usar.

Si haces lo siguiente:

UserService service = new UserServiceImpl();

No recogerá el @Autowired a menos que lo configure usted mismo.

 60
Author: Ben J,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-06-30 21:37:26

@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(););
    }
}
 18
Author: mohit bansal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-05-16 18:37:45

¿Cómo funciona internamente @Autowired?

Ex -

class EnglishGreeting {
   private Greeting greeting;
   //setter and getter
}

class Greeting {
   private String message;
   //setter and getter
}

.archivo xml se verá igual si no se utiliza @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 se utiliza @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, vaya a través de la siguiente demostración en vivo

¿Cómo funciona internamente @Autowired ?

 8
Author: jeet singh parmar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-04-02 08:55:07

@Autowired

  • Marca un constructor, campo, método setter o método config como para ser autowired por las instalaciones de inyección de dependencia de Spring.

  • Solo un constructor (en máx.) de cualquier clase bean dada puede llevar esto anotación, indicando el constructor a autowire cuando se usa como un Frijol de primavera. Un constructor no tiene que ser público.

  • Los campos se inyectan justo después de la construcción de un frijol, antes de cualquier se invocan los métodos de configuración. Tales un campo de configuración no tiene que ser publico.

  • Los métodos de configuración pueden tener un nombre arbitrario y cualquier número de argumentos; cada uno de esos argumentos se conectará automáticamente con una coincidencia frijol en el recipiente de primavera. Los métodos de setter de propiedades de Bean son efectivamente solo un caso especial de un método de configuración tan general. Tales los métodos de configuración no tienen que ser públicos.

  • En el caso de varios métodos de argumento, el parámetro' required ' es aplicable para todos argumento.

  • En caso de una colección o tipo de dependencia de mapa, el contenedor autowire todos los frijoles que coincidan con el tipo de valor declarado. En caso de Map, las claves deben ser declaradas como cadena de tipo y se resolverán a los nombres de frijol correspondientes.

 7
Author: nijogeorgep,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-10-28 09:51:59

Solo necesita anotar su clase de servicio UserServiceImpl con anotación

@Service("userService")

Spring container se encargará del ciclo de vida de esta clase a medida que se registre como servicio.

Luego en su controlador puede conectarlo automáticamente(instanciarlo) y usar su funcionalidad.

@Autowired
UserService userService;
 4
Author: Jitender Chahar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-03-18 09:47:28

Spring dependency inject te ayuda a eliminar el acoplamiento de tus clases. En lugar de crear un objeto como este

UserService userService = new UserServiceImpl();

Usted usará esto después de introducir DI

@Autowired
private UserService userService;

Para lograr esto necesita crear un bean de su servicio en su archivo ServiceConfiguration. Después de eso, necesita importar esa clase ServiceConfiguration a su clase WebApplicationConfiguration para que pueda conectar automáticamente ese bean a su Controlador de esta manera.

public class AccController {

    @Autowired
    private UserService userService;
} 

Usted puede encontrar un POC basado en configuración java aquí ejemplo

 1
Author: AbdusSalam,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-09-04 02:49:47

Todo el concepto de inversión de control significa que usted está libre de una tarea para instanciar objetos manualmente y proporcionar todas las dependencias necesarias. Cuando anota una clase con una anotación apropiada (por ejemplo, @Service), Spring creará automáticamente una instancia del objeto para usted. Si no está familiarizado con las anotaciones, también puede usar el archivo XML en su lugar. Sin embargo, no es una mala idea crear instancias de clases manualmente (con la palabra clave new) en pruebas unitarias cuando no desea cargar toda la primavera contexto.

 0
Author: pheasant,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-06-27 10:19:32

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 conectar automáticamente su servicio utilizando el método de Inyección de campo.

public class YourController{

 @Autowired
 private UserService userService; 

}

Encontré esto en el post Anotación Spring @autowired

 0
Author: David Pham,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-11-07 02:08:37