Introduction: Une dépendance circulaire est une référence imbriquée en boucle dans les classes N. Si cette dépendance circulaire se produit dans le développement quotidien à l'aide de la méthode du nouvel objet, le programme continuera à l'appeler Loop à l'exécution jusqu'à ce que la mémoire déborde et signale une erreur. Parlons de Spring si elle résout les dépendances circulaires.
Le premier type: Dépendance cyclique du paramètre du constructeur
Le conteneur de printemps placera chaque identifiant de haricots créé dans une "piscine de haricot actuelle" et l'identifiant de haricots restera dans cette piscine pendant le processus de création. Par conséquent, si vous constatez que vous êtes déjà dans la "piscine de haricots actuelle" pendant le processus de création, il sera lancé.
L'exception de haricot InCreationException indique une dépendance circulaire; Le haricot créé sera éliminé à partir de la "piscine de haricots actuellement créée".
Nous initialisons d'abord trois haricots.
classe publique Studenta {Private StudentB StudentB; public void SetStudentB (StudentB StudentB) {this.StudentB = StudentB; } public StudentA () {} public Studenta (StudentB StudentB) {this.StudentB = StudentB; }} classe publique StudentB {Private StudentC StudentC; public void SetStudentC (StudentC StudentC) {this.Studentc = StudentC; } public StudentB () {} public StudentB (StudentC StudentC) {this.Studentc = StudentC; }} classe publique StudentC {Private Studenta Studenta; public void SetStudenta (Studenta Studenta) {this.studenta = Studenta; } public StudentC () {} public StudentC (Studenta Studenta) {this.studenta = studenta; }}Ok, ce qui précède sont trois classes très basiques. La structure des paramètres de l'étudiant est StudentB. La structure des paramètres de StudentB est StudentC, et la structure des paramètres de StudentC est StudentA, ce qui crée une situation de dépendance circulaire.
Nous avons tous remis ces trois haricots à la gestion du printemps et les avons instanciés avec des constructions de paramètres
<bean id = "a"> <constructor-arg index = "0" ref = "b"> </ constructor-arg> </ane> <bean id = "b"> <constructor-arg index = "0" ref = "c"> </ constructor-arg> </ bean> <bean id = "c"> <constructor-arg index = "0" ref = "a"> </ constructor-aci
Voici la classe de test:
public class test {public static void main (String [] args) {applicationContext context = new ClassPathxmlApplicationContext ("com / zfx / student / applicationContext.xml"); //System.out.println(Context.getBean("a ", Studenta.class)); }}Le message d'erreur du résultat d'exécution est:
Causé par: org.springframework.beans.factory.beancurrentlyInCreationException:
Erreur de création de bean avec le nom «A»: Le bean demandé est actuellement en création: existe-t-il une référence circulaire non résoluble?
Si vous comprenez la phrase au début, vous ne devriez pas être surpris de signaler cette erreur. Le conteneur de printemps crée d'abord un singleton étudiant. Studenta dépend de StudentB, puis met un dans la "piscine de haricots actuelle". Pour le moment, StudentB est créé, StudentB dépend de StudentC, puis B est placé dans la "piscine de haricots actuelle". Pour le moment, StudentC est créé, StudentC dépend de Studenta. Cependant, pour le moment, l'étudiant est déjà dans la piscine, donc une erreur sera signalée. Parce que tous les haricots de la piscine n'ont pas été initialisés, ils dépendront des erreurs. (Le haricot initialisé sera retiré de la piscine)
Le deuxième type: méthode de setter singleton, méthode par défaut
Si vous voulez parler de l'injection de setter, nous ferions mieux de regarder une photo de haricots instantiaux au printemps
Comme indiqué dans les deux premières étapes de la figure, Spring instancie l'objet bean puis définit les propriétés de l'objet.
Modifiez le fichier de configuration pour l'injecter en mode SET:
<! - Scope = "singleton" (par défaut est la méthode singleton) -> <bean id = "a" scope = "singleton"> <propriété name = "studentb" ref = "b"> </ propriété> </-bean> <bean id = "b" scope = "singleton"> <propriété name = "studentc" Ref = "C"> </properfet> </EAN> </Ebgit name = "Studenta" Ref = "A"> </ Property> </bEAN>
Voici la classe de test:
public class test {public static void main (String [] args) {applicationContext context = new ClassPathxmlApplicationContext ("com / zfx / student / applicationContext.xml"); System.out.println (context.getBean ("A", Studenta.class)); }}Le résultat de l'impression est:
com.zfx.student.studenta@1fbfd6
Pourquoi ne signalez-vous pas une erreur en utilisant la méthode SET?
Regardons l'image ci-dessus. Spring d'abord instancie l'objet bean à l'aide de constructions. À l'heure actuelle, Spring mettra l'objet instancié dans une carte, et Spring fournit une méthode pour obtenir la référence d'objet instanciée avec l'attribut Unset. Sur la base de notre exemple, lorsque Spring instancie StudentA, StudentB et StudentC, il définira alors les propriétés de l'objet. À l'heure actuelle, Studenta s'appuiera sur StudentB et éliminera l'objet StudentB Singleton sur la carte, et ainsi de suite, il n'y aura pas de problème de boucle.
Ce qui suit est la méthode d'implémentation dans le code source Spring. Le code source suivant se trouve dans la classe par défaut de la classe BEACTERERICTERY.JAVA dans le package de bean de Spring
/ ** Cache des objets Singleton: Nom Bean -> Instance Bean (collection de cartes qui cache les objets instanciés singleton) * / Map final privé <String, objet> singletonObjects = new concurrentHashMap <String, objet> (64); / ** Cache des usines de Singleton: Nom Bean -> ObjectFactory (Singleton Factory Bean Cache Collection) * / Private Final Map <String, objectFactory> singletonfactory = new HashMap <String, objectFactory> (16); / ** Cache des premiers objets Singleton: Nom Bean -> Instance Bean * / Map finale privée <String, Object> EarlySingletonObjects = new HashMap <String, Object> (16); / ** Ensemble de singletons enregistrés, contenant les noms de bean dans l'ordre d'enregistrement * / set final privé <string> regritsingletons = new LinkedHashSet <string> (64); / ** * Ajouter une instance singleton * Résoudre le problème des références circulaires * Ajouter l'usine singleton donnée pour construire le singleton spécifié * si nécessaire. * <p> Pour être appelé à l'enregistrement impatient des singletons, par exemple pour pouvoir * résoudre les références circulaires. * @param beanname Le nom du bean * @param singletonfactory L'usine de l'objet singleton * / void protégé addSingletonfactory (string beanname, objectfactory singletonfactory) {assert.notnull (singletonfactory, "singleton factory ne pas être nulle"); synchronisé (this.singletonObjects) {if (! this.singletonobjects.containsKey (beanname)) {this.singletonfactories.put (beanname, singletonfactory); this.arlysingletonobject.remove (beanname); this.gisteredSingletons.Add (beanname); }}Le troisième type: prototype de secteur, prototype
Modifiez le fichier de configuration à:
<bean id = "a" <span style = "Color: # ff0000;"> scope = "Prototype" </span>> <propriété name = "StudentB" ref = "b"> </ propriété> </ bean> <bean id = "b" <span style = "Color: # ff0000;"> scope = "Prototype" </ span> </ Sprew name = "Studentc" Ref = "C"> </ Bean> </ Bean> </ Bean id = "c" <span style = "couleur: # ff0000;"> scope = "prototype" </span> <propriété name = "studentc" ref = "c"> </ propriété> </ank> <bean id = "c" <span style = "Color: # ff0000;"> scope = "promestype" </span> <propriété name = "studenta" Ref = "a"> </ property>
scope = "Prototype" signifie qu'un objet d'instance est créé à chaque fois que vous demandez. La différence entre les deux est: les haricots avec état utilisent la portée du prototype, tandis que les apatrides utilisent généralement la portée singleton singleton.
Cas de test:
public class test {public static void main (String [] args) {applicationContext context = new ClassPathxmlApplicationContext ("com / zfx / student / applicationContext.xml"); <strong> // Pour le moment, vous devez obtenir une instance de Spring Gerée, car maintenant scope = "Prototype" ne fera qu'instancier l'objet lorsque vous demandez à obtenir </strong> System.out.println (context.getBean ("A", Studenta.class)); }} Résultat d'impression:
Causé par: org.springframework.beans.factory.beancurrentlyInCreationException: Erreur Création de bean avec le nom «A»: Le bean demandé est actuellement en création: Existe-t-il une référence circulaire non résoluble?
Pourquoi le modèle prototype est-il mauvais?
Pour les haricots à portée de «prototype», le conteneur à ressort ne peut pas compléter l'injection de dépendance car le récipient à ressort ne cache pas les haricots dans les haricots portée «Prototype», donc un haricot créé ne peut pas être exposé à l'avance.
Ce qui précède est tout le contenu de cet article. J'espère que cela sera utile à l'apprentissage de tous et j'espère que tout le monde soutiendra davantage Wulin.com.