Comment fonctionne autowiring au printemps?


Je suis un peu confus quant à la façon dont la inversion de contrôle (IoC) travaille dans Spring.

Disons que j'ai une classe de service appelée UserServiceImpl qui implémente l'interface UserService.

Comment serait-ce @Autowired?

Et dans mon Controllers, comment pourrais-je instantiate un instance de ce service?

Est-ce que je ferais juste ce qui suit?

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

9 answers

Tout d'abord, et le plus important - tous les haricots de printemps sont gérés - ils "vivent" dans un conteneur, appelé "contexte d'application".

Deuxièmement, chaque demande a un point d'entrée dans ce contexte. Les applications Web ont une Servlet, JSF utilise un résolveur el, etc. En outre, il existe un endroit où le contexte de l'application est bootstrapped et tous les beans - autowired. Dans les applications Web, cela peut être un écouteur de démarrage.

Autowiring se produit en plaçant une instance d'un bean dans le champ souhaité dans une instance d'un autre bean. Les deux classes doivent être des beans, c'est-à-dire qu'elles doivent être définies pour vivre dans le contexte de l'application.

Qu'est-Ce que "vivre" dans le contexte de l'application? Cela signifie que le contexte instancie les objets, pas vous. C'est - à-dire-vous ne faites jamais new UserServiceImpl() - le conteneur trouve chaque point d'injection et y définit une instance.

Dans vos contrôleurs, vous avez juste ce qui suit:

@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);

    }
}

Quelques remarques:

  • Dans votre applicationContext.xml vous devez activer le <context:component-scan> afin que les classes soient analysées pour le @Controller, @Service, etc. annotation.
  • Le point d'entrée d'une application Spring-MVC est le DispatcherServlet, mais il vous est caché, et donc l'interaction directe et l'amorçage du contexte de l'application se produisent derrière la scène.
  • UserServiceImpl doit également être défini comme bean - soit en utilisant <bean id=".." class=".."> ou en utilisant l'annotation @Service. Comme ce sera le seul implémenteur de UserService , ce sera injecter.
  • En dehors de l'annotation @Autowired, Spring peut utiliser le câblage automatique configurable en XML. Dans ce cas, tous les champs dont le nom ou le type correspond à un bean existant reçoivent automatiquement un bean injecté. En fait, c'était l'idée initiale de autowiring - d'avoir des champs injectés avec des dépendances sans aucune configuration. D'autres annotations comme @Inject, @Resource peut également être utilisé.
 606
Author: Bozho, 2018-02-12 18:32:32

Dépend si vous avez suivi la route des annotations ou la route de définition XML bean.

Dites que vous avez défini les beans dans votre applicationContext.xml:

<beans ...>

    <bean id="userService" class="com.foo.UserServiceImpl"/>

    <bean id="fooController" class="com.foo.FooController"/>

</beans>

L'autowiring se produit lorsque l'application démarre. Donc, dans fooController, qui pour des raisons d'arguments veut utiliser la classe UserServiceImpl, vous l'annoteriez comme suit:

public class FooController {

    // You could also annotate the setUserService method instead of this
    @Autowired
    private UserService userService;

    // rest of class goes here
}

Quand il voit @Autowired, Spring recherchera une classe qui correspond à la propriété dans applicationContext et l'injectera automatiquement. Si vous avez plus de 1 UserService bean, alors vous devrez qualifier celui qu'il devrait utiliser.

Si vous procédez comme suit:

UserService service = new UserServiceImpl();

Il ne récupérera pas le @Autowired sauf si vous le définissez vous-même.

 60
Author: Ben J, 2010-06-30 21:37:26

@Autowired est une annotation introduite dans Spring 2.5, et elle est utilisée uniquement pour l'injection.

Par exemple:

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, 2018-05-16 18:37:45

Comment fonctionne @ Autowired en interne?

Ex -

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

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

.fichier xml il se ressemblera s'il n'utilise pas @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 vous utilisez @Autowired alors

class EnglishGreeting {
   @Autowired //so automatically based on the name it will identify the bean and inject.
   private Greeting greeting;
   //setter and getter
}

.fichier xml il se ressemblera s'il n'utilise pas @Autowired

<bean id="englishGreeting" class="com.bean.EnglishGreeting"></bean>

<bean id="greeting" class="com.bean.Greeting">
   <property name="message" value="Hello World"/>
</bean>

Si vous avez encore un doute, passez par ci-dessous la démo en direct

Comment fonctionne @Autowired en interne ?

 8
Author: jeet singh parmar, 2018-04-02 08:55:07

@Autocâblés

  • Marque un constructeur, un champ, une méthode setter ou une méthode config comme étant autowired par les installations d'injection de dépendance de Spring.

  • Un seul constructeur (au maximum) d'une classe de bean donnée peut porter ceci annotation, indiquant le constructeur à autowire lorsqu'il est utilisé comme un Haricot de printemps. Un tel constructeur n'a pas à être public.

  • Les champs sont injectés juste après la construction d'un haricot, avant tout les méthodes de configuration sont invoquées. Tel un champ de configuration ne doit pas nécessairement être public.

  • Les méthodes de configuration peuvent avoir un nom arbitraire et n'importe quel nombre de arguments; chacun de ces arguments sera activé automatiquement avec une correspondance haricot dans le récipient de printemps. Bean propriété setter sont effectivement, juste un cas particulier d'une telle méthode de configuration générale. Tel les méthodes de configuration ne doivent pas nécessairement être publiques.

  • Dans le cas de méthodes à arguments multiples, le paramètre 'required' est applicable pour tous les argument.

  • Dans le cas d'un type de dépendance de Collection ou de Map, le conteneur autowire tous les beans correspondant au type de valeur déclaré. Dans le cas d'une Map, les clés doivent être déclarées comme type String et seront résolues à les noms de haricots correspondants.

 7
Author: nijogeorgep, 2015-10-28 09:51:59

Il vous suffit d'annoter votre classe de service UserServiceImpl avec l'annotation

@Service("userService")

Spring Container prendra en charge le cycle de vie de cette classe lors de son enregistrement en tant que service.

Ensuite, dans votre contrôleur, vous pouvez le câbler automatiquement(instancier) et utiliser ses fonctionnalités.

@Autowired
UserService userService;
 4
Author: Jitender Chahar, 2016-03-18 09:47:28

Spring dependency inject vous aide à supprimer le couplage de vos classes. Au lieu de créer un objet comme celui-ci

UserService userService = new UserServiceImpl();

Vous l'utiliserez après avoir introduit DI

@Autowired
private UserService userService;

Pour y parvenir, vous devez créer un bean de votre service dans votre fichier ServiceConfiguration. Après cela, vous devez importer cette classe ServiceConfiguration dans votre classe WebApplicationConfiguration afin de pouvoir activer automatiquement ce bean dans votre contrôleur comme ceci.

public class AccController {

    @Autowired
    private UserService userService;
} 

Vous pouvez trouver un POC basé sur la configuration java ici exemple

 1
Author: AbdusSalam, 2017-09-04 02:49:47

Tout le concept d'inversion de contrôle signifie que vous êtes libre d'une corvée pour instancier les objets manuellement et fournir toutes les dépendances nécessaires. Lorsque vous annotez une classe avec une annotation appropriée (par exemple @Service), Spring instancie automatiquement l'objet pour vous. Si vous n'êtes pas familier avec les annotations, vous pouvez également utiliser un fichier XML à la place. Cependant, ce n'est pas une mauvaise idée d'instancier manuellement les classes (avec le mot-clé new) dans les tests unitaires lorsque vous ne voulez pas charger tout le printemps cadre.

 0
Author: pheasant, 2017-06-27 10:19:32

Gardez à l'esprit que vous devez activer l'annotation @Autowired en ajoutant l'élément <context:annotation-config/> dans le fichier de configuration spring. Cela va enregistrer le AutowiredAnnotationBeanPostProcessor qui s'occupe du traitement de l'annotation.

Et puis vous pouvez autowire votre service en utilisant la méthode d'injection de champ.

public class YourController{

 @Autowired
 private UserService userService; 

}

J'ai trouvé cela d'une post - Printemps @autocâblés annotation

 0
Author: David Pham, 2017-11-07 02:08:37