คำนำ
บทความนี้ส่วนใหญ่แนะนำเนื้อหาที่เกี่ยวข้องเกี่ยวกับการค้นหา (วิธีการฉีด) ในฤดูใบไม้ผลิ มันถูกแบ่งปันสำหรับการอ้างอิงและการเรียนรู้ของคุณ ฉันจะไม่พูดด้านล่างมากนัก มาดูการแนะนำรายละเอียดร่วมกัน:
สิ่งนี้อาจเกิดขึ้นได้เมื่อใช้สปริง: ถั่วซิงเกิลหนึ่งตัวขึ้นอยู่กับถั่วที่ไม่ใช่ผิวน้ำอีกตัว หากคุณเพียงแค่ใช้การประกอบอัตโนมัติเพื่อฉีดพึ่งพาปัญหาบางอย่างอาจเกิดขึ้นดังที่แสดงด้านล่าง:
คลาส A สำหรับซิงเกิลตัน
@ComponentPublic Class classa {@autowired Private classb classb; โมฆะสาธารณะ printclass () {system.out.println ("นี่คือคลาส A:" + สิ่งนี้); classb.printclass (); -คลาส B สำหรับการไม่เข้าร่วม
@component@scope (value = scope_prototype) คลาสสาธารณะคลาส b {โมฆะสาธารณะ printclass () {system.out.println ("นี่คือคลาส B:" + สิ่งนี้); - ที่นี่ Class A ใช้ขอบเขตของ Singleton เริ่มต้นและขึ้นอยู่กับ Class B ขอบเขตของ Class B เป็นต้นแบบดังนั้นจึงไม่ใช่ Singleton ในเวลานี้คุณสามารถเห็นปัญหาการเขียนเช่นนี้หลังจากทำการทดสอบ:
@Runwith (SpringRunner.Class) @ContextConfiguration (classes = {classa.class, classb.class}) คลาสสาธารณะ mytest {@autowired ส่วนตัว Classa classa; @Test Public Void SimpleTest () {สำหรับ (int i = 0; i <3; i ++) {classa.printclass (); -ผลลัพธ์ผลลัพธ์คือ:
นี่คือคลาส A: classa@282003e1
นี่คือคลาส B: classb@7fad8c79
นี่คือคลาส A: classa@282003e1
นี่คือคลาส B: classb@7fad8c79
นี่คือคลาส A: classa@282003e1
นี่คือคลาส B: classb@7fad8c79
อย่างที่คุณเห็นรหัสแฮชของทั้งสองคลาสนั้นเหมือนกันในสามเอาต์พุต เป็นที่เข้าใจกันว่าคุณค่าของคลาส A ยังคงไม่เปลี่ยนแปลงเพราะมันเป็นซิงเกิล แต่ขอบเขตของคลาส B เป็นต้นแบบ แต่ยังทำให้รหัสแฮชไม่เปลี่ยนแปลงซึ่งดูเหมือนว่าจะกลายเป็นซิงเกิลตัน?
เหตุผลสำหรับสถานการณ์นี้คือขอบเขตของคลาส A คือ Singleton เริ่มต้นดังนั้นบริบทจะสร้างถั่วของ Class A เพียงครั้งเดียวดังนั้นจึงมีโอกาสเพียงครั้งเดียวที่จะฉีดพึ่งพาและคอนเทนเนอร์ไม่สามารถจัดหาคลาส A ใหม่ได้ทุกครั้ง
ทางออกไม่ดีนัก
ในการแก้ปัญหาข้างต้นคุณสามารถทำการแก้ไขคลาส A เพื่อใช้งาน ApplicationContextaware
@ComponentPublic คลาส Classa ใช้ ApplicationContextaware {ApplicationContext Private ApplicationContext; โมฆะสาธารณะ printclass () {system.out.println ("นี่คือคลาส A:" + สิ่งนี้); getClassB (). printclass (); } public classb getClassB () {return applicationcontext.getBean (classb.class); } โมฆะสาธารณะ setApplicationContext (ApplicationContext ApplicationContext) พ่น beansexception {this.applicationContext = ApplicationContext; -ด้วยวิธีนี้คุณสามารถค้นหาถั่วใหม่ได้ด้วยตนเองในบริบททุกครั้งที่คุณต้องไปเรียน B หลังจากทำการทดสอบอีกครั้งฉันได้รับผลลัพธ์ต่อไปนี้:
นี่คือคลาส A: com.devhao.classa@4df828d7
นี่คือคลาส B: com.devhao.classb@31206beb
นี่คือคลาส A: com.devhao.classa@4df828d7
นี่คือคลาส B: com.devhao.classb@3e77a1ed
นี่คือคลาส A: com.devhao.classa@4df828d7
นี่คือคลาส B: com.devhao.classb@3ffcd140
คุณจะเห็นได้ว่ารหัสแฮชของคลาส A ยังคงไม่เปลี่ยนแปลงในผลลัพธ์ทั้งสามในขณะที่คลาส B นั้นแตกต่างกันทุกครั้งซึ่งแสดงให้เห็นว่าปัญหาได้รับการแก้ไขและมีการใช้อินสแตนซ์ใหม่ทุกครั้งที่เรียกว่า
อย่างไรก็ตามวิธีการเขียนนี้ควบคู่ไปกับฤดูใบไม้ผลิและฤดูใบไม้ผลิเป็นอีกวิธีหนึ่งในการลดการรุกราน
@lookup
ฤดูใบไม้ผลิมีคำอธิบายประกอบที่เรียกว่า @lookup ซึ่งเป็นคำอธิบายประกอบที่ใช้งานได้กับวิธีการ วิธีการที่ทำเครื่องหมายไว้จะถูกแทนที่ จากนั้นตามประเภทของค่าส่งคืนคอนเทนเนอร์เรียกใช้วิธี getBean () ของ beanfactory เพื่อส่งคืนถั่ว
@ComponentPublic คลาสคลาส {โมฆะสาธารณะ printclass () {system.out.println ("นี่คือคลาส A:" + สิ่งนี้); getClassB (). printclass (); } @lookup public classb getClassB () {return null; - มันสามารถพบได้ว่ามันง่ายกว่ามากและไม่เข้ากันอย่างมากกับฤดูใบไม้ผลิอีกต่อไป การรันการทดสอบอีกครั้งยังสามารถรับเอาต์พุตที่ถูกต้องได้
ค่าการส่งคืนของวิธีการที่มีคำอธิบายประกอบนั้นไม่สำคัญอีกต่อไปเนื่องจากคอนเทนเนอร์จะสร้างคลาสย่อยแบบไดนามิกจากนั้นเขียนใหม่/ใช้วิธีการอธิบายประกอบและวิธีการย่อยในที่สุดก็เรียกว่า
วิธี @lookup ที่ใช้ต้องปฏิบัติตามลายเซ็นต่อไปนี้:
<สาธารณะ | ได้รับการป้องกัน> [Abstract] <Return-type> thomethodname (No-Arguments);
สรุป
ข้างต้นเป็นเนื้อหาทั้งหมดของบทความนี้ ฉันหวังว่าเนื้อหาของบทความนี้จะมีค่าอ้างอิงบางอย่างสำหรับการศึกษาหรือที่ทำงานของทุกคน หากคุณมีคำถามใด ๆ คุณสามารถฝากข้อความไว้เพื่อสื่อสาร ขอบคุณสำหรับการสนับสนุน Wulin.com