Question

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

Juste pour préciser, 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ù.

Était-ce utile?

La solution

Pendant longtemps, j’ai pensé qu’il était utile d’avoir une & "configuration centralisée, déclarative, &"; comme les fichiers XML que nous utilisions tous. Ensuite, j'ai réalisé que la plupart des éléments contenus dans les fichiers n'étaient pas de 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 la valeur que dans les très petits systèmes - ce n’est que dans les petits systèmes que vous serez en mesure de 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 conservée, ce sont des méta-données (annotations), qui sont encore assez déclaratives. Ces jamais ne changent pas au moment de l'exécution et ils ne sont jamais & "Configuration &"; données que quelqu'un va changer à la volée - donc je pense que le garder 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 de préférer pleinement @Autowired ont changé au fil du temps.

À l'heure actuelle, je pense que la raison la plus importante d'utiliser le câblage automatique est qu'il y a une abstraction de moins dans votre système à surveiller. Le & Quot; nom du haricot & Quot; 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 lieriez nom-haricot & "Foo &"; Haricot & "Bar &";) A disparu. Maintenant, je câble le & Quot; Foo & Quot; interfacer directement dans mon haricot, et la mise en œuvre est choisie par le profil au moment de l'exécution. Cela me permet de travailler avec du code lors du traçage des dépendances et des implémentations. Quand je vois une dépendance auto-câblée dans mon code, je peux simplement appuyer sur & "Aller à la mise en oeuvre &"; La clé de mon IDE et plus vient la liste des implémentations connues. 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 - c'est 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 jamais ajouté une valeur réelle à un système avec lequel j'ai travaillé.

La plupart des systèmes avec lesquels je travaille n’ont que une configuration de l’environnement d’exécution de production. Il peut y avoir d’autres configurations à tester, etc.

.

Je dirais que le câblage automatique est le principe du ressort: il englobe l’idée selon laquelle il existe un modèle d’usage normal et commun suivi par la plupart des cas d’utilisation. Avec la configuration XML, vous autorisez de nombreuses utilisations de configuration cohérentes / incohérentes qui pourraient ne pas être voulues. 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. Ceci est un & Quotient désavantageux & Quot; nous rencontrons: 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 @Component. 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, surtout au printemps. 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 ne contient que contient l'anomalies. Le câblage automatique complet s'intègre parfaitement au XML.

La seule chose dont nous avons besoin maintenant est que les java.util.concurrent, <=> et le reste soient inclus dans un JSR (comme JSR-250 ), nous n’avons donc pas à nous associer au printemps. C’est comme cela que les choses se passaient dans le passé (<=> ça me vient à l’esprit), donc je ne serais pas tout à fait surpris que cela se reproduise.

Autres conseils

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.

Inconvénients:

  • L'utilisation du câblage automatique et des annotations vous rend dépendant des bibliothèques Spring, où vous pouvez choisir, comme pour la configuration XML, 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, pour moi cela rend le code vraiment compliqué. Si vous avez besoin d'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 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 y êtes habitué, vous réalisez à quel point il est puissant, facile et beaucoup moins stressant de fonctionner que la configuration XML.

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 avec impatience lors de l'initialisation Spring.

Il y a eu très peu de discussions sur les environnements de changement. 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 intéressante 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.

Je suis passé à @Autowire. Le maintien de 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.

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.

Les annotations telles que @Component aggravent encore 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, à temps de compilation!

Je reste sur le terrain où je déclare mes classes de configuration (configuration Spring basée sur Java utilisant @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 printanière s'exécute. (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, ce qui semble le compromettre. 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é.

La réduction des 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é.

Voici quelques expériences
Avantages

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

Inconvénients

  • Coupler étroitement au fichier XML même si nous utilisons DI
  • Difficile de trouver une implémentation (mais si vous utilisez des bonnes idées comme intellij, vous pouvez vous en débarrasser)

D'après mes expériences personnelles, je n'ai pas beaucoup utilisé l'annotation @AutoWire, mais dans des cas de test.

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

Ceci est ma liste

Pro:

  • Supprimer la ligne inutile du code XML
  • Simplifiez 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?

Inconvénients:

  • N’est pas une implémentation Java standard, mais vous pouvez passer à @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.

À ma connaissance, @Autowired est ce qu'il y a de mieux à utiliser tout en faisant référence à la référence d'interface et en utilisant ses fonctions de substitution, mais je ne trouve que le problème, c'est qu'il est parfois assigné à null lors de l'exécution.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top