web-dev-qa-db-fra.com

Printemps @Utilisation par câble

Quels sont les avantages et les inconvénients de l’utilisation de @Autowired dans un cours qui sera programmé avant le printemps? 

Juste pour clarifier, je parle spécifiquement de l'annotation @Autowired , et non du câblage automatique en XML.

Je ne le comprends probablement pas, mais pour moi, cela ressemble presque à un anti-modèle - vos classes commencent à prendre conscience du fait qu’elles sont liées à un cadre d’ID, plutôt que d’être simplement des POJO. Je suis peut-être friand de punition, mais j'aime bien avoir la configuration XML externe pour les beans, et j'aime avoir des câblages explicites, donc je sais exactement ce qui est câblé où.

207
Andy White

Pendant longtemps, j’ai pensé qu’il était utile de disposer d’une "configuration déclarative et centralisée" comme les fichiers xml que nous utilisions tous auparavant. Ensuite, j'ai réalisé que la plupart des éléments contenus dans les fichiers n'étaient pas configuration - ils n'ont jamais été modifiés nulle part après le développement. Ensuite, j'ai réalisé que "centralisé" n'a de valeur que dans des systèmes de petite taille. Ce n'est que dans des systèmes de petite taille que vous pourrez créer un fichier de configuration dans son ensemble. Et quelle est vraiment la valeur de comprendre le câblage dans son ensemble, lorsque les mêmes "câblages" sont principalement dupliqués par des dépendances dans le code? Donc, la seule chose que j'ai gardée, ce sont des méta-données (annotations), qui sont encore assez déclaratives. Ces never changent au moment de l'exécution et ils never des données de "configuration" que quelqu'un changera à la volée - je pense donc que le conserver dans le code est agréable.

J'utilise autant que possible le câblage automatique complet. J'aime cela. Je ne retournerai pas au printemps à l'ancienne, à moins d'être menacé au canon. Mes raisons pour préférer pleinement @Autowired ont changé avec le temps.

À l'heure actuelle, je pense que la principale raison d'utiliser l'auto-câblage est qu'il y a une abstraction de moins dans votre système à surveiller. Le "nom de haricot" est effectivement parti. Il s'avère que le nom du bean n'existe que pour xml. Ainsi, une couche complète de indirections abstraites (où vous liez le nom de bean "foo" à bean "bar") a disparu. Maintenant, je connecte l'interface "Foo" directement dans mon bean, et l'implémentation est choisie par le profil d'exécution. Cela me permet de travailler avec le code lors du traçage des dépendances et des implémentations. Lorsque je vois une dépendance auto-câblée dans mon code, je peux simplement appuyer sur la touche "aller à la mise en oeuvre" dans mon IDE et la liste des mises en œuvre connues apparaît. Dans la plupart des cas, il n'y a qu'une mise en œuvre et je suis directement dans la classe. Cela ne peut pas être beaucoup plus simple, et je sais toujours exactement quelle implémentation est utilisée (je prétends que le contraire est plus proche de la vérité avec le câblage xml - drôle comment votre perspective change!)

Maintenant, vous pouvez dire que c'est juste une couche très simple, mais chaque couche d'abstraction que nous ajoutons à nos systèmes augmente la complexité. Je ne pense vraiment pas que le xml ait ajouté une valeur réelle à un système avec lequel j'ai travaillé. 

La plupart des systèmes avec lesquels je travaille ne disposent que de la configuration one de l'environnement d'exécution de production. Il peut y avoir d'autres configurations pour le test, etc.

Je dirais que le câblage automatique complet correspond au printemps de Ruby-on-Rails: il englobe la notion selon laquelle il existe un modèle d'utilisation normal et commun que la plupart des cas d'utilisation suivent. Avec la configuration XML, vous permettez de nombreuses utilisations de configuration cohérentes/incohérentes qui pourraient être intentionnelles. J'ai vu tellement de configurations XML aller trop loin avec des incohérences - est-ce qu'elle est refactorisée avec le code? Je pensais pas. Ces variations sont-elles là pour une raison? Généralement pas.

Nous utilisons à peine des qualificateurs dans notre configuration et avons trouvé d'autres moyens de résoudre ces problèmes. Il s’agit là d’un "inconvénient" évident: nous avons légèrement modifié la façon dont nous codons pour rendre l’interaction plus fluide avec le câblage automatique: un référentiel client n’implémente plus l’interface générique Repository<Customer> mais nous créons une interface CustomerRepository qui étend Repository<Customer>. Parfois, il y a aussi une astuce ou deux en matière de sous-classement. Mais cela ne fait généralement que nous indiquer un typage plus fort, ce qui, selon moi, est presque toujours une meilleure solution.

Mais oui, vous vous attachez à un style particulier de DI que le printemps fait surtout. Nous ne faisons même plus de paramètres publics pour les dépendances (vous pouvez donc soutenir que nous sommes +1 dans le département encapsulation/masquage des informations). Nous avons encore du code XML dans notre système, mais le code XML essentiellement only contient les anomalies. L'auto-câblage complet s'intègre parfaitement au xml.

La seule chose dont nous avons besoin maintenant est que le @Component, le @Autowired et le reste soient inclus dans un JSR (comme JSR-250 ), de sorte que nous n’ayons pas à nous relier au printemps. C’est comme cela que les choses se passaient dans le passé (le code Java.util.concurrent me vient à l’esprit), donc je ne serais pas tout à fait surpris si cela se reproduisait.

248
krosenvold

Pour moi, voici ce que j'aime/n'aime pas à propos de Spring et du câblage automatique.

Avantages:

  • L'auto-câblage supprime les mauvaises configurations XML.
  • Il est beaucoup plus facile d'utiliser des annotations, ce qui vous permet d'injecter directement à l'aide de champs, de méthodes de définition ou de constructeurs. Vous permet également d'annoter et de «qualifier» vos haricots injectés.

Les inconvénients:

  • L'utilisation du câblage automatique et des annotations vous rend dépendant des bibliothèques Spring où, comme pour la configuration XML, vous pouvez choisir de fonctionner avec ou sans Spring. Comme vous l'avez dit, vous devenez lié à un cadre DI.
  • En même temps, j'aime bien pouvoir «qualifier» les haricots, ce qui rend le code vraiment compliqué. Si vous devez injecter le même haricot à plusieurs endroits, j'ai vu le même nom de chaîne répété partout. Pour moi, cela semble avoir le potentiel d'erreurs.

J'ai commencé à utiliser le câblage automatique presque exclusivement au travail car nous dépendons tellement de l'intégration Spring que le problème de la dépendance est sans objet. J'ai travaillé sur un projet Spring MVC qui utilisait beaucoup le câblage automatique et qui était un peu difficile à comprendre.

Je pense que l'auto-câblage est un goût acquis. Une fois que vous vous y êtes habitué, vous réalisez à quel point il est puissant, facile et beaucoup moins pénible de fonctionner que la configuration XML.

26
Jared Knipp

Nous passons de @Autowire à la configuration XML dans notre grand projet. Le problème est très faible performance d'amorçage. Le scanner de transfert automatique charge toutes les classes à partir du chemin de classe de recherche de transfert automatique. Ainsi, de nombreuses classes sont chargées lors de l'initialisation Spring.

15
Masterhard

Il y a eu très peu de discussions sur le changement d'environnement. La plupart des projets sur lesquels j'ai travaillé étaient un réel problème d'injection de dépendances en fonction de l'environnement sur lequel nous travaillons. Avec xml config, c'est assez simple avec Spring EL, et je ne connais aucune solution de Nice avec des annotations. Je viens de comprendre un:

    @Value("#{${env} == "production" ? realService : dummyService}")
    private SomeService service;

Cela devrait fonctionner, mais pas une bonne solution à mon humble avis.

6
BTakacs

Je suis passé à @Autowire. Maintenir la configuration XML sur autre chose qu'un petit projet est devenu une tâche à part entière et la compréhension s'est rapidement dégradée. 

IntelliJ fournit un bon support (pas parfait) pour les annotations Spring.

4
Paul McKenzie

Mon point de vue sur ce sujet est que, la configuration XML réduit la clarté du code, en particulier dans les grands systèmes. 

Des annotations telles que @Component aggravent les choses. Il guide les développeurs pour rendre les objets mutables, car les dépendances ne peuvent plus être finalisées, étant donné que les constructeurs par défaut doivent être fournis. Les dépendances doivent être injectées via un setter public ou non contrôlées via @Autowired. [L'injection de dépendance est encore pire avec des classes qui instancient leurs dépendances, je le vois toujours dans du code nouvellement écrit!]. Par incontrôlé, je veux dire, dans les grands systèmes, lorsque plusieurs implémentations (ou enfants) du type sont disponibles, il est beaucoup plus compliqué de comprendre laquelle des implémentations était @Autowired, une complexité qui complique beaucoup la recherche d'informations sur les bogues. Cela signifie également que, supposément, vous avez un profil pour l’environnement de test et un autre pour la production, vos bugs de production ne se produisent que lorsque cela fait le plus mal - en production, au lieu de pouvoir les repérer dans l’environnement de test, voire mieux, à compiler le temps!

Je m'en tiens au milieu où je déclare mes classes de configuration (configuration Spring basée sur Java avec @Configuration)

Je déclare explicitement tous mes beans dans la ou les classes de configuration. J'utilise uniquement @Autowired dans la ou les classes de configuration, le but est de limiter la dépendance à Spring à la ou aux classes de configuration.

La @Configuration réside dans un package spécifique, c'est le seul endroit où l'analyse Spring est exécutée. (Cela accélère considérablement le temps de démarrage dans les grands projets)

Je m'efforce de rendre toutes mes classes immuables, en particulier les objets de données, JPA, Hibernate et Spring, ainsi que de nombreuses bibliothèques de sérialisation, qui semblent compromettre cela. Je m'éloigne de tout ce qui m'oblige à fournir des installateurs ou à supprimer le mot-clé final de ma déclaration de propriété.

Réduire les possibilités de modification des objets après leur création réduit considérablement les bogues dans les systèmes de grande taille, ainsi que le temps nécessaire pour rechercher un bogue, le cas échéant. 

Il semble également que cela oblige le développeur à mieux concevoir l’interaction entre les différentes parties du système. Les problèmes et les bogues deviennent de plus en plus des erreurs de compilation, ce qui réduit les pertes de temps et améliore la productivité.

3
Charbel

J'adore écrire avec des annotations au lieu de XML ..__ Selon le manuel de Spring et les dernières versions, XML et Annotation ont donné le même résultat.

C'est ma liste

Pro:

  • Supprimer la ligne inutile du xml
  • Simplifier le débogage du code: lorsque vous ouvrez une classe, vous pouvez lire ce que vous avez dans la classe 
  • Plus rapidement, un projet avec 400 lignes XML ou plus est lisible?

Les inconvénients:

  • N’est pas une implémentation Java standard, mais vous pouvez utiliser @Inject, qui est une API standard Java, afin que le bean reste un Pojo
  • Vous ne pouvez pas simplement utiliser partout, db connection e etc., mais ce n'est qu'un avis, je préfère avoir un endroit où lire toutes les configurations. 
1
Luca Preziati

Voici quelques expériences 
Avantages  

  • Facilite la configuration car on peut simplement utiliser l'annotation @Autowire
  • Vous ne voulez pas utiliser les méthodes setter, donc la classe sera plus propre

Les inconvénients

  • Bien coupler au fichier XML même si nous utilisons DI
  • Difficile à trouver la mise en oeuvre (Mais si vous utilisez des bonnes idées comme intellij, vous pouvez vous en débarrasser)

En ce qui concerne mes expériences personnelles, je n'ai pas beaucoup utilisé l'annotation @AutoWire, mais dans des cas de test. 

1
Rajith Delantha

Pour ma compréhension, @Autowired est le meilleur à utiliser lorsque vous vous référez à la référence d'interface et à l'utilisation de ses fonctions de substitution, mais je ne trouve que le seul problème avec cela est qu'il est parfois assigné à null lors de l'exécution.

0
Shubham kapoor