Cet article présente une brève discussion sur le principe d'injection de dépendance des conteneurs Spring IOC et le partage avec vous, comme suit:
La tâche principale d'initialiser le conteneur IOC est d'établir une carte de données BeanDefinition dans le conteneur IOC. Je n'ai pas vu le conteneur IOC injecter la relation de dépendance au haricot.
En supposant que le conteneur IOC actuel a chargé des informations sur les bean définies par l'utilisateur, l'injection de dépendance se produit principalement en deux étapes.
Dans des circonstances normales, il est déclenché lorsque l'utilisateur demande un haricot du conteneur IOC pour la première fois.
Cependant, nous pouvons contrôler l'attribut Lazy-Init dans les informations de la définition de la haricot pour permettre au conteneur de préinstancer le haricot, c'est-à-dire que le processus d'injection de dépendance de certains haricots est terminé pendant le processus d'initialisation.
1. Injection de dépendance déclenchée par getbean
Dans l'interface de conteneur IOC de base Beanfactory, il existe une définition d'interface pour GetBean. L'implémentation de cette interface est l'endroit où l'injection de dépendance de déclenchement se produit. Afin de comprendre davantage le processus d'injection de dépendance, nous commençons par la classe de base AbstractBeanfactory de DefaultListableBeanFactory pour jeter un œil à la mise en œuvre de GetBean
// voici l'implémentation de l'interface beanfactory, telle que la méthode d'interface GetBean // Ces méthodes d'interface GetBean sont finalement implémentées en appelant DogetBean @Override public objet Getbean (nom de chaîne) lève BeanSexception {return dogetBean (name, null, null, false); } @Override public <t> t getBean (String Name, class <T> requiredType) lève BeanSexception {return doGetBean (name, requiredType, null, false); } @Override public Object GetBean (String Name, Object ... Args) lève BeanSexception {return doGetBean (name, null, args, false); } public <T> t getBean (String Name, class <T> requiredType, object ... args) lève BeanSexception {return doGetBean (name, requiredType, args, false); } // C'est là que le haricot est réellement obtenu, c'est-à-dire où l'injection de dépendance est déclenchée @SuppressWarnings ("Unchecked") protégé <t> t DogetBean (nom de chaîne finale, classe finale <T> requiseType, final objet [] args, boolean typcheckonly) thorwings; Haricot d'objet; // Vérifiez avec impatience le cache singleton pour les singletons enregistrés manuellement. // Vérifiez avec impatience le cache singleton pour les singletons enregistrés manuellement. // Vérifiez avec impatience le cache Singleton pour les singletons d'enregistrement manuel // Reproche d'abord les haricots du cache et traitez les haricots singleton qui ont été créés. Ne créez pas à plusieurs reprises objet SharedInstance = GetSingleton (beanname); if (sharedInstance! = null && args == null) {if (logger.isdebugeNabled ()) {if (issingletamUrlyInCreation (beanname)) {Logger.debug ("Retour Eaderly Cached Instance de Singleton Bean '" + Beanname + "" qui n'est pas entièrement initialisé mais une conséquence d'une référence circulaire "); } else {Logger.debug ("Renvoi d'instance mise en cache de Singleton Bean '" + Beanname + "'"); }} // Le GetObjectForBeanInstance termine ici le traitement pertinent de FactoryBean pour obtenir le traitement pertinent de FactoryBean pour obtenir les résultats de production de FactoryBean. La différence entre Beanfactory et FactoryBean a été mentionnée plus tôt. Ce processus sera analysé en détail plus tard. = GetObjectForBeAnstance (SharedInstance, Name, Beanname, NULL); } else {// échouer si nous créons déjà cette instance de bean: // nous sommes supposés dans une référence circulaire. if (isPrototyPyTyCurrentlyInCreation (beanname)) {lancez new BeanCurrentlyInCreationException (beanname); } // // Vérifiez si la définition BeanDefinition dans le conteneur IOC existe. S'il n'existe pas dans l'usine actuelle, suivez la chaîne Parent Beanfactory et regardez vers le haut le BeanFactory ParentBeanFactory = GetParentBeanFactory (); if (parentBeanFactory! = null &&! ContintainBeAndeFinition (beanname)) {// non trouvé -> Vérifiez le parent. String nametOlookup = originalBeanName (name); if (args! = null) {// Délégation à parent avec des args explicites. return (t) parentBeanfactory.getBean (nametolookup, args); } else {// no args -> déléguer à la méthode GetBean standard. return parentBeanFactory.getBean (nametolookup, requiredType); }} if (! typeCheckonly) {MarkBeAnascreated (beanname); } essayez {// obtenir le beandefinition final rootBeAnDefinition mbd = getMergedLocalBeAnDefinition (beanname); CheckmergedBeAnDefinition (MBD, Beanname, Args); // Garantir l'initialisation des haricots dont dépend le haricot actuel. // Obtenez de manière récursive tous les haricots dont le haricot actuel dépend de (le cas échéant) de la chaîne [] DEFENSON = MBD.GetDependSon (); if (Defeentson! = null) {for (String dep: DelateSon) {if (isDependent (beanname, dep)) {Throw new BeanCreationException (MBD.GetResourcedEsseScription (), beanname, "circulaire dépend-on entre '" + beanname + "' et '" + dep + ""); } RegisterDependentBean (DEP, beanname); getBean (DEP); }} // Créer une instance de bean singleton en appelant la méthode CreateBean if (mbd.issingleton ()) {sharedInstance = GettingLeton (beanname, nouveau objetFactory <objet> () {@Override Object GetObject () lance BeanSexception {try {return CreateBean (beanname, mbd, args); Instance de Singleton Cache: il pourrait y avoir été mis en œuvre // par le processus de création, pour permettre une résolution de référence circulaire. bean = getObjectForBeanInstance (SharedInstance, Name, Beanname, MBD); } // C'est l'endroit idéal pour créer un prototype de bean else if (mbd.isprototype ()) {// c'est un prototype -> créer une nouvelle instance. Object PrototypeInSance = NULL; essayez {avantprototypeCreation (beanname); PrototypeInSance = CreateBean (beanname, mbd, args); } enfin {AfterPrototyPeCreation (beanname); } bean = getObjectForBeanInstance (prototypeInstance, nom, beanname, mbd); } else {String scopename = mbd.getScope (); Scope finale Scope = this.scopes.get (scopename); if (scope == null) {lancez new illégalStateException ("Aucune étendue enregistrée pour le nom de la lunette '" + scopename + "'"); } essayez {objet ScopedInstance = Scope.get (Beanname, New ObjectFactory <Bject> () {@Override public Object GetObject () lève BeanSexception {avantprotypeCreation (Beanname); Try {return CreateBean (Beanname, Mbd, Args);} enfin {afterProtyPeCreatation (beanname);}); bean = getObjectForBeanInstance (ScopedInstance, nom, beanname, MBD); } catch (illégalStateException ex) {Throw New BeanCreationException (Beanname, "Scope '" + Scopename + "' n'est pas actif pour le thread actuel; considérer" + "définir un proxy lune }}} catch (beanSexception ex) {CleanUpafterBeanCreationFailure (beanname); jeter ex; }} // Vérifiez si le type requis correspond au type de l'instance de bean réelle. // La vérification de type est effectuée sur le haricot créé ici. S'il n'y a pas de problème, le haricot nouvellement créé est retourné. Ce haricot est déjà un haricot contenant la dépendance if (requiredType! = Null && bean! = Null &&! RequiredType.isAssignableFrom (bean.getClass ())) {try {return getTypeConverter (). Convertifnecessary (bean, requiredType); } catch (typeMismatchException ex) {if (logger.isdebugeNable ()) {logger.debug ("n'a pas réussi à convertir bean '" + name + "' à type requis '" + classutils.getqualifiedName (requiretype) + "'" ", ex); } Jetez un nouveau beannotofrequiredTypeException (nom, requiredType, bean.getClass ()); }} return (t) bean; }L'injection de dépendance est déclenchée ici. L'injection de dépendance se produit lorsque les données de la définition BeanDefinition dans le conteneur ont été établies. Bien que nous puissions décrire le conteneur IOC de la manière la plus simple, c'est-à-dire le traiter comme un hashmap, nous pouvons seulement dire que ce hashmap est la structure de données la plus basique du conteneur, pas le conteneur IOC entier.
Ce processus d'injection de dépendance sera expliqué en détail ci-dessous. La figure 1.1 montre le processus général d'injection de dépendance.
Figure 1.1 Processus d'injection de dépendance
Getbean est le point de départ de l'injection de dépendance. Après cela, CreateBean dans AbstractAutowireCapableBeanFactory sera appelé pour produire les haricots requis, et l'initialisation des haricots est également traitée, comme la mise en œuvre de la définition d'attribut d'initiation dans le beandefinition, le post-processeur de bean, etc.
@Override Protected Object CreateBean (string beanname, rootBeAndefinition mbd, object [] args) lève beanCreationException {if (logger.isdebugeNabled ()) {logger.debug ("Création de l'instance de bean '" + beanname + "'"); } RootBeAnDefinition mbdtouse = mbd; // Assurez-vous que la classe de bean est réellement résolu à ce stade, et // cloner la définition de bean en cas d'une classe résolue dynamiquement // qui ne peut pas être stockée dans la définition du bean fusionnée partagée. // Nous déterminons ici si le bean à créer peut être instancié, si cette classe peut être chargée via la classe de chargeur de classe <?> RESOLVEDCLASS = RESOLOLBEANCLASS (MBD, beanname); if (résolvedClass! = null &&! mbd.hasbeANClass () && mbd.getBeANClassName ()! = null) {mbdtouse = new rootBeAlDefinition (MBD); mbdtouse.setBeANClass (RésolvedClass); } // Préparer les remplacements de la méthode. essayez {mbdtouse.prePareMethodoverrides (); } catch (beanDefinitionValidationException ex) {lancez new BeanDefinitionStoreException (mbdtouse.getResourcedScription (), beanname, "La validation des remplacements de la méthode a échoué", ex); } Essayez {// Donnez à BeanPostProcessors une chance de renvoyer un proxy au lieu de l'instance de bean cible. // Si le bean a configuré le postprocesseur, alors l'objet proxy renvoyé Bean = ResolveBeforeInstanciation (beanname, mbdtouse); if (bean! = null) {return bean; }} catch (Throwable ex) {lancez new BeanCreationException (mbdtouse.getResourceDeScription (), beanname, "BeanPostProcessor avant l'instanciation du haricot", ex); } try {object beanInstance = doCreateBean (beanname, mbdtouse, args); if (logger.isdebugeNabled ()) {logger.debug ("Création finie de la création de bean '" + beanname + "'"); } return beaninstance; } catch (beanCreationException ex) {// une exception détectée précédemment avec un contexte de création de bean déjà déjà ... throw ex; } Catch (implicitement AppetedSingLetLexception ex) {// Un illégalStateException à communiquer jusqu'à DefaultSingletOnBeanRegistry ... Throw Ex; } Catch (Throwable Ex) {Throw New BeanCreationException (Mbdtouse.getResourcedEcriScription (), Beanname, "Exception inattendue pendant la création de bean", ex); }} // À côté de DOCreate pour voir comment les haricots sont générés objet protégé DOCreateBean (Final String Beanname, Final rootBeAnDefinition MBD, objet final [] args) {// Instancier le bean. // Utilisé pour maintenir l'objet bean créé beanwrapper instanceWrapper = null; // S'il s'agit d'un singleton, effacez d'abord le haricot du même nom dans le cache if (mbd.issingleton ()) {instanceWrapper = this.factoryBeanInstanceCache.Remove (beanname); } // C'est l'endroit pour créer le bean, et il se fait par createBeAnSance if (instanceWrapper == null) {// Créer une nouvelle instance basée sur le bean spécifié en utilisant la stratégie correspondante, telle que: méthode d'usine, injection automatique du constructeur, simple initialisation instancewrapper = createBeanInstance (beanname, mbd, args); } final objet bean = (instanceWrapper! = null? instancewrapper.getWrapyInSance (): null); Class <?> BeanType = (instanceWrapper! = Null? InstanceWrapper.getWrapyClass (): null); // Permettez aux post-processeurs de modifier la définition du bean fusionné. Synchronized (MBD.PostProcessingLock) {if (! MBD.PostProcessed) {ApplyMergedBeAnDeFinitionPostProcessors (MBD, beanType, Beanname); mbd.PostProcessed = true; }} // cache des singletons avec impatience pour pouvoir résoudre les références circulaires // même lorsqu'elles sont déclenchées par des interfaces de cycle de vie comme BeanfactoryAware. // est-il nécessaire d'exposer à l'avance: singleton et autoriser les dépendances cycliques et le bean actuel est en cours de création, détecter les dépendances cycliques booléennes de précaution EarlySingExpose = (mbd.issingleton () && this.AllowcircularReferences && issingletCurrentelyInCreation (beanname)); if (EarlySingletOnExpose) {if (logger.isdebugeNable ()) {logger.debug ("cache-cache avec impatience '" + beanname + "' pour permettre de résoudre les références circulaires potentielles"); } // Pour éviter les dépendances à cycle en retard, l'objetFactory qui crée une instance peut être ajouté à l'usine avant la fin de l'initialisation du bean. AddSingletOnfactory (beanname, nouvel objetFactory <Bject> () {@Override public objet getObject () lève à nouveau BeanSexception {// reyyyez les références à des haricots, en utilisant principalement SmartInStantialiationAware BeanPostProcessor, // le fceau, nous connaissons ici un retour dynamiquement. GETEALLYBEAnReference (beanname, mbd, bean);}}); } // Initialisez l'instance de bean. // C'est l'initialisation du haricot et l'injection de dépendance se produit souvent ici. Cet objet Exposed regrette le retour à mesure que le haricot après l'initialisation est traité. Objet exposéObject = Bean; Essayez {// Mettez le bean et injectez chaque valeur d'attribut. Parmi eux, il peut y avoir des attributs qui dépendent des autres haricots, le bean de dépendance sera initialisé Recursively PopulateBean (Beanname, MBD, instanceWrapper); if (exposéObject! = null) {// Appel de la méthode d'initialisation, tel que initi-méthod exposéObject = initializeBean (beanname, exposéObject, MBD); }} catch (Throwable ex) {if (ex instanceof beanCreationException && beanname.equals (((beanCreationException) ex) .getBeAnName ())) {thord (beanCreationException) ex; } else {Throw new BeanCreationException (MBD.GetResourcedEcriScription (), beanname, "L'initialisation de la haricot a échoué", ex); }} if (EarlySingletOnExpose) {objet EarlySingletOnReference = GetSingleton (beanname, false); // EarlySingletOnReference n'est pas vide uniquement si une dépendance circulaire est détectée si (EarlySingletOnReference! = NULL) {if (exposéObject == bean) {// Si exposé-objet n'est pas modifié dans la méthode d'initialisation, il n'est pas amélioré exposéObject = EarlySingletonreference; } else if (! this.allowrawinjectionDesshipiteWapping && HasdependentBean (beanname)) {String [] DependentBeans = GetDependentBeans (beanname); Set <string> réelDependentBeans = new LinkedHashSet <string> (DependentBeans.Length); pour (String DependentBean: DependentBeans) {// Détection de détection if (! RemovesingLeTOnifreatedFortyPyCheckonly (DependentBean)) {réelDependentBeans.Add (DependentBean); }} // Parce que les haricots dont il dépend après la création du haricot doit avoir été créé, les cages dépendantes réelles ne sont pas vides, ce qui signifie qu'il y a une dépendance circulaire si (! ActualDependentBeans.isempty ()) {Jetez une nouvelle dépendance à " Injecté dans d'autres haricots [+ StringUtils.CollectionToComADelimitedString (réelsDependentBeans) + "] dans sa version brute dans le cadre d'une référence circulaire, mais a finalement été" + "enveloppé. Le drapeau de la «perteAreagerinit» s'est éteint, par exemple. »); }}}}} // Enregistrer le bean comme jetable. essayez {// enregistrer le bean en fonction de la portée regritantDisposableBeAnifnessary (beanname, bean, mbd); } catch (beanDefinitionValidationException ex) {Throw new BeanCreationException (mbd.getResourceDeScription (), beanname, "signature de destruction invalide", ex); } return exposéObject; }L'injection de dépendance implique en fait deux processus principaux
À partir de ce qui précède, nous pouvons voir que les méthodes qui sont particulièrement étroitement liées à l'injection de dépendance comprennent
CreateBeaninstance
Générer des objets Java contenus dans les haricots
PopulateBean.
Traitement du processus de traitement des propriétés de divers objets de haricot (c'est-à-dire le processus de traitement de la dépendance)
Jetons un coup d'œil au code source CreateBeanInstance en premier
/ ** * Créez une nouvelle instance pour le bean spécifié, en utilisant une stratégie d'instance appropriée: * Méthode d'usine, automatique du constructeur ou instance simple. * @param beanname Le nom du bean * @param mbd la définition de bean pour le bean * @param args des arguments explicites à utiliser pour l'invocation de la méthode du constructeur ou de l'usine * @return un beanwrapper pour la nouvelle instance * / beanwrapper protégée createBeanInstance (string beanname, rootBeANDefinition mbd, objet [] args) {// assurez-vous que la classification du bean est réellement résolue. // Confirmez que la classe de l'instance Bean que vous souhaitez créer peut être une classe instanciée <?> Beanclass = ResolveBeANClass (MBD, beanname); if (beanclass! = null &&! modificateur.ispublic (beanclass.getModifiers ()) &&! mbd.isnonPublicAccessallowed ()) {Throw New BeanCreationException (Mbd.getResourceDedescription (), Beanname, "Bean Class n'est pas publique, et non-Public Access pas autorisé:" + Beanclass.get.getname (); } Fournisseur <?> InstanceSupplier = mbd.getInstancesupplier (); if (instanceSupplier! = null) {return obtientfromsupplier (instanceSuppler, beanname); } // Si la méthode d'usine n'est pas vide, utilisez la stratégie de méthode d'usine pour instancier le bean if (mbd.getFactoryMethodName ()! = Null) {return instanciateUsingFactoryMethod (beanname, mbd, args); } // raccourci lors de la recréation du même bean ... booléen résolu = false; booléen autowireenessary = false; if (args == null) {synchronisé (mbd.ConstructorargumentLock) {// Une classe a plusieurs constructeurs, chaque constructeur a différents paramètres, donc avant d'appeler, vous devez verrouiller le constructeur ou la méthode d'usine correspondante selon les paramètres si (Resolved = true; AutowireeNessary = MBD.CONSTUCTORArGuments Resolved; }}} // S'il a été analysé, utilisez la méthode du constructeur analysé sans verrouiller à nouveau if (résolu) {if (autowireneceSsary) {// Le constructeur injecte automatiquement RETOUR AutowireConstructor (beanname, mbd, null, null); } else {// Constructeur utilisant le constructeur par défaut du constructeur InstantiateBean (beanname, mbd); }} // besoin de déterminer le constructeur ... // Instancier le bean à l'aide du constructeur du constructeur <?> [] Ctors = déterminceconstructorsfrombepostProcessors (harinclass, beanname); if (ctors! = null || mbd.getResolvedAutowireMode () == rootBeAnDefinition.Autowire_Constructor || MBD.HasconstructorArgumentValues () ||! ObjectUtils.isempty (args)) {return autowirestructor (Beanname, Mbd, ctors, args); } // Pas de manipulation spéciale: utilisez simplement le constructeur sans arg. // Instancier le bean à l'aide de son constructeur par défaut; } / ** * Instancier le bean donné en utilisant son constructeur par défaut. * @param beanname Le nom du bean * @param mbd la définition de bean pour le bean * @return un beanwrapper pour la nouvelle instance * / // le nom de beanname InstanciateBean le plus courant (// Instanciate le beanname final, la stratégie d'instance définitive. La stratégie d'instanciation par défaut est // cglibsubclassingInstantiationStrategy, c'est-à-dire instancier le haricot en utilisant cglib. essayez {objet beanInstance; Parent Final Beanfactory = ceci; if (System.getSecurityManager ()! = null) {beanInstance = AccessController.Dopriviled (new privilEdAction <objet> () {@Override Object Run () {return getInsTantiationStrategy (). Instantiate (mbd, beanname, parent);}}, getACCSSControlContext (mbd); } else {beanInstance = getInStantiationStrategy (). instanciate (MBD, beanname, parent); } Beanwrapper bw = new BeanwrapperImpl (beanInstance); initbeanwrapper (BW); Retour BW; } Catch (Throwable ex) {Throw New BeanCreationException (mbd.getResourcedEsseScription (), beanname, "Instanciation of Bean Faich", ex); }}CGLIB est utilisé ici pour instancier des haricots. CGLIB est une bibliothèque de classe pour les générateurs de bytecode, qui fournit une série d'API pour fournir la fonction de génération et de conversion de bytecode Java.
Dans le printemps AOP, CGLIB est également utilisé pour améliorer les bytecodes Java. Dans les conteneurs IOC, pour comprendre comment utiliser CGLIB pour générer des objets de haricots, vous devez consulter la classe SimpleInstantiationStrategy. Il s'agit de la classe par défaut utilisée par Spring pour générer des objets Bean. Il fournit deux méthodes pour instancier des objets de bean.
classe publique SimpleInStantiationStrategy implémente InstantiationStrategy {@Override Public Object Instanciate (rootBeAnDefinition BD, String Beanname, BeanFactory Owner) {// Ne pas remplacer la classe avec CGLIB si aucun sans-fondement. if (bd.getMethodoverrides (). iSEmpty ()) {// Ici, vous obtenez le constructeur ou la méthode d'usine spécifiée pour instancier le beanConstructor <?> ConstructorTouse; synchronisé (bd.constructorargumentlock) {ConstructOrTouse = (Constructor <?>) bd.resolvedConstructororFactoryMethod; if (ConstructOrTouse == null) {final class <?> Clazz = bd.getBeAnclass (); if (Clazz.isinterface ()) {Throw New BeanInstantiationException (Clazz, "la classe spécifiée est une interface"); } essayez {if (system.getSecurityManager ()! = null) {ConstructOrTouse = AccessController.Dopriviled (new privilEGEDExException <? >>> () {@Override Public Constructor <?> Run () lève exception {return Clazz.getDeclaredConstructor ((class []) null);}}); } else {ConstructOrTouse = Clazz.getDeclaredConstructor ((class []) null); } bd.resolvedConstructororFactoryMethod = ConstructOrTouse; } catch (Throwable ex) {Throw New BeanInstantiationException (Clazz, "Aucun constructeur par défaut trouvé", ex); }}} // Instancier via des beanutils. L'instanciation de ces beanutils instancie le haricot à travers le constructeur. Dans Beanutils, vous pouvez voir l'appel spécifique ctor.newinstance (args) return Beanutils.instantiateClass (ConstructOrTouse); } else {// instancier l'objet return instanciatewithMethodInjection (bd, beanname, propriétaire); }}}Gestion des dépendances entre les haricots
L'entrée au traitement de dépendance est la méthode PopulateBean mentionnée ci-dessus. Comme il y a trop d'aspects impliqués, je ne publierai pas le code ici. Une brève introduction au processus de traitement des dépendances: dans la méthode PopulateBean,
Tout d'abord, obtenez la valeur de la propriété définie dans BeanDefinition, puis démarrez le processus d'injection de dépendance.
Tout d'abord, l'injection automatique peut être traitée, byname ou byType, puis les attributs sont injectés.
Ensuite, vous devez analyser la référence au bean. Après l'analyse de la gestion de la direction, du manageSet, du ManageMap, etc., vous avez préparé des conditions pour l'injection de dépendance. C'est là que vous définissez vraiment l'objet bean sur une autre propriété Bean dont elle dépend, et les propriétés traitées sont diverses.
L'injection de dépendance se produit dans les valeurs SetProperty de BeanWrapper, mais l'achèvement spécifique est implémenté dans la sous-classe BeanWrapper BeanWrapperImpl. Il terminera l'injection de la valeur de la propriété du haricot, y compris l'injection de tableau, l'injection de classes de collecte telles que la liste et l'injection de classes de non-collection.
Après une série d'injections, le processus d'injection de dépendance de diverses propriétés de haricots est terminé.
Pendant le processus de création de haricots et d'injection de dépendance des objets, l'injection de dépendance doit être achevée récursivement sur la base des informations de la haricot.
D'après les processus de récursivité précédents, nous pouvons voir que ces récursions sont toutes portables avec GetBean.
Une récursivité consiste à trouver les haricots requis et à créer l'appel récursif aux haricots dans le système de contexte;
Une autre récursivité consiste à appeler la méthode Getbean du conteneur récursivement lors de l'injection de dépendance pour obtenir le haricot de dépendance du haricot actuel, et également déclencher la création et l'injection du haricot de dépendance.
Lors de l'injection de dépendance sur les propriétés d'un haricot, le processus d'analyse est également un processus récursif. De cette façon, selon la dépendance, la création et l'injection du haricot sont complétées par couche jusqu'à ce que la création du haricot actuel soit finalement terminée. Avec la création de ce haricot de niveau supérieur et l'achèvement de son injection de dépendance d'attribut, cela signifie que la solution d'injection de toute la chaîne de dépendance liée au haricot actuel est terminée.
Une fois la création de haricots et l'injection de dépendance terminées, une série de haricots liés par des dépendances est établi dans le conteneur IOC. Ce haricot n'est plus un simple objet Java. Une fois la relation de dépendance entre la série de haricots et les haricots, il peut être utilisé très facilement pour les applications de niveau supérieur via les méthodes d'interface pertinentes du CIO.
2. Attribut et préinstallation paresseux
Dans la méthode de rafraîchissement précédente, nous pouvons voir que FinishBeanfactoryInitialisation est appelé pour traiter les haricots configurés avec des Init paresseux.
En fait, dans cette méthode, le traitement de l'attribut Lazy-Init est encapsulé et le traitement réel est effectué dans la méthode préinstantiatesingleton du conteneur de base de par défautListableBeAnfactory. Cette méthode complète les haricots singleton préstaqués, et cette réalisation préstaquée est intelligemment déléguée au conteneur à implémenter. Si un préinstallation est requis, GetBean est utilisé ici pour déclencher l'injection de dépendance. Par rapport aux déclencheurs d'injection normale de dépendance, le temps de déclenchement et l'occasion ne sont que différents. Ici, l'injection de dépendance se produit pendant le processus de rafraîchissement du conteneur, c'est-à-dire pendant le processus d'initialisation du conteneur IOC, contrairement à l'injection de dépendance ordinaire, lorsque le conteneur demande le bean pour la première fois après l'initialisation du conteneur IOC via GetBean.
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.