مقدمة: التبعية الدائرية هي مرجع متداخل حلقة في فئات N. في حالة حدوث هذه التبعية الدائرية في التطوير اليومي باستخدام طريقة الكائن الجديد ، سيستمر البرنامج في تسميته حلقة في وقت التشغيل حتى تفيض الذاكرة وتبلغ خطأ. دعنا نتحدث عن الربيع إذا كان يحل التبعيات الدائرية.
النوع الأول: التبعية الدورية للمعلمة بنيت
سيضع حاوية الربيع كل معرف فول يتم إنشاؤه في "حمام السباحة الحالي" وسيبقى معرف الفول في هذا المسبح أثناء عملية الإنشاء. لذلك ، إذا وجدت أنك بالفعل في "تجمع الفول الحالي" أثناء عملية الإنشاء ، فسيتم إلقاؤه.
يشير استثناء BeanCurlyIncreationException إلى تبعية دائرية ؛ سيتم تطهير الفول الذي تم إنشاؤه من "حمام السباحة الفاصوليا الذي تم إنشاؤه حاليًا".
أولا نهيئة ثلاثة حبوب.
فئة عامة studenta {private studentB StudentB ؛ public void setStudentB (studentB studentB) {this.studentB = studentB ؛ } public studenta () {} public studenta (studentB studentB) {this.studentB = studentB ؛ }} طالب الطبقة العامة {private studentc studentc ؛ public void setStudentC (studentc studentc) {this.studentc = studentc ؛ } public studentB () {} public studentB (studentc studentc) {this.studentc = studentc ؛ }} طالب الطبقة العامة {Private Studenta ؛ public void setStudenta (studenta studenta) {this.studenta = studenta ؛ } public studentc () {} public studentc (studenta studenta) {this.studenta = studenta ؛ }}حسنًا ، ما سبق ثلاثة فصول أساسية للغاية. هيكل المعلمة الطالب هو الطالب. هيكل المعلمة الطالب هو طالب ، وهيكل المعلمة الطالب هو طالب ، مما يخلق حالة تبعية دائرية.
سلمنا جميعًا هذه الفاصوليا الثلاثة إلى إدارة الربيع وتأسيسها مع بنيات المعلمة
<bean id = "a"> <constructor-arg index = "0" ref = "b"> </constructor-arg> </bean> <bean id = "b"> <constructor-arg index = "0" ref = "c"> </arg> </bantructor> <bean id = c "
هنا فئة الاختبار:
اختبار الفئة العامة {public static void main (string [] args) {applicationContext context = new ClassPathxMlapplicationContext ("com/zfx/student/applicationContext.xml") ؛ //system.out.println(context.getBean("a "، studenta.class) ؛ }}رسالة الخطأ لنتيجة التنفيذ هي:
سبب: org.springframework.beans.factory.beancurrinctionCreationException:
خطأ في إنشاء الفاصوليا باسم "A": الحبة المطلوبة حاليًا في الإنشاء: هل هناك مرجع دائري لا يمكن حله؟
إذا فهمت الجملة في البداية ، فلن تفاجأ بالإبلاغ عن هذا الخطأ. حاوية الربيع أولاً تنشئ طالب سينجلتون. يعتمد الطالب على الطالب ، ثم يضع في "حمام السباحة الحالي". في هذا الوقت ، يتم إنشاء StudentB ، يعتمد StudentB على StudentC ، ثم يتم وضع B في "حمام السباحة الحالي". في هذا الوقت ، يتم إنشاء StudentC ، يعتمد StudentC على الطالب. ومع ذلك ، في هذا الوقت ، يكون الطالب بالفعل في المجموعة ، لذلك سيتم الإبلاغ عن خطأ. نظرًا لعدم تهيئة جميع الفاصوليا في حمام السباحة ، فإنها تعتمد على الأخطاء. (ستتم إزالة الحبة المهيئة من المسبح)
النوع الثاني: طريقة Setter Singleton ، الطريقة الافتراضية
إذا كنت ترغب في التحدث عن حقن Setter ، فمن الأفضل أن ننظر إلى صورة لفاصوليا في الربيع
كما هو موضح في الخطوتين الأوليين في الشكل ، يقوم Spring بإعادة إنشاء كائن الفول ثم يعين خصائص الكائن.
قم بتعديل ملف التكوين لحقنه في وضع SET:
<!-Scope = "Singleton" (افتراضي هو طريقة Singleton)-> <bean id = "a" scope = "singleton"> <property name = "studentb" ref = "b"> </prereent name = "studenta" ref = "a"> </property> </ban>
هنا فئة الاختبار:
اختبار الفئة العامة {public static void main (string [] args) {applicationContext context = new ClassPathxMlapplicationContext ("com/zfx/student/applicationContext.xml") ؛ system.out.println (context.getBean ("a" ، studenta.class)) ؛ }}نتيجة الطباعة هي:
com.zfx.student.studenta@1fbfd6
لماذا لا تقم بالإبلاغ عن خطأ باستخدام طريقة SET؟
دعونا نلقي نظرة على الصورة أعلاه. الربيع أولاً يثبت كائن الفول باستخدام بنيات. في هذا الوقت ، سيضع Spring الكائن الذي تم إنشاءه في خريطة ، ويوفر Spring طريقة للحصول على مرجع الكائن الذي تم إنشاؤه مع سمة enset. استنادًا إلى مثالنا ، عندما يقوم Spring بتأسيس Studenta و StudentB و StudentC ، فسيقوم بعد ذلك بتعيين خصائص الكائن. في هذا الوقت ، سيعتمد الطالب على الطالب وسيأخذ كائن طالب Singleton في الخريطة ، وهكذا ، لن تكون هناك مشكلة في حلقة.
فيما يلي طريقة التنفيذ في رمز مصدر الربيع. رمز المصدر التالي موجود في فئة DefaultSingleTonBeanRegistry.java في حزمة Bean's Spring
/ ** ذاكرة التخزين المؤقت لكائنات Singleton: اسم الفول -> مثيل Bean (مجموعة الخريطة التي تقوم بتخزين Cachleton instantized كائنات)*/ خريطة نهائية خاصة <سلسلة ، كائن> singletonobjects = concurrenthashmap الجديد <string ، كائن> (64) ؛ / ** ذاكرة التخزين المؤقت لمصانع Singleton: اسم الفول -> ObjectFactory (مجموعة ذاكرة التخزين المؤقت لـ Singleton Factory Bean)*/ الخريطة النهائية الخاصة <string ، ObjectFactory> singletonfactory = new hashmap <string ، ObjectFactory> (16) ؛ / ** ذاكرة التخزين المؤقت للكائنات المبكرة المبكرة: اسم الفول -> مثيل بين*/ الخريطة النهائية الخاصة <string ، Object> ilatingsingletonObjects = new hashmap <string ، Object> (16) ؛ / ** مجموعة من singletons المسجلة ، التي تحتوي على أسماء الفاصوليا في أمر التسجيل*/ المجموعة النهائية الخاصة <String> registerSingletons = New LinkedHashset <string> (64) ؛ /*** إضافة مثيل Singleton* حل مشكلة المراجع الدائرية* إضافة مصنع Singleton المعطى لبناء Singleton المحدد* إذا لزم الأمر. * <p> ليتم استدعاؤها لتسجيل المفردات المتشاغرة ، على سبيل المثال ، لتكون قادرًا على * حل المراجع الدائرية. * param beanname اسم الفول * param singletonfactory المصنع لكائن singleton */ void المحمي addsingletonfactory (سلسلة beanname ، ObjectFactory singletonfactory) {Assert.notnull (singletonfactory ، "singleton face يجب ألا تكون فارغة") ؛ synchronized (this.singletonobjects) {if (! this.singletonobjects.containskey (beanname)) {this.singletonfactories.put (beanname ، singletonfactory) ؛ this.earlysingletonobjects.remove (beanname) ؛ this.registeredSingletons.Add (Beanname) ؛ }}النوع الثالث: النموذج الأولي ، النموذج الأولي
تعديل ملف التكوين إلى:
<bean id = "a" <span style = "color:#ff0000 ؛"> scope = "prototype" </span >> <property name = "studentB" ref = "b"> </property> </bean> <bean id = "b" <span style = "color:#ff0000 ؛ id = "c" <span style = "color:#ff0000 ؛
Scope = "النموذج الأولي" يعني أنه يتم إنشاء كائن مثيل في كل مرة تطلب فيها. الفرق بين الاثنين هو: الفاصوليا الحكومية تستخدم نطاق النموذج الأولي ، في حين أن عديمة الجنسية تستخدم عمومًا نطاق Singleton Singleton.
حالات الاختبار:
اختبار الفئة العامة {public static void main (string [] args) {applicationContext context = new ClassPathxMlapplicationContext ("com/zfx/student/applicationContext.xml") ؛ <strong> // في هذا الوقت ، يجب أن تحصل على مثيل لإدارة الربيع ، لأن الآن Scope = "النموذج الأولي" لن يقوم بتثبيت الكائن إلا عند طلب الحصول على </strong> system.out.println (context.getBean ("a" ، studenta.class)) ؛ }} نتيجة الطباعة:
بسبب: org.springframework.beans.factory.beancurrinctionCreationException: خطأ في إنشاء الفاصوليا مع الاسم "A": الفول المطلوب حاليًا في الإنشاء: هل هناك مرجع دائري لا يمكن حله؟
لماذا نموذج النموذج الأولي خاطئ؟
بالنسبة إلى "النموذج الأولي" ، لا يمكن لحاوية الزنبرك إكمال حقن التبعية لأن حاوية الزنبرك لا تخدع الفاصوليا في الفاصوليا "النموذج الأولي" ، لذلك لا يمكن تعرض الفاصوليا المخلوقة مسبقًا.
ما سبق هو كل محتوى هذه المقالة. آمل أن يكون ذلك مفيدًا لتعلم الجميع وآمل أن يدعم الجميع wulin.com أكثر.