บทนำ: การพึ่งพาแบบวงกลมเป็นข้อมูลอ้างอิงที่ซ้อนกันในชั้น N หากการพึ่งพาแบบวงกลมนี้เกิดขึ้นในการพัฒนารายวันโดยใช้วิธีวัตถุใหม่โปรแกรมจะเรียกมันว่าลูปที่รันไทม์จนกว่าหน่วยความจำล้นและรายงานข้อผิดพลาด มาพูดคุยเกี่ยวกับฤดูใบไม้ผลิถ้ามันแก้ปัญหาการพึ่งพาเป็นวงกลม
ประเภทแรก: พารามิเตอร์ตัวสร้างการพึ่งพาวงจร
คอนเทนเนอร์สปริงจะวางตัวระบุถั่วแต่ละตัวที่ถูกสร้างขึ้นใน "พูลถั่วปัจจุบัน" และตัวระบุถั่วจะยังคงอยู่ในสระนี้ในระหว่างกระบวนการสร้าง ดังนั้นหากคุณพบว่าคุณอยู่ใน "พูลถั่วปัจจุบัน" ในระหว่างกระบวนการสร้างมันจะถูกโยนทิ้ง
ข้อยกเว้นของ beancurrentlyincreationException บ่งชี้ว่าการพึ่งพาเป็นวงกลม; ถั่วที่สร้างขึ้นจะถูกล้างออกจาก "สระถั่วที่สร้างขึ้นในปัจจุบัน"
ก่อนอื่นเราเริ่มต้นถั่วสามตัว
นักศึกษาชั้นเรียนสาธารณะ {Private StudentB studentB; โมฆะสาธารณะ setStudentB (StudentB studentB) {this.studentB = studentB; } Public Studenta () {} Public Studenta (StudentB studentB) {this.studentB = StudentB; - นักศึกษาชั้นเรียนสาธารณะ {Private Studentc Studentc; โมฆะสาธารณะ setStudentC (StudentC studentc) {this.studentC = studentc; } Public StudentB () {} Public StudentB (StudentC StudentC) {this.studentC = StudentC; - นักศึกษาชั้นเรียนสาธารณะ {นักศึกษาเอกชนนักศึกษา; โมฆะสาธารณะ setstudenta (นักศึกษา studenta) {this.studenta = studenta; } Public Studentc () {} Public Studentc (Studenta Studenta) {this.studenta = studenta; -ตกลงข้างต้นเป็นสามคลาสพื้นฐานมาก โครงสร้างพารามิเตอร์ของนักเรียนคือ StudentB โครงสร้างพารามิเตอร์ของ StudentB คือ StudentC และโครงสร้างพารามิเตอร์ของ StudentC คือ Studenta ซึ่งสร้างสถานการณ์การพึ่งพาเป็นวงกลม
เราทุกคนมอบถั่วทั้งสามนี้ให้กับการจัดการฤดูใบไม้ผลิและสร้างอินสแตนซ์ด้วยการสร้างพารามิเตอร์
<bean id = "a"> <constructor-arg index = "0" ref = "b"> </constructor-arg> </ebean> <bean id = "b"> <constructor-arg index = "0" ref = "c"> </ebean>
นี่คือคลาสทดสอบ:
การทดสอบคลาสสาธารณะ {โมฆะคงที่สาธารณะหลัก (สตริง [] args) {applicationcontext context = ใหม่ classPathxMlApplicationContext ("com/zfx/applicationcontext.xml"); //system.out.println(context.getBean("a ", Studenta.class)); -ข้อความแสดงข้อผิดพลาดของผลการดำเนินการคือ:
เกิดจาก: org.springframework.beans.factory.beancurrentlyincreationexception:
ข้อผิดพลาดในการสร้างถั่วด้วยชื่อ 'A': การร้องขอถั่วกำลังอยู่ในการสร้าง: มีการอ้างอิงแบบวงกลมที่ไม่สามารถแก้ไขได้หรือไม่?
หากคุณเข้าใจประโยคในตอนแรกคุณไม่ควรแปลกใจที่จะรายงานข้อผิดพลาดนี้ สปริงคอนเทนเนอร์แรกสร้างนักศึกษาซิงเกิลตัน นักศึกษาขึ้นอยู่กับ studentb จากนั้นวางไว้ใน "สระว่ายน้ำถั่วปัจจุบัน" ในเวลานี้ StudentB ถูกสร้างขึ้น studentb ขึ้นอยู่กับนักเรียนและจากนั้น b จะถูกวางไว้ใน "พูลถั่วปัจจุบัน" ในเวลานี้นักเรียนจะถูกสร้างขึ้นนักเรียนจะขึ้นอยู่กับนักศึกษา อย่างไรก็ตามในเวลานี้นักเรียนอยู่ในกลุ่มแล้วดังนั้นจะมีการรายงานข้อผิดพลาด เนื่องจากถั่วทั้งหมดในสระยังไม่ได้เริ่มต้นพวกเขาจะขึ้นอยู่กับข้อผิดพลาด (ถั่วที่เริ่มต้นจะถูกลบออกจากสระ)
ประเภทที่สอง: Setter Method Singleton วิธีการเริ่มต้น
หากคุณต้องการพูดคุยเกี่ยวกับการฉีด setter เราควรดูรูปถั่วอินสแตนซ์ในฤดูใบไม้ผลิ
ดังที่แสดงในสองขั้นตอนแรกในรูปสปริงอินสแตนซ์วัตถุถั่วจากนั้นตั้งค่าคุณสมบัติของวัตถุ
แก้ไขไฟล์การกำหนดค่าเพื่อฉีดลงในโหมด SET:
<!-scope = "Singleton" (ค่าเริ่มต้นคือวิธีการซิงเกิล)-> <bean id = "a" scope = "singleton"> <property name = "studentb" ref = "b"> </property> </bean> <bean id = "b" spope = "singleton"> < scope = "singleton"> <property name = "studenta" ref = "a"> </property> </ebean>
นี่คือคลาสทดสอบ:
การทดสอบคลาสสาธารณะ {โมฆะคงที่สาธารณะหลัก (สตริง [] args) {applicationcontext context = ใหม่ classPathxMlApplicationContext ("com/zfx/applicationcontext.xml"); System.out.println (context.getBean ("a", studenta.class)); -ผลการพิมพ์คือ:
com.zfx.student.studenta@1fbfd6
ทำไมคุณไม่รายงานความผิดพลาดโดยใช้วิธีการที่กำหนด
มาดูภาพด้านบน สปริงแรกสร้างวัตถุถั่วโดยใช้โครงสร้าง ในเวลานี้สปริงจะใส่วัตถุอินสแตนซ์ลงในแผนที่และสปริงมีวิธีการที่จะได้รับการอ้างอิงวัตถุอินสแตนซ์ด้วยแอตทริบิวต์ UNSET จากตัวอย่างของเราเมื่อฤดูใบไม้ผลิอินสแตนติสนักศึกษา, StudentB และ StudentC จะตั้งค่าคุณสมบัติของวัตถุ ในเวลานี้ Studenta จะพึ่งพา StudentB และจะนำวัตถุ Singleton StudentB ออกไปในแผนที่และอื่น ๆ จะไม่มีปัญหาวนรอบ
ต่อไปนี้เป็นวิธีการใช้งานในซอร์สโค้ดฤดูใบไม้ผลิ ซอร์สโค้ดต่อไปนี้อยู่ในชั้นเรียนเริ่มต้น
/ ** แคชของวัตถุซิงเกิลตัน: ชื่อถั่ว -> อินสแตนซ์ถั่ว (คอลเลกชันแผนที่ที่แคชวัตถุอินสแตนซ์ซิงเกิ้ล)*/ แผนที่สุดท้ายส่วนตัว <String, Object> SingletonObjects = ใหม่ ConcurrentHashMap <String, Object> (64); / ** แคชของโรงงานซิงเกิลตัน: ชื่อถั่ว -> ObjectFactory (ซิงเกิลตันโรงงานคอลเลกชัน Cache Cache Cache)*/ MAP สุดท้าย <String, ObjectFactory> SingletonFactory = HashMap ใหม่ <String, ObjectFactory> (16); / ** แคชของวัตถุซิงเกิลยุคแรก: ชื่อถั่ว -> อินสแตนซ์ถั่ว*/ แผนที่สุดท้ายส่วนตัว <สตริง, วัตถุ> ournersingletonObjects = new hashmap <string, object> (16); / ** ชุดของ singletons ที่ลงทะเบียนซึ่งมีชื่อถั่วในลำดับการลงทะเบียน*/ ชุดสุดท้ายส่วนตัว <String> registersingletons = ใหม่ LinkedHashSet <String> (64); /*** เพิ่มอินสแตนซ์ Singleton* แก้ปัญหาการอ้างอิงแบบวงกลม* เพิ่มโรงงานซิงเกิลที่กำหนดสำหรับการสร้างซิงเกิลที่ระบุ* หากจำเป็น * <p> ที่จะเรียกร้องให้มีการลงทะเบียน Singletons อย่างกระตือรือร้นเช่นสามารถ * แก้ไขการอ้างอิงแบบวงกลมได้ * @param beanname ชื่อของถั่ว * @param singletonfactory โรงงานสำหรับวัตถุซิงเกิล */ โมฆะที่ได้รับการป้องกันการเพิ่มการเข้าร่วม (สตริง Beanname, ObjectFactory SingletonFactory) {assert.notnull ซิงโครไนซ์ (this.singletonobjects) {ถ้า (! this.singletonobjects.containskey (Beanname)) {this.singletonfactories.put (Beanname, SingletonFactory); this.earlysingletonobjects.remove (Beanname); this.registeredsingletons.add (Beanname); -ประเภทที่สาม: Setter Prototype, Prototype
แก้ไขไฟล์กำหนดค่าเป็น:
<bean id = "a" <span style = "color:#ff0000;"> scope = "prototype" </span >> <property name = "studentb" ref = "b"> </property> </epean> <bean id = "b" <span style = "color:#ff0000;"> </ebean> <bean id = "c" <span style = "สี:#ff0000;"> prope = "prototype" </span >> <property name = "studentc" ref = "c"> </property> </ebean> <bean id = "c" ref = "a"> </property> </ebean>
Prope = "Prototype" หมายความว่าวัตถุอินสแตนซ์ถูกสร้างขึ้นทุกครั้งที่คุณร้องขอ ความแตกต่างระหว่างทั้งสองคือ: ถั่วที่มีสถานะใช้ขอบเขตต้นแบบในขณะที่ไร้สัญชาติใช้ขอบเขต Singleton Singleton
กรณีทดสอบ:
การทดสอบคลาสสาธารณะ {โมฆะคงที่สาธารณะหลัก (สตริง [] args) {applicationcontext context = ใหม่ classPathxMlApplicationContext ("com/zfx/applicationcontext.xml"); <strong> // ในเวลานี้คุณจะต้องได้รับอินสแตนซ์ของการจัดการฤดูใบไม้ผลิเพราะตอนนี้ scope = "ต้นแบบ" จะสร้างอินสแตนซ์วัตถุเมื่อขอให้ได้รับ </strong> system.out.println (บริบท. getBean ("a", studenta.class); - ผลการพิมพ์:
เกิดจาก: org.springframework.beans.factory.beancurrentyincreationexception: ข้อผิดพลาดการสร้างถั่วด้วยชื่อ 'A': การร้องขอถั่วกำลังอยู่ในการสร้าง: มีการอ้างอิงแบบวงกลมที่ไม่สามารถแก้ไขได้หรือไม่?
เหตุใดแบบจำลองต้นแบบจึงผิด?
สำหรับถั่ว "ต้นแบบ" ที่มีการกำหนดค่าสปริงคอนเทนเนอร์ไม่สามารถฉีดพึ่งพาได้เสร็จสมบูรณ์เนื่องจากภาชนะสปริงไม่ได้แคชถั่วในถั่ว "ต้นแบบ" ดังนั้นถั่วที่สร้างขึ้นจึงไม่สามารถสัมผัสได้ล่วงหน้า
ข้างต้นเป็นเนื้อหาทั้งหมดของบทความนี้ ฉันหวังว่ามันจะเป็นประโยชน์ต่อการเรียนรู้ของทุกคนและฉันหวังว่าทุกคนจะสนับสนุน wulin.com มากขึ้น