Quels sont les avantages et les inconvénients de l'utilisation de @Autowired dans une classe qui sera câblée au printemps?
Juste pour clarifier, je parle spécifiquement de l' annotation @Autowired , pas 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 qu'elles sont liées à un cadre DI, plutôt que d'être simplement des POJO. Je suis peut-être un glouton pour la punition, mais j'aime 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ù.
Réponses:
Pendant longtemps, j'ai cru qu'il y avait une valeur à avoir une "configuration centralisée et déclarative" comme les fichiers xml que nous utilisions tous. Ensuite, j'ai réalisé que la plupart des éléments des fichiers n'étaient pas de configuration - ils n'ont jamais été modifiés n'importe où après le développement. Ensuite, j'ai réalisé que "centralisé" n'a de valeur que dans des systèmes assez petits - ce n'est que dans les petits systèmes que vous pourrez jamais bloquer un fichier de configuration dans son ensemble . Et quelle est vraiment la valeur de la compréhension du câblage dans son ensemble, lorsque les mêmes "câblages" sont pour la plupart dupliqués par des dépendances dans le code? Donc, la seule chose que j'ai gardée, ce sont les métadonnées (annotations), qui sont toujours en quelque sorte déclaratives. Ceux-ci ne changent jamais à l'exécution et ils ne les données de "configuration" que quelqu'un changera à la volée - donc je pense que les conserver dans le code est bien.
J'utilise autant que possible le câblage automatique complet. J'aime cela. Je ne reviendrai pas au printemps à l'ancienne à moins d'être menacé à bout portant. 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 de l'utilisation du câblage automatique est qu'il y a une abstraction de moins dans votre système à suivre. Le "nom du bean" a effectivement disparu. Il s'avère que le nom du bean n'existe qu'en raison de xml. Ainsi, une couche complète d'indirections abstraites (où vous câblez le nom du bean "foo" dans le "bar" du bean) 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 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 la touche "aller à l'implémentation" dans mon IDE et la liste des implémentations connues apparaît. Dans la plupart des cas, il n'y a qu'une seule implémentation et je suis directement dans la classe. Pouvez' 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!)
Vous pouvez maintenant dire que ce n'est qu'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é de valeur réelle à un système avec lequel j'ai travaillé.
La plupart des systèmes avec lesquels j'ai déjà travaillé n'ont qu'une seule configuration de l'environnement d'exécution de production. Il peut y avoir d'autres configurations pour le test et ainsi de suite.
Je dirais que le câblage automatique complet est le rubis sur rails du printemps: il embrasse la notion qu'il existe un modèle d'utilisation normal et commun que la plupart des cas d'utilisation suivent. Avec la configuration XML, vous autorisez de nombreuses utilisations de configuration cohérentes / incohérentes qui peuvent / peuvent ne pas être prévues. J'ai vu tellement de configuration xml passer par dessus bord avec des incohérences - est-ce qu'elle est refactorisée avec le code? Je ne pensais pas. Ces variations existent-elles pour une raison? Généralement non.
Nous utilisons à peine des qualificatifs dans notre configuration et avons trouvé d'autres moyens de résoudre ces situations. C'est un "désavantage" évident que nous rencontrons: nous avons légèrement changé la façon dont nous codons pour le rendre plus fluide avec le câblage automatique: un référentiel client n'implémente plus l'
Repository<Customer>
interface générique mais nous créons une interfaceCustomerRepository
qui s'étendRepository<Customer>
. Parfois, il y a aussi une ou deux astuces en matière de sous-classement. Mais cela nous pointe généralement vers une frappe plus forte, ce qui est presque toujours une meilleure solution.Mais oui, vous êtes lié à un style particulier de DI que le printemps fait. Nous ne rendons même plus de paramètres publics pour les dépendances (vous pouvez donc affirmer que nous sommes +1 dans le département d'encapsulation / masquage des informations) Nous avons encore du XML dans notre système, mais le XML ne contient essentiellement que les anomalies. Le câblage automatique complet s'intègre parfaitement avec xml.
La seule chose dont nous avons besoin maintenant est que le
@Component
,@Autowired
et le reste soit inclus dans un JSR (comme le JSR-250 ), donc nous n'avons pas à nous lier au ressort. C'est ainsi que les choses se sont passées dans le passé (les choses me viennentjava.util.concurrent
à l'esprit), donc je ne serais pas entièrement surpris si cela se reproduisait.la source
Pour moi, voici ce que j'aime / n'aime pas dans le ressort et le câblage automatique.
Avantages:
Les inconvénients:
J'ai commencé à utiliser le câblage automatique presque exclusivement au travail, car nous dépendons tellement de l'intégration de 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 était un peu difficile à comprendre.
Je pense que le câblage automatique 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 mal à la tête que de travailler avec la configuration XML.
la source
Nous passons de @Autowire à la configuration XML dans notre grand projet. Le problème réside dans les performances d'amorçage très faibles. Le scanner de câblage automatique charge toutes les classes à partir du chemin de classe de recherche de câblage automatique, de sorte que de nombreuses classes sont chargées avec impatience lors de l'initialisation de Spring.
la source
Il y a eu très peu de discussions sur la commutation des environnements. La plupart des projets sur lesquels j'ai travaillé étaient un vrai problème pour injecter des dépendances en fonction de l'environnement sur lequel nous travaillons. Avec la configuration xml, c'est assez simple avec Spring EL, et je ne connais aucune bonne solution avec des annotations. Je viens d'en découvrir un:
Cela devrait fonctionner, mais pas une bonne solution à mon humble avis.
la source
@Profiles
et@Configuration
: blog.springsource.org/2011/02/14/… Voir aussi l'autre fil: stackoverflow.com/questions/13490393/…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.
la source
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 comme @Component aggravent les choses. Il aide les développeurs à rendre les objets mutables, car les dépendances ne peuvent plus être définitives, étant donné que les constructeurs par défaut doivent être fournis. Les dépendances doivent être injectées via le setter public ou non contrôlées via @Autowired. [encore pire l'injection de dépendances est compromise avec des classes qui instancient leurs dépendances, je le vois toujours dans du code nouvellement écrit!]. Par non contrôlé, je veux dire, dans les grands systèmes, lorsque plusieurs implémentations (ou enfants) du type sont disponibles, il est beaucoup plus difficile de comprendre laquelle des implémentations était @Autowired, une complexité qui rend l'enquête sur les bogues beaucoup plus difficile. Cela signifie également que, soi-disant, vous avez un profil pour l'environnement de test et un autre pour la production,
Je m'en tiens au milieu où je déclare ma (mes) classe (s) de configuration (configuration Spring basée sur java en utilisant @Configuration)
Je déclare explicitement tous mes beans dans la ou les classes de configuration. J'utilise uniquement @Autowired dans les classes de configuration, le but est de limiter la dépendance de Spring aux classes de configuration
La @Configuration réside dans un package spécifique, c'est le seul endroit où l'analyse de printemps s'exécute. (Cela accélère considérablement le démarrage dans les grands projets)
Je m'efforce de rendre toutes mes classes immuables, en particulier l'objet de données, JPA, Hibernate et Spring, ainsi que de nombreuses bibliothèques de sérialisation semblent miner cela. Je m'éloigne de tout ce qui m'oblige à fournir des setters, ou je retire le mot-clé final de ma déclaration de propriété.
Réduire les possibilités de changer des objets après leur création, réduit considérablement les bogues dans les grands systèmes ainsi que le temps de trouver un bogue lorsqu'il existe.
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 d'erreurs de compilation, ce qui réduit le temps perdu et améliore la productivité.
la source
Voici quelques - unes d'expérience
Pros
Les inconvénients
À partir de mes expériences personnelles, je n'ai pas beaucoup utilisé l'annotation @AutoWire, mais dans les cas de test.
la source
J'adore vraiment écrire avec des annotations, au lieu de XML. Selon le manuel Spring et les dernières versions, XML et Annotation ont obtenu le même résultat.
C'est ma liste
Pro:
Les inconvénients:
la source
Pour ma compréhension, @Autowired est le meilleur à utiliser tout en se référant à la référence d'interface et en utilisant ses fonctions de remplacement, mais je trouve que le problème est qu'il est parfois attribué à null lors de l'exécution.
la source