336 votes

Utilisation de compréhension printemps @Autowired

Salut, je suis à la lecture de printemps site pour comprendre Printemps Autocâblés annotation http://docs.spring.io/spring/docs/3.0.x/reference/beans.html#beans-autowired-annotation

3.9.2 @Autocâblés et @Inject

Je ne suis pas en mesure de comprendre comment les exemples ci-dessous. Et avons-nous besoin de faire quelque chose dans le fichier xml pour que cela fonctionne?

EXEMPLE1

   public class SimpleMovieLister {

  private MovieFinder movieFinder;

   @Autowired
   public void setMovieFinder(MovieFinder movieFinder) {
     this.movieFinder = movieFinder;
 }

 // ...
  }

EXEMPLE 2

public class MovieRecommender {

 private MovieCatalog movieCatalog;

  private CustomerPreferenceDao customerPreferenceDao;

 @Autowired
  public void prepare(MovieCatalog movieCatalog,
                    CustomerPreferenceDao customerPreferenceDao) {
    this.movieCatalog = movieCatalog;
    this.customerPreferenceDao = customerPreferenceDao;
  }

   // ...
  }

Svp quelqu'un peut me montrer comment autowire deux classes qui implémentent la même interface et utilisé de la même classe ?

    Exmaple: 

    class Red implements Color
    class Blue implements Color

    class myMainClass{

    @Autowired 
    private Color color;

    draw(){
       color.design(); 
    } 
  }

Mon doute est, dont la conception de la méthode sera appelée ? Comment puis-je m'assurer que la méthode de conception de Rouge classe sera appelée et non pas Bleu.

Merci beaucoup!

576voto

Avi Points 4056

L' @Autowired d'annotation vous permet de passer des configurations d'ailleurs de quoi injecter et juste fait pour vous. En supposant que votre paquet est - com.mycompany.movies vous devez mettre cette balise xml (contexte d'application fichier):

<context:component-scan base-package="com.mycompany.movies" />

Cette balise va faire un scan automatique. En supposant que chaque classe doit devenir un bean est annoté avec une annotation correcte comme @Component (pour de simples haricots) ou @Controller (pour un servlet contrôle) ou en @Repository ( DAO des classes) et ces catégories sont quelque part dans le paquet com.mycompany.movies, printemps trouverez tous les de ces et de créer un bean pour chacun. Ceci est fait en 2 scans des classes - la première fois, elle fouille pour les classes qui en ont besoin pour devenir un haricot et les cartes, les injections, il doit être en train de faire, et sur la deuxième analyse, il injecte les haricots. Bien sûr, vous pouvez définir vos haricots dans les plus traditionnels de fichier XML ou avec un @de Configuration de la classe (ou une combinaison des trois).

L' @Autowired d'annotation indique le printemps, où l'injection doit se produire. Si vous le mettez sur une méthode setMovieFinder il comprend (par le préfixe set + @Autowired d'annotation) qu'un bean doit être injectée. Dans le deuxième scan printemps recherches pour un bean de type MovieFinder, s'il en trouve la fève, il injecte à cette méthode. S'il en trouve 2, par exemple les haricots que vous obtenez une exception. Afin d'éviter l'exception que vous pouvez utiliser l' @Qualifier d'annotation et de dire lequel des 2 haricots à injecter De la manière suivante:

@Qualifier("redBean")
class Red implements Color {
   // Class code here
}

 @Qualifier("blueBean")
class Blue implements Color {
   // Class code here
}

Ou si vous préférez déclarer les haricots dans votre xml, il ressemblerait à quelque chose comme ceci:

<bean id="redBean" class="com.mycompany.movies.Red"/>

<bean id="blueBean" class="com.mycompany.movies.Blue"/>

Dans l' @Autowire déclaration, vous devez également ajouter l' @Qualifier afin de déterminer lequel des 2 couleurs de haricots à injecter:

@Autowired
@Qualifier("redBean")
public void setColor(Color Color) {
  this.color = color;
}

Si vous ne voulez pas utiliser de 2 notes ( @Autowired et @Qualifier) vous pouvez utiliser @Resource de combiner ces 2:

@Resource(name="redBean")
public void setColor(Color Color) {
  this.color = color;
}

L' @Resource (vous pouvez lire quelques données supplémentaires à ce sujet dans le 5ème commentaire sur cette réponse) vous épargne l'utilisation de 2 annotations et au lieu d'une seule.

Je vais juste ajouter 2 commentaires:

  1. Une bonne pratique serait d'utiliser @Inject au lieu de @Autowired parce que c'est pas le printemps-spécifique et fait partie de l' JSR-330 la norme. Vous pouvez lire à ce sujet ici
  2. Une autre bonne pratique serait de mettre la @Inject / @Autowired sur un constructeur au lieu d'une méthode. Si vous le mettez sur un constructeur, printemps valide ces bean existe avant l'injection. Dans la méthode de la façon dont il injecte la valeur null si il ne peut pas trouver la fève vous avez besoin de ce qui va provoquer un NullPointerException lorsque vous essayez d'utiliser cette fève au lieu d'un descriptif exception de la première fois que vous démarrez votre application.

Donc, pour résumer: L' @Autowired d'annotation vous épargne la nécessité de faire le câblage par vous-même dans le fichier XML (ou autre) et trouve qu'il est pour vous ce qui doit être injecté où, et le fait pour vous.

Mise à jour: Pour remplir l'image, j'ai créé une nouvelle question à propos de @Configuration classe

21voto

Aaron Digulla Points 143830

Rien dans l'exemple, dit que "les classes qui implémentent la même interface". MovieCatalog est un type et CustomerPreferenceDao est un autre type. Le printemps peut facilement les distinguer.

Au Printemps 2.x, le câblage de haricots sont surtout produites par bean Id ou les noms. C'est toujours supportée par le Ressort 3.x mais souvent, vous aurez une instance d'un bean avec un certain type de la plupart des services sont des singletons. Création de noms pour ceux qui est fastidieux. Afin de Printemps ont commencé à le soutenir "autowire par type".

Ce que le montrent les exemples est différentes manières que vous pouvez utiliser pour injecter les haricots dans des champs, des méthodes et des constructeurs.

Le XML contient déjà toutes les informations que le Printemps, car vous devez spécifier le nom de classe entièrement qualifié dans chaque fève de cacao. Vous devez être un peu prudent avec les interfaces, si:

Cela permettra à l'autowiring va échouer:

 @Autowire
 public void prepare( Interface1 bean1, Interface1 bean2 ) { ... }

Depuis Java permet de ne pas garder les noms de paramètre dans le code octet, le Printemps ne peut pas distinguer entre les deux fèves de plus. La solution est d'utiliser @Qualifier:

 @Autowire
 public void prepare( @Qualifier("bean1") Interface1 bean1,
     @Qualifier("bean2")  Interface1 bean2 ) { ... }

5voto

Cem Sultan Points 180

Oui, vous pouvez configurer le Printemps servlet contexte fichier xml pour définir vos haricots (c'est à dire, des classes), afin qu'elle puisse faire l'injection automatique pour vous. Toutefois, notez que vous avez à faire d'autres configurations d'avoir des Printemps et en cours d'exécution et la meilleure façon de le faire, est de suivre un tutoriel sol.

Une fois que vous avez votre Printemps configuré probablement, vous pouvez effectuer les opérations suivantes dans votre Printemps servlet contexte fichier xml de l'Exemple 1 ci-dessus pour travailler (veuillez remplacer le nom du package de com.des films de quel est le vrai nom du package est et si c'est une 3ème partie de la classe, alors assurez-vous que le fichier jar est sur le chemin de la classe) :

<beans:bean id="movieFinder" class="com.movies.MovieFinder" />

ou si le MovieFinder classe a un constructeur avec une valeur primitive, alors vous pourriez quelque chose comme ceci,

<beans:bean id="movieFinder" class="com.movies.MovieFinder" >
    <beans:constructor-arg value="100" />
</beans:bean>

ou si le MovieFinder classe a un constructeur attend à une autre classe, alors vous pourriez faire quelque chose comme cela,

<beans:bean id="movieFinder" class="com.movies.MovieFinder" >
    <beans:constructor-arg ref="otherBeanRef" />
</beans:bean>

...où"otherBeanRef' est un autre bean qui a une référence de la classe.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X