ขอบเขตของถั่วไร้สัญชาติเป็นอินสแตนซ์ซิงเกิล หากเราฉีดถั่ว B ของต้นแบบลงในถั่วของซิงเกิลและหวังว่าจะสามารถส่งคืนถั่วใหม่ได้ทุกครั้งที่เรียกว่าถั่ว () ของถั่ว A เรียกว่าข้อกำหนดนี้ไม่สามารถทำได้โดยใช้วิธีการฉีดแบบดั้งเดิม เนื่องจากการกระทำของการฉีดถั่วที่เกี่ยวข้องของถั่วของซิงเกิลเกิดขึ้นเพียงครั้งเดียวแม้ว่าขอบเขตของถั่ว B เป็นประเภทต้นแบบวัตถุที่กลับมาผ่าน getBeanb () ยังคงเป็นถั่ว B ที่ถูกฉีดในตอนแรก
ดังนั้นหากคุณต้องการส่งคืน Beanb ใหม่ทุกครั้งที่คุณเรียก GetBeanb () ของ Beana โซลูชั่นเสริมคือให้ Beana ใช้อินเทอร์เฟซ BeanFactoryAware เพื่อให้คุณสามารถเข้าถึงคอนเทนเนอร์แล้วนำไปใช้ในวิธีต่อไปนี้
ก่อนกำหนด XML:
<Bean ID = "Author" Prope = "Prototype"/> <bean id = "Book" P: name = "Veil"> </ebean>
ขอบเขตของผู้เขียนถั่วถูกตั้งค่าเป็นต้นแบบ
คลาสหนังสือใช้อินเทอร์เฟซ BeanFactoryAware:
หนังสือชั้นเรียนสาธารณะใช้ beanfactoryaware {...@overridepublic void setbeanfactory (beanfactory beanfactory) พ่น beansexception {this.factory = beanfactory;} ผู้เขียนสาธารณะ getPrototypeauthor () {return (ผู้เขียน) โรงงาน -การทดสอบหน่วย:
บริบท ApplicationContext; @beforemethodpublic การตั้งค่าโมฆะ () พ่นข้อยกเว้น {บริบท = ใหม่ classPathxMlApplicationContext ("Beans5-5.xml");}@testPublic Void Test () {หนังสือหนังสือ = (หนังสือ) บริบท. getBean ("หนังสือ"); System.out.println (book.getauthor (). hashcode ()); System.out.println (book.getauthor (). hashcode ()); System.out.println (book.getPrototypeauthor (). hashCode ()); System.out.println (book.getPrototypeauthor (). hashCode ());ผลการทดสอบ
จากผลลัพธ์เราจะเห็นได้ว่ามีเพียงอินสแตนซ์ของผู้เขียนที่ได้รับจาก beanfactory เท่านั้น
การใช้งานนี้ผูกแอปพลิเคชันด้วยกรอบสปริง มีทางออกที่ดีกว่านี้หรือไม่? ใช่มันเป็นวิธีการฉีด
1 วิธีการฉีด
คอนเทนเนอร์ฤดูใบไม้ผลิพึ่งพาไลบรารี CGLIB ดังนั้นรหัสไบต์ของคลาสสามารถทำงานได้แบบไดนามิกในระหว่างการรันไทม์เช่นการสร้างคลาสย่อยแบบไดนามิกหรือคลาสการใช้งานของถั่ว
อินเทอร์เฟซ BookInterface:
Public Interface BookInterface {ผู้แต่ง getauthor ();}การกำหนดค่า XML:
<!-วิธีการฉีด-> <bean id = "ผู้แต่ง" scope = "ต้นแบบ" p: name = "maugham"/> <bean id = "book2"> <lookup-method name = "getauthor" bean = "ผู้เขียน"/> </epean>
การทดสอบหน่วย:
BookInterface Book = (BookInterface) Context.getBean ("Book2"); assert.assertequals ("maugham", book.getauthor (). getName ()); assert.asserttrue (book.getauthor (). hashcode ()! = book.getauthor ()ด้วยวิธีการกำหนดค่านี้การใช้งานแบบไดนามิกสามารถจัดเตรียมไว้สำหรับอินเทอร์เฟซและถั่วที่ส่งคืนด้วยวิธีนี้เป็นอินสแตนซ์ใหม่ทั้งหมด
ดังนั้นหากคุณต้องการได้ถั่วต้นแบบในถั่วซิงเกิลคุณสามารถใช้การค้นหาเพื่อใช้วิธีการฉีด
2 วิธีการเปลี่ยน
ในฤดูใบไม้ผลิคุณสามารถใช้วิธีการของถั่วเพื่อแทนที่วิธีอื่นของถั่ว
สมมติว่ามีวิธี getName () ในหนังสือเพื่อรับชื่อ:
/*** ชื่อหนังสือ*/ชื่อสตริงส่วนตัว; สตริงสาธารณะ getName () {return name;}ตอนนี้เราสร้างถั่วใหม่ซึ่งใช้อินเตอร์เฟส MethodReplacer เพื่อแทนที่วิธี getName () ในหนังสือ:
Public Class Book4 ใช้ MethodReplacer {@Override การปรับปรุงวัตถุสาธารณะใหม่ (Object OBJ, วิธีการ, วัตถุ [] args) โยน {return "return" มีชีวิตอยู่ "; -การกำหนดค่า:
<bean id = "book3" p: name = "Bright Thousand Suns"> <แทนที่ชื่อวิธีการ = "getName" replacer = "book4"/> </epean> <bean id = "book4"/>>
ทดสอบ:
หนังสือหนังสือ = (หนังสือ) บริบท. getBean ("book3"); assertequals ("Living", book.getName ()); สรุป
ข้างต้นคือการใช้วิธีการฉีดหรือทดแทนในกรอบฤดูใบไม้ผลิที่แนะนำโดยตัวแก้ไข ฉันหวังว่ามันจะเป็นประโยชน์กับทุกคน หากคุณมีคำถามใด ๆ โปรดฝากข้อความถึงฉัน บรรณาธิการจะตอบกลับทุกคนในเวลา!