292 votes

Pourquoi est-printemps ' s ApplicationContext.getBean considéré comme mauvais ?

J'ai demandé à un général de Printemps à la question: Auto-cast Beans Spring , et plusieurs personnes répondent que l'appel du Printemps, ApplicationContext.getBean() devrait être évitée autant que possible. Pourquoi est-ce?

Comment dois-je avoir accès aux haricots, j'ai configuré le Printemps de créer?

Je suis à l'aide de Spring dans une application web non et qui avait prévu sur l'accès partagé ApplicationContext objet tel que décrit par LiorH.

Amendement

J'accepte la réponse ci-dessous, mais voici un autre prendre par Martin Fowler qui présente les avantages de l'Injection de Dépendance au lieu d'utiliser un Localisateur de Service (qui est essentiellement le même que l'appel d'une enveloppé ApplicationContext.getBean()).

En partie, Fowler états-unis, "Avec le service localisateur de la classe d'application le demande [le service] explicitement par un message à la localisation. Avec l'injection il n'y a pas de demande explicite, le service s'affiche dans la classe d'application - d'où l'inversion de contrôle. L'Inversion de contrôle est une caractéristique commune des cadres, mais c'est quelque chose qui vient à un prix. Il a tendance à être difficile à comprendre, et conduit à des problèmes lorsque vous essayez de déboguer. Donc dans l'ensemble je préfère l'éviter [Inversion de Contrôle], à moins que j'en ai besoin. Ce n'est pas à dire que c'est une mauvaise chose, juste que je pense qu'il a besoin de se justifier sur l'alternative plus simple."

214voto

ColinD Points 48573

Je l'ai mentionné dans un commentaire sur l'autre question, mais l'idée de l'Inversion de Contrôle est d'avoir aucun de vos classes de savoir ou de soins de la façon dont ils obtiennent les objets dont ils dépendent. Cela rend plus facile de changer ce type de mise en œuvre d'une dépendance que vous utilisez à tout moment. Il rend également les classes facile à tester, que vous pouvez fournir des simulacres d'implémentations de dépendances. Enfin, il rend les classes plus simple et plus concentré sur le cœur de leur responsabilité.

Appelant ApplicationContext.getBean() n'est pas d'Inversion de Contrôle! Pendant qu'il est encore facile de changer ce que la mise en oeuvre est configuré pour le haricot nom, la classe s'appuie directement sur le Printemps de prévoir que la dépendance et ne pouvez pas obtenir de toute autre manière. Vous ne pouvez pas simplement faire votre propre maquette de mise en œuvre dans une classe de test et transmettre à vous-même. Fondamentalement défaites Printemps de l'objet en tant que conteneur d'injection de dépendance.

Partout où vous voulez-à-dire:

MyClass myClass = applicationContext.getBean("myClass");

en revanche, vous pouvez, par exemple, déclarer une méthode:

public void setMyClass(MyClass myClass) {
   this.myClass = myClass;
}

Et puis dans votre configuration:

<bean id="myClass" class="MyClass">...</bean>

<bean id="myOtherClass" class="MyOtherClass">
   <property name="myClass" ref="myClass"/>
</bean>

Le printemps sera alors automatiquement injecter myClass en myOtherClass.

Déclarer tout de cette façon, et à la racine de tout cela quelque chose comme:

<bean id="myApplication" class="MyApplication">
   <property name="myCentralClass" ref="myCentralClass"/>
   <property name="myOtherCentralClass" ref="myOtherCentralClass"/>
</bean>

MyApplication est le quartier le plus central de la classe, et dépend au moins indirectement sur tous les autres services dans votre programme. Lors de l'amorçage, dans votre main méthode, vous pouvez appeler applicationContext.getBean("myApplication") mais vous ne devriez pas besoin d'appeler getBean() n'importe où ailleurs!

66voto

Moa Points 187

Les raisons de préférer Service Locator plus de l'Inversion de Contrôle (IoC) sont:

1) Service Locator est beaucoup, beaucoup plus facile pour d'autres personnes de la suite dans votre code. Cio est la "magie", mais l'entretien des programmeurs doivent comprendre vos alambiqué Printemps des configurations et toutes les myriade de lieux à comprendre comment vous wired vos objets.

2) le Cio est terrible pour le débogage des problèmes de configuration. Dans certaines classes d'applications, l'application ne démarre pas lorsque mal configuré et que vous ne pouvez pas obtenir une chance de l'étape par le biais de ce qui se passe avec un débogueur.

3) le Cio est principalement basé sur XML (Annotations améliorer les choses, mais il y a encore beaucoup de XML). Cela signifie que les développeurs ne peuvent pas travailler sur votre programme, à moins qu'ils connaissent la magie balises définies par le Printemps. Il n'est pas assez bon à savoir Java plus. Ce entrave le moins d'expérience des programmeurs (ie. c'est en fait une mauvaise conception de l'utilisation d'un plus compliqué solution quand une solution plus simple, tels que le Service de localisation, à satisfaire aux mêmes exigences). De Plus, le soutien pour le diagnostic de XML problèmes est beaucoup plus faible que le support de Java problèmes.

4) l'injection de Dépendance est plus adapté pour les grands programmes. La plupart du temps, la complexité n'est pas la peine.

5) Printemps est Souvent utilisé dans le cas où vous "pouvez changer la mise en œuvre plus tard". Il y a d'autres façons d'y parvenir sans la complexité de Printemps du Cio.

6) Pour les applications web (Java EE Guerres), le Ressort contexte est effectivement lié au moment de la compilation (sauf si vous voulez les opérateurs de grub autour du contexte dans le schéma de la guerre). Vous pouvez faire de Printemps de l'utilisation de la propriété des fichiers, mais avec des servlets propriété fichiers doivent se trouver à un emplacement prédéterminé, ce qui signifie que vous ne pouvez pas déployer plusieurs servlets le même temps sur la même case. Vous pouvez utiliser le Printemps avec JNDI pour modifier les propriétés à servlet temps de démarrage, mais si vous êtes en utilisant JNDI pour l'administrateur-modifiable dans les paramètres de la nécessité pour le Printemps lui-même diminue (depuis JNDI est effectivement un Localisateur de Service).

7) Avec le Printemps, vous pouvez perdre le Contrôle du programme si le Printemps est en train d'envoyer à vos méthodes. C'est pratique et travaille pour de nombreux types d'applications, mais pas tous. Vous pouvez avoir besoin de contrôler le flux de programme lorsque vous avez besoin pour créer des tâches (threads, etc) lors de l'initialisation ou de la nécessité modifiables ressources que le Printemps ne connaissais pas wehen le contenu est lié à votre GUERRE.

Le printemps est très bonne pour la gestion des transactions et a quelques avantages. C'est juste que le Cio peut être plus de génie dans de nombreuses situations, et d'introduire injustifiée de la complexité pour les responsables. Ne pas utiliser automatiquement Cio sans penser à des façons de ne pas l'utiliser en premier.

25voto

Fritz Meissner Points 871

Il est vrai que l'inclusion de la classe dans application-context.xml permet d'éviter l'utilisation getBean. Cependant, même ce qui est en fait inutile. Si vous écrivez une application autonome et vous NE voulez PAS de votre permis de classe dans application-context.xml, vous pouvez utiliser le code suivant pour avoir le Printemps autowire le pilote de dépendances:

public class AutowireThisDriver {

    private MySpringBean mySpringBean;    

    public static void main(String[] args) {
       AutowireThisDriver atd = new AutowireThisDriver(); //get instance

       ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext(
                  "/WEB-INF/applicationContext.xml"); //get Spring context 

       //the magic: auto-wire the instance with all its dependencies:
       ctx.getAutowireCapableBeanFactory().autowireBeanProperties(atd,
                  AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE, true);        

       // code that uses mySpringBean ...
       mySpringBean.doStuff() // no need to instantiate - thanks to Spring
    }

    public void setMySpringBean(MySpringBean bean) {
       this.mySpringBean = bean;    
    }
}

J'ai eu besoin de faire cette une couple de fois, quand j'ai une sorte de classe autonome qui nécessite l'utilisation de certains aspects de mon application (par exemple pour les tests) mais je ne veux pas l'inclure dans l'application-contexte, car il n'est pas réellement partie de l'application. Notez également que cela permet d'éviter le besoin de chercher les haricots à l'aide d'un nom de Chaîne, que j'ai toujours pensé était laid.

22voto

Brandon Yarbrough Points 8558

Un des meilleurs avantages de l'utilisation de quelque chose comme le Printemps, c'est que vous n'avez pas de fil de vos objets. De Zeus, chef divisions de l'ouvrir et de vos classes apparaissent, entièrement formé avec toutes leurs dépendances créé et câblé dans les, au besoin. C'est magique et fantastique.

Plus vous en dites ClassINeed classINeed = (ClassINeed)ApplicationContext.getBean("classINeed");, moins de magie que vous obtenez. Moins de code est presque toujours la meilleure. Si votre classe vraiment besoin d'un ClassINeed bean, pourquoi ne pas vous venez de fil?

Cela dit, quelque chose de bien besoin pour créer le premier objet. Il n'y a rien de mal avec votre méthode principale de l'acquisition d'un haricot ou deux par getBean(), mais vous devriez éviter, car à chaque fois que vous l'utilisez, vous n'êtes pas vraiment à l'aide de toute la magie du Printemps.

16voto

erickson Points 127945

La motivation est d’écrire du code qui ne dépend pas explicitement sur le printemps. De cette façon, si vous choisissez de passer des conteneurs, vous n’avez pas de réécrire tout le code.

Penser le conteneur que quelque chose est invisible à votre code, comme par magie, fournissant à ses besoins, sans y être invitée.

Injection de dépendance est un contrepoint au modèle « localisateur de service ». Si vous allez aux dépendances de recherche par nom, vous pourriez aussi bien se débarrasser du conteneur DI et utilisez quelque chose comme JNDI.

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