web-dev-qa-db-fra.com

Différence entre les annotations Spring

Questions:

1) Différence entre @Component et @Configuration?

J'ai lu que les deux suppriment la nécessité de câbler le code pour être mis en XML, mais n'ont pas fait la différence entre ceux-ci.

2) Quelles sont les différences entre @Autowired, @Inject et @Resource?
- Lequel utiliser quand?
- Quels sont les avantages/inconvénients de chacun?

40
Anand

_@Component_ et _@Configuration_ sont en effet des types d'annotations très différents.

_@Component_ et annotations similaires (_@Service_, _@Repository_, etc.) et son JSR-3 contrepartie _@Named_ vous permettent de déclarer des beans qui sont à être récupérés par analyse automatique avec _<context:component-scan/>_ ou _@ComponentScan_ ils enregistrent la définition de bean pour les classes, ils sont donc à peu près équivalents à déclarer les beans spécifiés avec la balise _<bean ... />_ en XML. Ces types de bean adhéreront aux politiques de création de proxy standard.

_@Configuration_ l'annotation a été conçue pour remplacer le fichier de configuration XML. Pour créer _@Configuration_ beans annotés, Spring utilisera toujours CGLIB pour sous-classer la classe annotée _@Configuration_, en remplaçant sa méthode annotée _@Bean_ pour la remplacer par la méthode de recherche de bean à effectuer les beans singleton ne doivent être créés qu'une seule fois. (Spring n'utilise pas CGLIB pour intercepter interne appels de méthode normal Spring beans, il crée à la place une instance distincte de proxy (de la même manière comme le fait le proxy JDK). Cela permet d'utiliser des proxys pour éviter la non-correspondance de cardinalité - par exemple, un singleton proxy peut extraire le bean de session en cours, ce qui n'est pas possible avec l'héritage de classe uniquement. ). Malgré cela, _@Configuration_ les classes annotées peuvent toujours utiliser les champs et propriétés annotés (_@Autowired_, _@Inject_ etc.) pour demander des beans (et même d'autres _@Configuration_ beans annotés aussi) du conteneur.

Exemple de la section 4.12.5 de la documentation

_@Configuration
public class AppConfig {

  @Bean
  public ClientService clientService1() {
    ClientServiceImpl clientService = new ClientServiceImpl();
    clientService.setClientDao(clientDao());
    return clientService;
  }
  @Bean
  public ClientService clientService2() {
    ClientServiceImpl clientService = new ClientServiceImpl();
    clientService.setClientDao(clientDao());
    return clientService;
  }

  @Bean
  public ClientDao clientDao() {
    return new ClientDaoImpl();
  }
}
_

dans l'exemple ci-dessus, une seule instance ClientDao sera créée.

_@Autowired_ est une annotation Spring, tandis que _@Inject_ est une annotation JSR-330. _@Inject_ est équivalent à _@Autowired_ ou @Autowired(required=true), mais vous ne pouvez pas obtenir le comportement @Autowired(required=false) avec l'annotation JSR-330 _@Inject_. Cette annotation utilise toujours le câblage automatique par type.

Spring implémente JSR-25 _@Resource_ annotation d'une manière assez spéciale. _@Resource_ a été initialement conçu pour localiser les ressources JNDI dans Java EE, mais Spring élargit son applicabilité permettant de câbler à n'importe quel bean dans le conteneur (les ressources JNDI sont disponibles sous forme de beans avec le aide de SimpleJndiBeanFactory ). Le nom du bean correspondant peut être spécifié comme name attribut de _@Resource_ annotation, si aucun nom n'a été spécifié, alors le nom du champ annoté ou une propriété sera utilisée. Une autre caractéristique étrange est que si aucun bean portant le nom de la propriété n'a été trouvé, le ressort revient au câblage par type.

Exemple Imaginez que nous avons un bean AlphaClass nommé beanAlpha et un BetaClass bean beanBeta dans le conteneur.

_@Resource 
BetaClass something;  // Wires to beanBeta - by-type

@Resource 
BetaClass beanAlpha;  // Will throw exception, because "beanAlpha" is not BetaClass -> it's a bad idea to use @Resource as a replacement of @Autowired

@Resource 
Object beanAlpha;  //Wires to beanAlpha - by-name
_

Il est donc recommandé de toujours spécifier explicitement le nom de la ressource lors de l'utilisation de l'annotation _@Resource_.

Documentation

Annotations de printemps

Annotations standard du bean

mise à jour correction des références JSR comme shevchik l'a souligné. Les annotations spécifiques aux DI sont fournies par JSR-330, qui a été développé par les ingénieurs de Google (Guice Framework) et SpringSource (Spring Framework). _@Resource_ est basé sur JNDI et fourni par JSR-25 .

54
Boris Treukhov

@Component est équivalent à <bean>,
@Configuration est équivalent à <beans>.

22
xyz

Dans la plupart des réponses ci-dessus, les utilisateurs suggèrent de dire que @Component et @ Configuration ont des objectifs différents. Mais je ne vois pas cela se produire dans la réalité.

Mais j'ai une simple application Spring MVC.

@Configuration
    public class SpringConfiguration {

@Bean
public  InternalResourceViewResolver initViewResolver(){
    InternalResourceViewResolver x = new InternalResourceViewResolver();
    x.setPrefix("/WEB-INF/jsp/");
    x.setSuffix(".jsp");
    return x;
}

}

Cette classe principale fonctionne bien même si elle est annotée en tant que @Component au lieu de @Configuration.

De même, à l'intérieur d'une classe annotée en tant que @Component si vous avez des méthodes annotées avec @Bean, ces beans sont créés lorsque le contexte est loaed.

Je pense donc que c'est juste pour la lisibilité du code que nous devrions marquer la classe de configuration principale comme @Configuration et d'autres classes avec @Component. En ce qui concerne l'exécution réelle, il ne semble pas y avoir de différence.

5
Kaushik Lele

Sur la différence entre @Autowired, @Inject et @Resource vous pouvez regarder ici . Ici vous pouvez une description et une comparaison approfondies.

Ce qui concerne la première différence: @Configuration est utilisé en remplacement de la configuration basée sur XML, c'est-à-dire. il marque les classes comme celles utilisées pour la configuration basée sur Java, voir ici . À son tour, @Component est en fait utilisé pour marquer les classes comme celles à instancier par Spring et @Configuration est méta-annoté par @Component annotation.

@Component et @Configuration servent à des fins différentes, il n'est donc pas logique de les comparer.

2

1) Si vous souhaitez une configuration XML, ignorez @Configuration, car cela n'est utile que pour la configuration basée sur Java. La configuration XML est probablement la meilleure pour quelqu'un qui ne connaît pas Spring car il existe d'autres exemples disponibles.

Les classes annotées @Component sont récupérées lors de l'analyse des composants. Utilisez-les pour étiqueter les classes que vous souhaitez exposer en tant que beans Spring. Encore une fois, vous pouvez simplement déclarer tous vos beans dans la configuration XML et ignorer complètement @Component.

2) Si vous êtes heureux de lier votre application à Spring, utilisez @Autowire plutôt que l'équivalent javax @Inject. Je dirais que l'acceptation d'une dépendance à Spring est la meilleure façon de commencer.

2
Rich Cowin