تقدم هذه المقالة مناقشة موجزة حول مبدأ حقن التبعية لحاويات الربيع IOC ، ويشاركها معك ، على النحو التالي:
تتمثل المهمة الرئيسية في تهيئة حاوية IOC في إنشاء خريطة بيانات Beandefinition في حاوية IOC. لم أر حاوية IOC تضخ علاقة اعتماد الفول.
على افتراض أن حاوية IOC الحالية قامت بتحميل معلومات الفاصوليا المعرفة من قبل المستخدم ، فإن حقن التبعية يحدث بشكل أساسي على مرحلتين.
في ظل الظروف العادية ، يتم تشغيله عندما يسأل المستخدم حبة من حاوية IOC لأول مرة.
ومع ذلك ، يمكننا التحكم في السمة البطيئة في معلومات الفاصوليا للسماح للحاوية بالتحديد مسبقًا ، أي أن عملية حقن التبعية لبعض الفاصوليا قد اكتملت أثناء عملية التهيئة.
1. حقن التبعية الناتج عن getBean
في واجهة حاوية IOC الأساسية Beanfactory ، هناك تعريف واجهة لـ GetBean. تنفيذ هذه الواجهة هو المكان الذي يحدث فيه حقن تبعية الزناد. من أجل زيادة فهم عملية حقن التبعية ، نبدأ مع الفئة الأساسية الملخصية لـ DefaultListableBeanfactory لإلقاء نظرة على تنفيذ GetBean
// هنا هو تنفيذ واجهة BeanFactory ، مثل طريقة واجهة getBean // يتم تنفيذ طرق واجهة getBean هذه في النهاية عن طريق استدعاء DogetBeanToverride Public Object GetBean (اسم السلسلة) يلقي beansexception {return doggetbean (name ، null ، null ، false) ؛ } Override Public <T> t getBean (اسم السلسلة ، الفئة <T> مطلوبة) يلقي beansexception {return dogetBean (name ، requiredtype ، null ، false) ؛ } Override public object getBean (اسم السلسلة ، الكائن ... args) يلقي beansexception {return dogetBean (الاسم ، null ، args ، false) ؛ } public <t> t getBean (اسم السلسلة ، الفئة <T> مطلوبة ، كائن ... args) يلقي beansexception {return dogetBean (name ، requiredType ، args ، false) ؛ } // هذا هو المكان الذي يتم فيه الحصول على الفول فعليًا ، أي حيث يتم تشغيل حقن التبعية suppressWarnings ("غير محدد") محمية <T> t doggetbean (اسم السلسلة النهائية ، الفئة النهائية <T> المطلوبة ، الكائن النهائي [] args ، typecheckonly) كائن الفول // تحقق بفارغ الصبر من ذاكرة التخزين المؤقت Singleton لـ Singletons المسجلة يدويًا. // تحقق بفارغ الصبر من ذاكرة التخزين المؤقت Singleton لـ Singletons المسجلة يدويًا. . لا تنشئ مرارًا وتكرارًا كائن مشترك = getSingleton (Beanname) ؛ if (sharedInstance! = null && args == null) {if (logger.isdebugenabled ()) {if (issingletonCurrincurlyIncreation (beanname)) {logger.debug ("عودة مثيل Singleton Bean ' + Beanname +" } else {logger.debug ("مثيل عودة مخبأة من Singleton Bean '" + Beanname + "'") ؛ }} // يكمل getObjectForBeaninStance هنا المعالجة ذات الصلة لـ Factorybean للحصول على المعالجة ذات الصلة للمصنع للحصول على نتائج إنتاج المصنع. تم ذكر الفرق بين Beanfactory و Factorybean في وقت سابق. سيتم تحليل هذه العملية بالتفصيل لاحقًا. = getObjectForBeanInstance (مشترك ، الاسم ، beanname ، null) ؛ } آخر {// تفشل إذا كنا بالفعل قم بإنشاء مثيل الفول هذا: // نحن افتراض ضمن مرجع دائري. if (isProtypeCurlyIncreation (beanname)) {رمي جديد beancurerlyincreationException (beanname) ؛ } // // تحقق مما إذا كان هناك beandefinition في حاوية IOC موجودة. إذا لم يكن موجودًا في المصنع الحالي ، فاتبع سلسلة Beanfactory الأصل وابحث عن Beanfactory ParentBeanFactory = getParentBeanfactory () ؛ if (parentBeanFactory! = null &&! containsbeandefinition (beanname)) {// غير موجود -> تحقق من الأصل. سلسلة nametolookup = OriginalBeanName (الاسم) ؛ if (args! = null) {// devation to parent مع args صريحة. إرجاع (t) parentbeanfactory.getBean (nametolookup ، args) ؛ } آخر {// لا args -> تفويض إلى طريقة getBean القياسية. إرجاع ParentBeanfactory.getBean (nametolookup ، مطلوبة stype) ؛ }} if (! typecheckonly) {markBeanAscreated (beanname) ؛ } جرب {// الحصول على beandefinition النهائي rootbeandefinition mbd = getmergedlocalbeandefinition (beanname) ؛ checkmergedbeandefinition (MBD ، Beanname ، args) ؛ // ضمان تهيئة الفاصوليا التي يعتمد عليها الفول الحالي. // الحصول على جميع الفاصوليا بشكل متكرر الذي يعتمد عليه الفاصوليا الحالية على (إن وجد) سلسلة [] deparson = mbd.getDependson () ؛ if (conterentson! = null) {for (string dep: deparson) {if (isDender (beanname ، dep)) {رمي جديد beancreationException (mbd.getResourcedescription () ، beanname ، "تعتمد الدائرية على العلاقة بين" + beanname + "" و " + dep +" "") ؛ } registerDependentBean (dep ، beanname) ؛ getBean (dep) ؛ }} // إنشاء مثيل Singleton Bean من خلال استدعاء طريقة CreateBean if (mbd.issingleton ()) {sharedInstance = getSingleton (beanname ، ObjectFactory new Objectsory <bomf> () {Override public object getObject () reflesexception {try {return createbean (beanname ، mbd ، مثيل من ذاكرة التخزين المؤقت Singleton: ربما تم وضعها في عملية الإبداع. Bean = getObjectForBeanInstance (sharedInstance ، name ، Beanname ، MBD) ؛ } // هذا هو المكان المناسب لإنشاء حبة نموذجية أخرى إذا (mbd.isprototype ()) {// إنه نموذج أولي -> إنشاء مثيل جديد. Object OrityOnstance = null ؛ جرب {قبل النموذج النموذجي (beanname) ؛ النموذج الأولي intractance = createBean (beanname ، mbd ، args) ؛ } أخيرًا {efterPrototypecreation (beanname) ؛ } bean = getObjectForBeanInstance (النموذج الأولي ، الاسم ، beanname ، mbd) ؛ } آخر {String scopename = mbd.getScope () ؛ نطاق النطاق النهائي = this.scopes.get (scopename) ؛ if (Scope == NULL) {رمي جديد alficalStateException ("لا يوجد نطاق مسجل لاسم النطاق '" + scopename + "' ') ؛ } جرب {Object scopedInstance = scope.get (beanname ، ObjectFactory <object> () {Override الكائن العام getObject () يلقي beansexception {قبل protototypecreation (beanname) ؛ try {return createbean (beanname ، mbd ، args) ؛} أخيرًا {afterprototypecreation (}}} ؛ Bean = getObjectForBeanInstance (ScopedInstance ، name ، Beanname ، MBD) ؛ } catch (alfortalstateException ex) {رمي beancreationException (beanname ، "النطاق" " + scopename +" "غير نشط للخيط الحالي ؛ فكر" + "تحديد وكيل محدد لهذا الفول إذا كنت تنوي الإشارة إليه من المفرد" ، السابقين) ؛ }}} catch (beansexception ex) {cleanupAfterBeanCreationFailure (beanname) ؛ رمي السابقين }} // تحقق من أن النوع المطلوب يطابق نوع مثيل الفول الفعلي. // يتم إجراء فحص النوع على الفول الذي تم إنشاؤه هنا. إذا لم تكن هناك مشكلة ، يتم إرجاع الفول الذي تم إنشاؤه حديثًا. هذه الفول هي بالفعل حبة تحتوي على التبعية إذا (requiretType! = null && bean! = null &&! requiredType.IsAssignableFrom (bean.getclass ())) {try {return gettypeconverter (). } catch (typemismatchException ex) {if (logger.isdebugenabled ()) {logger.debug ("فشل في تحويل Bean '" + name + "' إلى النوع المطلوب '" + classUtilSteQualifiedName (requiredType) + "' '، ex) ؛ } رمي beannotofrequiredtypeexception (الاسم ، المطلوبة ، bean.getclass ()) ؛ }} return (t) Bean ؛ }يتم تشغيل حقن التبعية هنا. يحدث حقن التبعية عند إنشاء بيانات الفاصولياء في الحاوية. على الرغم من أنه يمكننا وصف حاوية IOC بأبسط طريقة ، أي تعامل معها على أنها hashmap ، إلا أنه يمكننا القول فقط أن هذا hashmap هو بنية بيانات أساسية للحاوية ، وليس حاوية IOC بأكملها.
سيتم شرح عملية حقن التبعية هذه بالتفصيل أدناه. يوضح الشكل 1.1 العملية العامة لحقن التبعية.
الشكل 1.1 عملية حقن التبعية
GetBean هي نقطة انطلاق حقن التبعية. بعد ذلك ، سيتم استدعاء CreateBean in AbstractAutOwIreCableBeanFactory لإنتاج الفاصوليا المطلوبة ، ويتم معالجة تهيئة الفاصوليا أيضًا ، مثل تنفيذ تعريف سمة الأساليب في التعريف الفاصولي ، ما بعد المعالجة ، وما إلى ذلك.
Override محمي كائن CreateBean (سلسلة Beanname ، RootBeanDefinition MBD ، Object [] args) يلقي beancreationException {if (logger.isdebugenabled ()) {logger.debug ("إنشاء مثيل Bean '" + Beanname + "'") ؛ } ROOTBEANDEFINITION MBDTOUSE = MBD ؛ // تأكد من حل فئة الفول بالفعل في هذه المرحلة ، و // استنساخ تعريف الفاصوليا في حالة وجود فئة تم حلها ديناميكيًا// لا يمكن تخزينها في تعريف الفول المدمج المشترك. // هنا نحدد ما إذا كان يمكن إنشاء إنشاء الفول الواجب إنشاء ، ما إذا كان يمكن تحميل هذه الفئة من خلال فئة Loader الفئة <؟> ResolvedClass = ResolveBeanClass (MBD ، Beanname) ؛ if (solvedClass! = null &&! mbd.hasbeanclass () && mbd.getBeanClassName ()! = null) {mbdtouse = new RootBeanDefinition (mbd) ؛ mbdtouse.setBeanClass (ResolvedClass) ؛ } // تحضير طريقة تجاوز طريقة. حاول {mbdtouse.preparemethodoverrides () ؛ } catch (BeanDefinitionValidationException ex) {رمي جديد BeanDefinitionStoreException (mbdtouse.getResourcedescription () ، beanname ، "فشل التحقق من تجاوزات الطريقة" ، على سبيل المثال) ؛ } جرب {// أعط BeanPostProcessors فرصة لإعادة وكيل بدلاً من مثيل الفاصوليا الهدف. // إذا كانت الفاصوليا قد قامت بتكوين معالج ما بعد المعالج ، فإن كائن الوكيل الذي تم إرجاعه = solveBeforeInstantiation (Beanname ، MbdTouse) ؛ if (Bean! = null) {return Bean ؛ }} catch (throwable ex) {رمي beancreationException (mbdtouse.getResourCedescription () ، beanname ، "BeanPostProcessor قبل أن فشلت إنشاء الفول" ، على سبيل المثال) ؛ } جرب {object beaninstance = docreateBean (beanname ، mbdtouse ، args) ؛ if (logger.isdebugenabled ()) {logger.debug ("الانتهاء من إنشاء مثيل bean '" + beanname + "' ') ؛ } إرجاع Beaninstance ؛ } catch (beancreationException ex) {// استثناء تم اكتشافه مسبقًا مع سياق إنشاء الفول المناسب بالفعل ... رمي EX ؛ } catch (ضمنيًا appearedsingletonexception ex) {// a alfarkalstateException ليتم توصيله إلى defaultsingletonbeanregistry ... رمي السابقين ؛ } catch (throwable ex) {refl new BeancreationException (mbdtouse.getResourcedescription () ، beanname ، "استثناء غير متوقع أثناء إنشاء الفول" ، ex) ؛ }} // بجانب doceate لمعرفة كيفية إنشاء الفاصوليا كائن محمي docreateBean (السلسلة النهائية beanname ، rootbeandefinition mbd ، الكائن النهائي [] args) {// instantiate the bean. // تستخدم لعقد كائن Bean Beanwrapper الذي تم إنشاؤه conferwrapper = null ؛ // إذا كان Singleton ، فقم أولاً بمسح الفول الذي يحمل نفس الاسم في ذاكرة التخزين المؤقت إذا (mbd.issingleton ()) {estanceWrapper = this.factorybeanstancecache.remove (beanname) ؛ } // هذا هو المكان المناسب لإنشاء الفول ، ويتم ذلك عن طريق CreateBeanInstance if (extultwRapper == NULL) {// إنشاء مثيل جديد يعتمد على الفول المحدد باستخدام الاستراتيجية المقابلة ، مثل: طريقة المصنع ، الحقن التلقائي للبناء ، almate almatewrapper = createBeanstance (Beanname ، mbd ، args) ؛ } الكائن النهائي Bean = (eCHATIONWRAPPER! = null؟ aluteWrapper.getWrappedInStance (): null) ؛ الفئة <؟> beantype = (almatewrapper! = null؟ aluteWrapper.getWrappedClass (): null) ؛ // السماح لما بعد المعالجات بتعديل تعريف الفول المدمج. Synchronized (MBD.PostProcessinglock) {if (! mbd.postprocound) {ardmergedBeanDefinitionPostProcsors (MBD ، Beantype ، beanname) ؛ mbd.postprocorted = true ؛ }} // ذاكرة التخزين المؤقت بفارغ الصبر لتكون قادرة على حل المراجع الدائرية // حتى عندما يتم تشغيلها بواسطة واجهات دورة الحياة مثل beanfactoryaware. // هل من الضروري الكشف مسبقًا: Singleton والسماح للتبعيات الدورية والفاصوليا الحالية يتم إنشاؤها ، واكتشاف التبعيات الدورية المبكرة ايترسينجليتونيكس = (mbd.issingleton () && this.allowcircularerences && issingletoncurtion (beanname)) ؛ if (اوكرنغليتونيكبوس) {if (logger.isdebugenabled ()) {logger.debug ("بتخزين واحد بفارغ الصبر" + beanname + "'للسماح بحل المراجع الدائرية المحتملة") ؛ } // لتجنب تبعيات الدورة المتأخرة ، يمكن إضافة ObjectFactory الذي ينشئ مثيلًا إلى المصنع قبل اكتمال تهيئة الفول. AddSingletonFactory (BeanName ، ObjectFactory <bomf> () {Override الكائن العام getObject () يلقي beansexception {// الاعتماد على الإشارات إلى الفاصوليا مرة أخرى ، بشكل رئيسي باستخدام smartinstantialiationaware beanpostprocessor ، // AOP التي نعرفها هنا نصيحة weavives إلى الفاصوليا. GeteArlyBeanReference (Beanname ، MBD ، Bean) ؛ } // تهيئة مثيل الفول. // هذا هو تهيئة الفول ، وغالبًا ما يحدث حقن التبعية هنا. هذا يأسف المعرضة لرجوع إلى عودة الفول بعد معالجة التهيئة. الكائن المعرض exposedObject = Bean ؛ حاول {// ضع الفول وحقن كل قيمة سمة. من بينها ، قد تكون هناك سمات تعتمد على الفاصوليا الأخرى ، وسيتم تهيئة حبوب التبعية بشكل متكرر (Beanname ، MBD ، extalwrapper) ؛ if (exposedObject! = null) {// استدعاء طريقة التهيئة ، مثل init-method eintoBected = initializeBean (beanname ، exposedObject ، MBD) ؛ }} catch (throwable ex) {if (ex extuteof beancreationException && beanname.equals (((beancreationException) ex) .getBeanName ())) } آخر {رمي جديد beancreationException (mbd.getResourCedescription () ، beanname ، "تهيئة الفول فشل" ، ex) ؛ }} if (ariOmSingLetOnexposure) {Object ariatsingleTonReference = getSingleton (beanname ، false) ؛ // اوكرنغليتونريفران هو غير فارغ فقط إذا تم الكشف عن تبعية دائرية إذا (اوكرنغليتونيرايفور! = null) {if (oundosedObject == Bean) {// إذا لم يتم تغيير الكائنات المعرضة في طريقة التهيئة ، فهو غير معرض غير معرض = اوكرنغليتون. } آخر إذا (! this.allowRawInjectionDespItEwRapping && hasdependentbean (beanname)) {string [] ceneralbeans = getDependentBeans (beanname) ؛ SET <Tring> agauldependentBeans = New LinkedHashSet <String> (ArendenceBeans.Length) ؛ لـ (string arendentbean: ArendentBeans) {// الكشف عن الاعتماد إذا (! removesingletonifcreatevespecheckonly (arendenceBean)) {stuterpendentBeans.add (AdendentBean) ؛ }} // لأن الفاصوليا التي يعتمد عليها بعد إنشاء الفول يجب أن تكون قد تم إنشاءها ، فإن bevendencependens غير فارغة ، مما يعني أن الفاصوليا التي يعتمد عليها بعد إنشاء الفول الحالي لم يتم إنشاء ، أي ، هناك اعتماد دائري إذا كان هناك (! تم حقنها في الفاصوليا الأخرى [" تم إيقاف علم "pleasegerinit" ، على سبيل المثال. ") ؛ }}}}} // تسجيل الفول على أنه يمكن التخلص منه. حاول {// register bean استنادًا إلى Scope RecordDisposableBeanifnecessary (Beanname ، Bean ، MBD) ؛ } catch (BeanDefinitionValidationException ex) {رمي جديد beancreationException (mbd.getResourcedescription () ، beanname ، "توقيع الدمار غير الصالح" ، EX) ؛ } إرجاع مكشوفة ؛ }يتضمن حقن التبعية في الواقع عمليتين رئيسيتين
مما سبق يمكننا أن نرى أن الطرق التي ترتبط ارتباطًا وثيقًا بشكل خاص بحقن التبعية تشمل
CreateBeaninstance
توليد كائنات java الموجودة في الفاصوليا
PopulateBean.
معالجة عملية معالجة خصائص كائنات الفاصوليا المختلفة (أي عملية معالجة التبعية)
دعونا نلقي نظرة على رمز مصدر CreateBeaninstance أولاً
/** * قم بإنشاء مثيل جديد للفول المحدد ، باستخدام استراتيجية مثيل مناسبة: * طريقة المصنع أو مُنشئ تلقائي أو مثيل بسيط. * param beanname اسم الفول * param mbd تعريف الفاصوليا لـ Bean * @param args الوسيطات الصريحة لاستخدامه في Invocation أو طريقة المصنع * @Return a beanwrapper للمثيل الجديد */ pealwrapper محمي BeanWrapper createBeanStance (سلسلة Beanname ، RootBeandipinition mbd ، Object) // تأكد من أن فئة مثيل الفول الذي تريد إنشائه يمكن أن يتم إنشاء فئة <؟> beanclass = solveBeanClass (MBD ، Beanname) ؛ if (beanclass! = null &&! modifier.ispublic (beanclass.getModifiers ()) &&! mbd.isnonpublicAccessesslowed ()) } المورد <؟> instancesupplier = mbd.getInstancesUpplier () ؛ if (extanceupplier! = null) {return getfromsupplier (extanceupplier ، beanname) ؛ } // إذا لم تكن طريقة المصنع فارغة ، فاستخدم استراتيجية طريقة المصنع لإنشاء إنشاء الفاصوليا إذا (mbd.getFactoryMethodName ()! = null) {return instantiateiateingfactorymethod (beanname ، mbd ، args) ؛ } // اختصار عند إعادة إنشاء نفس الفول ... حل منطقي = خطأ ؛ Boolean autowirenecatary = false ؛ إذا كان (args == null) {synchronized (mbd.constructorArgumentlock) {// ، يحتوي الفئة على مُنشئات متعددة ، كل مُنشئ له معلمات مختلفة ، لذلك قبل الاتصال ، تحتاج إلى قفل المُنشئ أو طريقة المصنع المقابلة = trate ؛ autowirenecessary = mbd.constructorArgumentsResRive ؛ }}} // إذا تم تحليله ، فاستخدم طريقة المنشئ المحسّنة دون قفل مرة أخرى إذا (تم حلها) {if (autowirenecessary) {// constructor تلقائيًا إرجاع autowireconstructor (beanname ، mbd ، null ، null ، null) ؛ } آخر {// مُنشئ باستخدام المُنشئ الافتراضي إلى مُنشئ instantiateBean (Beanname ، MBD) ؛ }} // بحاجة إلى تحديد المُنشئ ... // إنشاء الفول باستخدام مُنشئ المنشئ <؟> [] ctors = deturneconstructorsfrompeanpostprocessors (beanclass ، beanname) ؛ if (ctors! = null || mbd.getResolvedautowIreMode () == rootbeandefinition.autowire_constructor || mbd.hasconstructorgumentvalues () ||! objectUtils.isempty (args)) } // لا معالجة خاصة: ما عليك سوى استخدام مُنشئ no-arg. // Instantiate الفول باستخدام مُنشئها الافتراضي ؛ } /*** مثبت على الفول المعطى باستخدام مُنشئها الافتراضي. * param beanname اسم الفول * param mbd تعريف الفاصوليا للفول * regurn beanwrapper للمثال الجديد *///الأكثر شيوعًا على instantiateBean beanwrapper instantiateBean (سلسلة beanname النهائية ، interbeandefinition mbd) استراتيجية التأسيس الافتراضية هي // cglibsubclassingInstantiationStrategy ، أي إنشاء الفول باستخدام cglib. جرب {كائن بينينستانس ؛ الوالد الفاصوليا النهائي = هذا ؛ if (system.getSecurityManager ()! = null) {beaninstance = accessController.doprivileged (new terilegedAction <Object> () { @ @ @oundride run () {return getInStantiationStrategy (). } آخر {beaninstance = getInstantiationStrategy (). instantiate (MBD ، beanname ، parent) ؛ } beanwrapper bw = new BeanWrapperImpl (beaninstance) ؛ initBeanWrapper (BW) ؛ إرجاع BW ؛ } catch (throwable ex) {رمي beancreationException جديد (mbd.getResourCedescription () ، beanname ، "instantiation of bean fans" ، ex) ؛ }}يتم استخدام CGLIB هنا لتثبيت الفاصوليا. CGLIB هي مكتبة فئة لمولدات Bytecode ، والتي توفر سلسلة من واجهات برمجة التطبيقات لتوفير وظيفة توليد وتحويل Java Bytecode.
في الربيع AOP ، يتم استخدام CGLIB أيضًا لتعزيز Java Bytecode. في حاويات IOC ، لفهم كيفية استخدام CGLIB لإنشاء كائنات الفول ، تحتاج إلى النظر إلى فئة SimpleinstantiationStrategy. إنها الفئة الافتراضية التي تستخدمها الربيع لإنشاء كائنات الفول. يوفر طريقتين لتثبيت كائنات الفاصوليا.
الطبقة العامة SimpleInstantiationStrategy تنفذ instantiationStrategy {Override كائن عام instantiate (RootBeanDefinition BD ، سلسلة Beanname ، مالك Beanfactory) {// لا تتجاوز الفصل مع cglib إذا لم يتجاوز. if (bd.getMethodoverRides (). isempty ()) {// هنا ستحصل على مُنشئ أو طريقة محددة لإنشاء إنشاء BeanConstructor <؟> ؛ متزامن (bd.constructorArgumancelock) {constructortouse = (مُنشئ <؟ if (constructortouse == null) {final class <؟> clazz = bd.getBeanClass () ؛ if (clazz.isinterface ()) {رمي جديد BeanInstantiationException (clazz ، "الفئة المحددة هي واجهة") ؛ } جرب {if (system.getSecurityManager ()! = null) {constructOrose = AccessController.doprivileged (New TerilegedExceptionAction <constructor <؟ >> () {class []) } else {constructortouse = clazz.getDeclaredConstructor ((class []) null) ؛ } bd.ResolvedConstructorOrfactoryMethod = constructortouse ؛ } catch (throwable ex) {رمي جديد beaninstantiationException (clazz ، "لم يتم العثور على مُنشئ افتراضي" ، ex) ؛ }}} // instantiate من خلال beanutils. تثبيت هذا الفاصوليا على إنشاء الفول من خلال المُنشئ. في BeanUtils ، يمكنك رؤية المكالمة المحددة ctor.newinstance (args) إرجاع beanutils.instantiateclass (Constructortouse) ؛ } آخر {// instantiate الكائن إرجاع instantiAtewithMethodInjection (bd ، beanname ، المالك) ؛ }}}التعامل مع التبعيات بين الفاصوليا
الإدخال إلى معالجة التبعية هو طريقة PopulateBean المذكورة أعلاه. نظرًا لوجود العديد من الجوانب ، لن نشر الكود هنا. مقدمة موجزة لعملية معالجة التبعية: في طريقة populateBean ،
أولاً ، احصل على قيمة الممتلكات في BeanDefinition ، ثم ابدأ عملية حقن التبعية.
أولاً ، يمكن معالجة حقن الأوتار أو الاسم البياني أو بايت ، ثم يتم حقن السمات.
ثم تحتاج إلى تحليل مرجع الفول. بعد تحليل المدير ، MAGINGEST ، MANAGEMAP ، وما إلى ذلك ، لديك ظروف تحضير لحقن التبعية. هذا هو المكان الذي تقوم فيه بتعيين كائن الفول حقًا على خاصية فول أخرى تعتمد عليها ، والخصائص التي تمت معالجتها مختلفة.
يحدث حقن التبعية في القيم المحددة لـ BeanWrapper ، ولكن يتم تنفيذ الإكمال المحدد في الفئة الفرعية BeanWrapper. وسوف يكمل حقن قيمة الممتلكات للفول ، بما في ذلك حقن الصفيف ، وحقن فئات التجميع مثل القائمة ، وحقن فئات عدم التجميع.
بعد سلسلة من الحقن ، يتم الانتهاء من عملية حقن التبعية لمختلف خصائص الفول.
أثناء عملية إنشاء الفاصوليا وحقن التبعية للكائنات ، يجب إكمال حقن التبعية بشكل متكرر بناءً على المعلومات في التعريف الفاصولي.
من عمليات التكرار السابقة ، يمكننا أن نرى أن هذه الأكرات محمولة مع GetBean.
تتمثل التكرار في العثور على الفاصوليا المطلوبة وإنشاء مكالمة متكررة إلى الفاصوليا في نظام السياق ؛
هناك عودة أخرى تتمثل في استدعاء طريقة getBean للحاوية بشكل متكرر أثناء حقن التبعية للحصول على حبة التبعية الحالية ، وكذلك تؤدي إلى إنشاء وحقبة التبعية.
عند إجراء حقن التبعية على خصائص الفول ، تكون عملية التحليل أيضًا عملية متكررة. وبهذه الطريقة ، وفقًا للاعتماد ، يتم إكمال إنشاء وحقن الفاصوليا بالطبقة حسب الطبقة حتى يتم الانتهاء من إنشاء الفاصوليا الحالية. مع إنشاء هذه الفول من المستوى الأعلى واستكمال حقن التبعية السمة ، فإن ذلك يعني أن محلول الحقن لسلسلة التبعية بأكملها تتعلق بالفاصوليا الحالية.
بعد الانتهاء من إنشاء الفاصوليا وحقن التبعية ، يتم إنشاء سلسلة من الفاصوليا المرتبطة بالتبعيات في حاوية IOC. لم يعد هذا الفول كائن جافا بسيط. بعد إنشاء علاقة التبعية بين سلسلة Bean و Beans ، يمكن استخدامها بشكل مريح للغاية للتطبيقات ذات المستوى العلوي من خلال طرق الواجهة ذات الصلة لـ IOC.
2. السمة الكسول في الوصلات وسبق الثقافة
في طريقة التحديث السابقة ، يمكننا أن نرى أن FinishBeanFactoryInitialization يتم استدعاؤه لمعالجة الفاصوليا التي تم تكوينها باستخدام Lazy-Init.
في الواقع ، في هذه الطريقة ، يتم تغليف معالجة السمة الكسولة الوصفية ، ويتم المعالجة الفعلية في طريقة preinstantiatsingleton للحاوية الأساسية لـ DefaultListableBeanfactory. تكمل هذه الطريقة حبوب المفرد المتوازنة مسبقًا ، ويتم تفويض هذا الانتهاء المتمثل مسبقًا بذكاء إلى الحاوية لتنفيذها. إذا كان مطلوبًا مسبقًا مطلوبًا ، فسيتم استخدام GetBean هنا لإحداث حقن التبعية. بالمقارنة مع محفزات حقن التبعية الطبيعية ، فإن الوقت المنقول والمناسبة مختلفان فقط. هنا ، يحدث حقن التبعية أثناء عملية تحديث الحاوية ، أي أثناء عملية تهيئة الحاوية IOC ، على عكس حقن التبعية العادية ، عندما تطلب الحاوية الفول لأول مرة بعد تهيئة الحاوية IOC من خلال GetBean.
ما سبق هو كل محتوى هذه المقالة. آمل أن يكون ذلك مفيدًا لتعلم الجميع وآمل أن يدعم الجميع wulin.com أكثر.