ในชั้นเรียน Java ชายผู้ยิ่งใหญ่ชื่อ Rod Johnson พบว่าการพัฒนาระดับเริ่มต้นของ Java Enterprise อยู่ในสภาพที่วุ่นวาย
ดังนั้นจึงตัดสินใจเขียนโครงสร้างพื้นฐานทั่วไปที่สามารถแก้ปัญหาได้
เพราะเชื่อมั่นว่าการเขียนโปรแกรมเชิงอินเตอร์เฟสสามารถลดการเปลี่ยนแปลงได้ แต่ยังช่วยให้การขยายตัวและการเปลี่ยนแปลงอำนวยความสะดวก ดังนั้นจึงเขียนอินเทอร์เฟซต่อไปนี้
สิ่งแรกที่จะสร้างในสภาวะที่วุ่นวายคือแม่ของวัตถุทั้งหมด, beanfactory และด้วยมันคุณสามารถรับวัตถุทั้งหมดและคุณลักษณะที่มันบำรุงนั่นคือก่อนอื่น Gaia - แม่ของโลก
ด้วยแม่ต้นฉบับ Beanfactory จอห์นสันคิดว่าถ้าฉันต้องการที่จะได้ชุดวัตถุถั่วแทนที่จะเป็นหนึ่งหรือหลาย ๆ ? นอกจากนี้ถ้าลูกของแม่ต้องการให้กำเนิดหุ้นส่วน? ดังนั้นจอห์นสันจึงสร้าง ListableBeanFactory เพื่อใช้งานชุดของวัตถุถั่ว ตัวอย่างเช่น getBeansoftype สามารถรับชุดของถั่วชนิดเดียวกันตามมัน; สร้างลำดับชั้น beanfactory เพื่อแก้ปัญหาลำดับชั้นของ beanfactory หลายอย่างเช่น getParentBeanfactory สามารถรับโรงงานแม่ของ beanfactory
beanfactory นี้ถูกใช้ในที่สุดในแอปพลิเคชันดังนั้น beanfactory จะต้องได้รับความสามารถในการย้ายในแอปพลิเคชัน ใน beanfactory คุณจะต้องพิจารณาพฤติกรรมที่เกี่ยวข้องกับถั่วเช่นวิธีรับถั่วชนิดของถั่ว ฯลฯ ; และหากคุณต้องการให้ความสามารถแก่พวกเขาในแอปพลิเคชันคุณต้องพิจารณาเพิ่มเติมเช่นชื่อแอปพลิเคชันเวลาเริ่มต้น id ฯลฯ พฤติกรรมและคุณลักษณะที่เกี่ยวข้องกับแอปพลิเคชันเองดังนั้นจอห์นสันจึงคิดที่จะสร้างแอปพลิเคชัน จอห์นสันคิดว่า ApplicationContext นี้จะต้องสามารถทำสิ่งต่าง ๆ ได้หลายอย่างและจะต้องสามารถจัดการข้อมูลข้อความพารามิเตอร์และสากลได้ดังนั้นจึงเพิ่มอินเทอร์เฟซ MessagesOrce จะต้องสามารถเผยแพร่กิจกรรมเพื่อแยกส่วนประกอบได้ดังนั้นจึงมีอินเทอร์เฟซ ApplicationEventPublisher จะต้องสามารถรับไฟล์ทรัพยากรได้ดังนั้นจึงมีอินเตอร์เฟส ResourcePatternResolver มันจะต้องสามารถมีวัตถุการประมวลผลที่แตกต่างกันในสภาพแวดล้อมที่แตกต่างกันดังนั้นจึงมีอินเตอร์เฟสสิ่งแวดล้อม
ApplicationContext สืบทอดอินเทอร์เฟซเหล่านี้ทั้งหมด
แต่สิ่งที่สำคัญที่สุดคือทั้ง BeanFactory และ ApplicationContext จำเป็นต้องมีความสามารถที่กำหนดค่าได้ดังนั้นจึงมีอินเทอร์เฟซย่อยที่กำหนดค่าได้ว่าสามารถกำหนดค่าได้และ configurableapplicationContext นอกจากนี้เว็บยังเป็นเทรนด์ที่สำคัญมากในเวลานั้นและมันก็ไม่ซ้ำกันเล็กน้อยเมื่อเทียบกับแอปพลิเคชันอื่น ๆ ดังนั้นจึงจำเป็นต้องได้รับ ServletContext ดังนั้นจึงมี WebApplicationContext
จนถึงตอนนี้จอห์นสันได้คิดเชิงนามธรรมเกี่ยวกับพฤติกรรมอินเทอร์เฟซและไม่ได้นำไปใช้ในรายละเอียด
เมื่อมองไปที่ BeanFactory และ ApplicationContext ที่สร้างขึ้นจอห์นสันตระหนักว่างานของวันนั้นยังห่างไกลเพราะไม่มีวิธีแก้ปัญหาที่แท้จริงในการทำให้ระบบทั้งหมดทำงานได้ดังนั้นจอห์นสันจึงเริ่มคิดเกี่ยวกับวิธีการใช้งาน
สิ่งแรกที่ Johoson คิดเกี่ยวกับความสามารถในการดำเนินการนี้มีความสามารถอย่างไร แน่นอนว่าเราจำเป็นต้องรวม AutoWireCapableBeanFactory, ListableBeanFactory และ ConfigureDableBeanFactory ที่กล่าวถึงก่อนหน้านี้ ดังนั้นจึงมีการสร้าง configurableListableBeanFactory ประการที่สองความสามารถหลายอย่างสำหรับวัตถุถั่วจำเป็นต้องได้รับการพิจารณาหนึ่งคือความสามารถในการนามแฝง; ประการที่สองคือความสามารถในการบันทึกวัตถุซิงเกิล ประการที่สามคือความสามารถในการแคช; พวกเขาจะถูกนำไปใช้ในคลาส SimpleLeiAsRegistry, คลาส DefaultSingleTletonBeanRegistry และคลาส FactoryBeanRegistRySupport ตามลำดับ
ในที่สุด DefaultListableBeanFactory ถูกสร้างขึ้นซึ่งเป็นต้นแบบของโรงงาน IOC ทั้งหมดในฤดูใบไม้ผลิและเป็นลูกจริงของ Beanfactory เด็กคนนี้มีความสำคัญมากและได้กลายเป็นพื้นฐานสำหรับการสร้างภาชนะบรรจุ IOC อย่างอิสระ หากมีการขยายและใช้งานส่วนใหญ่จะได้รับการสืบทอดหรือใช้ร่วมกัน
หากคุณต้องการเริ่มต้นการเริ่มต้นที่เป็นไปได้ที่คุณสามารถใช้รหัสต่อไปนี้ได้
classPathResource res = new classPathResource ("ApplicationContext.xml"); defaultListableBeanFactory f = ใหม่ defaultListableBeanFactory (); XMLBEANDEFINITIONREADER R = ใหม่ XMLBEANDEFINITIONREADER (F); R.LoadBeanDefinitions (RES); ถัดไปจอห์นสันคิดว่า BeanFactory มีการใช้งานเริ่มต้นที่ค่อนข้างครอบคลุมดังนั้นสิ่งที่เกี่ยวกับ ApplicationContext? ดังนั้นการสร้างแอปพลิเคชันแอปพลิเคชันที่สำคัญอย่างไม่เคยมีมาก่อน: filesystemxmlapplicationcontext, classpathxmlapplicationContext, AnnotationConfigWebapplicationContext (อันที่จริงมีอีกมากมายเช่นการจัดการพอร์ตเล็ตและการจัดการเว็บ)
สิ่งแรกที่จอห์นสันคิดว่าคือวิธีการดำเนินการเริ่มต้นฤดูใบไม้ผลิ ควรวางไว้ในระดับที่ค่อนข้างเป็นนามธรรมเพื่อให้ทุกคลาสในระดับล่างสามารถนำกลับมาใช้ใหม่ได้ ดังนั้นเขาจึงใช้ configurableapplicationContext โดยใช้ AbstractApplicationContext นอกจากนี้ยังมีฟังก์ชั่นที่สำคัญมากนั่นคือการโหลดไฟล์ในรูปแบบของทรัพยากรซึ่งต้องการการสรุปทรัพยากรในคลาสทรัพยากรและการใช้การใช้งานเฉพาะของทรัพยากรการวางตำแหน่งไปยัง ResourceLoader AbstractApplicationContext ยังจำเป็นต้องสืบทอด defaultresourceLoader เพื่อให้ฟังก์ชั่นนี้ AbstractapplicationContext เสร็จสิ้นกระบวนการเริ่มต้นทั้งหมด (พระเจ้าจัดให้เสร็จในวันถัดไป) แต่ไม่ได้จัดการ beanfactory ดังนั้น subclass abstractrefreshableapplicationContext ทำสิ่งนี้โดยเฉพาะอย่างยิ่งการใช้งาน RefreshBeanFactory, closebeanfactory, GetBeanFactory จัดการวงจรชีวิตของ beanfactory แต่ abstractrefreshablePplicationContext ยังไม่โหลดถั่วที่กำหนดไว้ทั้งหมด ที่จะโหลดทรัพยากรที่กำหนดค่าไว้จริง ๆ แล้วมันไปที่ subclass ที่ต่ำกว่าเพื่อทำเช่น filesystemxmlapplicationContext ซึ่งคือการอ่าน XML ApplicationContext ไปยังระบบไฟล์ classpathxmlapplicationContext คือการอ่าน ApplicationContext นี้ไปยังเส้นทางการโหลดคลาส AnnotationConfigWebapplicationContext โหลดถั่วจากคำอธิบายประกอบของไฟล์คลาสและการสแกนสปริงเริ่มตั้งแต่ตอนนี้
เมื่อเห็นว่ากรอบหลักได้รับการจัดตั้งขึ้นจอห์นสันก็หลับไปด้วยความพึงพอใจด้วยรอยยิ้ม
วันแรกจอห์นสันเสร็จสิ้นกรอบการทำงานโดยรวมของฤดูใบไม้ผลิ
ในวันที่สองจอห์นสันกำลังเตรียมที่จะจัดการกับปัญหาก่อนหน้านี้จริง ๆ ตัวอย่างเช่นกระบวนการเริ่มต้นคอนเทนเนอร์ของสปริง ดังที่แสดงในรูปจอห์นสันแบ่งกระบวนการนี้ออกเป็น subprocesses จำนวนมากซึ่งทั้งหมดทำงานรอบเป้าหมายที่ยิ่งใหญ่ของการโหลดถั่ว
กระบวนการนี้ถูกวางไว้ในวิธีการรีเฟรชใน AbstractApplicationContext รหัสมีดังนี้: จอห์นสันแบ่งกระบวนการรีเฟรชออกเป็น subprocesses จำนวนมากและกระบวนการย่อยเหล่านี้อยู่ในระดับนามธรรมเดียวกัน วิธีการเขียนนี้คือการให้แบบอย่างที่ดีในอนาคต
Public Void Refresh () พ่น beansexception, unglishalstateException {ซิงโครไนซ์ (this.startupshutdownmonitor) {// เตรียมบริบทนี้สำหรับการรีเฟรช Prepressfresh (); // บอกคลาสย่อยให้รีเฟรชโรงงานถั่วภายใน configurableListableBeanFactory beanfactory = etaidfreshbeanfactory (); // เตรียมโรงงานถั่วเพื่อใช้ในบริบทนี้ preparybeanfactory (beanfactory); ลอง {// อนุญาตให้โพสต์การประมวลผลของโรงงานถั่วในคลาสย่อยบริบท postprocessbeanfactory (beanfactory); // เรียกใช้โปรเซสเซอร์จากโรงงานที่ลงทะเบียนเป็นถั่วในบริบท InvokeBeanFactoryPostProcessors (BeanFactory); // ลงทะเบียนโปรเซสเซอร์ถั่วที่สกัดกั้นการสร้างถั่ว RegisterBeanPostProcessors (BeanFactory); // เริ่มต้นแหล่งข้อความสำหรับบริบทนี้ InitMessagesource (); // เริ่มต้นเหตุการณ์ Multicaster สำหรับบริบทนี้ InitapplicationEventMulticaster (); // เริ่มต้นถั่วพิเศษอื่น ๆ ในคลาสย่อยเฉพาะบริบท onrefresh (); // ตรวจสอบถั่วผู้ฟังและลงทะเบียน registerListeners (); // อินสแตนซ์ Singletons ที่เหลืออยู่ทั้งหมด FinishBeanFactoryInitialization (beanfactory); // ขั้นตอนสุดท้าย: เผยแพร่เหตุการณ์ที่เกี่ยวข้อง FinishRefresh (); } catch (beansexception ex) {// ทำลายซิงเกิ้ลที่สร้างขึ้นแล้วเพื่อหลีกเลี่ยงทรัพยากรที่ห้อยต่อง Destroybeans (); // รีเซ็ตธง 'ใช้งาน' Cancelrefresh (ex); // เผยแพร่ข้อยกเว้นให้กับผู้โทร โยนอดีต; - หากคุณดูในระดับที่สูงขึ้นกระบวนการเหล่านี้จะหมุนได้หลายด้าน: 1. รีเฟรชวงจรชีวิต; 2. การเริ่มต้นและการเตรียมการของ beanfactory; 3. สร้างและลงทะเบียน Beandefinition; 4. Postprocessor Beanfactory; 5. ตั้งข้อความเหตุการณ์และผู้ฟัง
1. วงจรชีวิตที่สดชื่น
PREPARYEREFRESH กระบวนการนี้ส่วนใหญ่จะบันทึกบันทึกและระบุว่าฤดูใบไม้ผลิเริ่มต้นขึ้นเริ่มต้นทรัพยากรทรัพย์สิน (เช่นการเริ่มต้นทรัพยากรบางอย่างใน SERLVET) และการตรวจสอบทรัพยากรทรัพย์สิน (เช่นการเขียนคีย์โดยไม่มีค่าเท่านั้น)
Onrefresh วัตถุประสงค์คือเพื่อให้แอปพลิเคชันพิเศษบางอย่างเพื่อให้พวกเขาสามารถขยายในระหว่างกระบวนการรีเฟรช การใช้งานปัจจุบันส่วนใหญ่คือการตั้งค่าธีมสำหรับบริบทแอปพลิเคชัน Servlet
FinishRefresh ทำงานตกแต่งบางอย่างเช่นการเริ่มต้น LifeCycleProcessor การเผยแพร่เหตุการณ์ที่ลงท้ายด้วยการรีเฟรช ฯลฯ
Cancelrefresh ส่วนใหญ่จะเปลี่ยนสถานะปัจจุบันเป็นแบบไม่ใช้งานเมื่อมีข้อยกเว้นเกิดขึ้น
2. การเริ่มต้นและการเตรียมการของ beanfactory
จอห์นสันคิดว่าเราควรปล่อยให้การโหลด beanfactory และลงทะเบียนถั่วอย่างโปร่งใสเมื่อเริ่มต้นดังนั้นการห่อหุ้มของฉันจึงประสบความสำเร็จอย่างมากสำหรับโลกภายนอกดังนั้นขั้นตอนนี้จึงทำสิ่งต่าง ๆ มากมาย รูปต่อไปนี้ละเว้นหลายขั้นตอนและแสดงเฉพาะประเด็นสำคัญ
AbstractApplicationContext จะเรียก RefreshBeanFactory มันจะตรวจสอบและปิด beanfactory ที่มีอยู่ก่อนจากนั้นสร้าง beanfactory ใหม่แล้วใช้โรงงานนี้เพื่อโหลด beandefinitions ทั้งหมด
ในหมู่พวกเขา LoadBeanDefinitions จะถูกส่งไปยังคลาสย่อยสำหรับการใช้งานที่แตกต่างกัน ตัวอย่างเช่น AbstractxMlapplicationContext ส่วนใหญ่จะอ่านผ่าน XML; การใช้คำ AnnotationConfigWebapplicationContext จะเรียกสแกนเนอร์เพื่อสแกนถั่วในชั้นเรียน
3. สร้างและลงทะเบียน Beandefinition
หลังจากแยกวิเคราะห์การกำหนดค่า XML วิธี ParsedEfaultElement ของ DefaultBeandEfinitionDocumentReader จะทำการประมวลผลที่สอดคล้องกันตามองค์ประกอบใน XML ในหมู่พวกเขาเมื่อพบองค์ประกอบของถั่ววิธีการลงทะเบียนในการลงทะเบียนใน beandefinitionreaderutils จะถูกเรียกในที่สุด พารามิเตอร์ที่ผ่านในวิธีนี้คือ BeanDefinitionRegistry ซึ่งจริง ๆ แล้วโทรกลับวิธีการลงทะเบียน BEANDEFINITION ของ DefaultListableBeanFactory เพื่อลงทะเบียน BeanDefinition
4. Postprocessor ของ Beanfactory
postprocessor beanfactory เป็นวิธีที่จัดทำโดยฤดูใบไม้ผลิเพื่อให้คลาสย่อยของมันมีความยืดหยุ่น มี 2 ขั้นตอนในฤดูใบไม้ผลิ: PostprocessBeanFactory, InvokeBeanFactoryPostProcessors RegisterBeanPostProcessors อินสแตนซ์และโทรหา beanpostprocessors ทั้งหมดซึ่งใช้เพื่อขยายถั่วก่อนและหลังการเริ่มต้นถั่ว
5. ตั้งค่าข้อความเหตุการณ์และผู้ฟัง
ตั้งค่าแหล่งที่มาข้อความเริ่มต้นเป็น delegatingMessageSource หากมีข้อความในโรงงานอยู่แล้วให้ใช้ข้อความนี้ Event Multicaster เป็นเรื่องง่ายที่จะใช้งานได้ง่าย หากมี ApplicationEventMulticaster อยู่แล้วในโรงงานให้ใช้ ApplicationEventMulticaster นี้และลงทะเบียนผู้ฟังแอปพลิเคชันทั้งหมดเพื่อรับกิจกรรม
MessagesOrce เป็นวิธีที่สำคัญสำหรับไฟล์ทรัพยากรระหว่างประเทศ สปริงรองรับแหล่งข้อความใน ApplicationContext
ฤดูใบไม้ผลิให้การใช้งาน MessagesOrce เริ่มต้นโดยใช้ java.util.resourceBundle เพื่อแยกข้อความ ฤดูใบไม้ผลิสามารถเข้าถึงข้อความโดยตรงจาก ApplicationContext.getMessage () โดยการกำหนดค่าถั่วด้วยรหัสพิเศษเป็น MessagesOrce และตั้งชื่อไฟล์ของ i18n หากอยู่ใน JSP คุณสามารถเข้าถึงข้อความผ่านสปริง: แท็กข้อความ
เหตุการณ์: เหตุการณ์เป็นกลไกการแยกส่วนที่สำคัญ ฤดูใบไม้ผลิได้แนะนำใน Core ApplicationContext หลักการของมันค่อนข้างง่าย ในอีกด้านหนึ่งเครื่องกำเนิดเหตุการณ์สามารถส่งเหตุการณ์ได้ ในทางกลับกันดูเหมือนว่าผู้ฟังเหตุการณ์สามารถตอบสนองต่อเหตุการณ์ได้ การใช้งานที่เฉพาะเจาะจงโดยทั่วไปถือคอลเลกชันผู้ฟังเหตุการณ์ในเครื่องกำเนิดและ "ลงทะเบียน" (นั่นคือเข้าร่วม) ผู้ฟังทั้งหมดในคอลเลกชันผู้ฟังเหตุการณ์นี้
ในฤดูใบไม้ผลิ ApplicationContext ใช้เป็นตัวสร้างเหตุการณ์แอปพลิเคชันจะใช้เป็นคอลเลกชันผู้ฟังและ ApplicationEventMulticaster ใช้ในการเผยแพร่กิจกรรม
หลายขั้นตอนในการเผยแพร่กิจกรรม:
การสมัครสมาชิก: เริ่มแรก AddapplicationListener ไปยังคอลเลกชันผู้ฟัง
เผยแพร่: ApplicationContext สืบทอด ApplicationEventPublisher จึงใช้ PublisheVent วิธีนี้จะสำรวจคอลเลกชัน ApplicationListeners ของ ApplicationContext นี้ก่อนที่จะเรียก onApplicationEvent สำหรับผู้ฟังแต่ละคนดังนั้นผู้ฟังแต่ละคนจะได้รับแจ้ง หลังจากขั้นตอนนี้เสร็จสิ้นเหตุการณ์เดียวกันจะถูกเผยแพร่สำหรับแอพพลิเคชั่นทั้งหมดของ ApplicationContext Parent
การเผยแพร่เหตุการณ์เป็นเรื่องธรรมดามาก แอปพลิเคชันของเราไม่เพียง แต่สามารถใช้การเผยแพร่กิจกรรมนี้ได้ แต่ Framework Spring นั้นยังใช้การเผยแพร่เหตุการณ์ นี่คือแอปพลิเคชั่นของกิจกรรมในฤดูใบไม้ผลิ:
ContextrefreshedEvent จะถูกเผยแพร่ใน FinishRefresh เพื่อระบุว่าการรีเฟรชสิ้นสุดลงและแจ้งผู้ฟัง ใน ApplicationContext วิธีการเริ่มต้นและหยุดจะเผยแพร่เหตุการณ์ที่ระบุบริบทเริ่มต้นหรือสิ้นสุด
หลังจากที่จอห์นสันสร้างกรอบหลักและกระบวนการดำเนินงานของฤดูใบไม้ผลิเขาพบว่าฤดูใบไม้ผลิมีสถานที่ขยายตัวที่ยืดหยุ่นมากมาย ดังนั้นจอห์นสันกำลังเตรียมที่จะประกาศการใช้การขยายตัวที่ยืดหยุ่นเหล่านี้ในวันที่สาม
1. BeanPostProcessor BeanPostProcessor จัดเตรียมอินเทอร์เฟซส่วนขยายหลังจากการสร้างถั่วเสร็จสมบูรณ์ เมื่อคุณต้องการทำการประมวลผลถั่วหลังจากถูกสร้างขึ้น BeanPostProcessor เป็นวิธีที่ต้องการ
2. รับรู้. ถั่วฉีดจำเป็นต้องรู้บางส่วนของภาชนะ ฤดูใบไม้ผลิเสร็จสิ้นการโทรกลับผ่านการรับรู้เช่น BeannameAwer ซึ่งช่วยให้ถั่วรู้ชื่อ BeanFactoryAware สามารถให้ถั่วเข้าใจ BeanFactory, ApplicationContextAware ซึ่งช่วยให้ถั่วสามารถใช้งาน ApplicationContext ได้ ด้วยวิธีนี้ถั่วที่ฉีดด้วยสปริงสามารถทำสิ่งต่าง ๆ ได้ในวงกว้าง
สำหรับการขยายของ BeanPostProcessor สปริงตัวเองมีตัวอย่างของวิธีการระบุถั่วที่รับรู้ ถั่วที่รับรู้เป็นถั่วที่ค่อนข้างพิเศษและฤดูใบไม้ผลิต้องใช้คุณลักษณะเพิ่มเติมบางอย่าง ดังนั้นสปริงจะใช้สำหรับกระบวนการฉีดอย่างไร? ในความเป็นจริงฤดูใบไม้ผลิไม่ได้เขียนไว้ในกระบวนการประมวลผลหลัก แต่ใส่ไว้ใน ApplicationContextawareProcessor, beanpostprocessor และในที่สุดก็ indexaWaWareInterfaces เพื่อกำหนดประเภทของถั่วและการฉีดแอตทริบิวต์ที่สอดคล้องกัน วิธีการนี้ใช้ beanpostprocessor เพื่อให้การใช้งานเพิ่มเติมอีกครั้งซึ่งยอดเยี่ยมจริงๆ
โมฆะส่วนตัว InvokeAwerInterfaces (Object Bean) {ถ้า (Bean Instance ของการรับรู้) {ถ้า (Bean Instanceof EnvironmentArar) {((((สิ่งแวดล้อม) ถั่ว). setenvironment (this.applicationContext.getenvironment ()); } if (bean instanceof embeddedvalueresolveraware) {((embeddedvalueresolveraware) bean). setembeddedDvalueresolver (ใหม่ EmbeddedValueresolver } if (bean instanceof resourceLoaderAware) {((ResourceLoaderAware) Bean) .setResourceLoader (this.applicationContext); } if (Bean Instance ของ ApplicationEventPublisherAware) {((ApplicationEventPublisherAware) ถั่ว) .SetApplicationEventPublisher (this.applicationContext) } if (bean instanceof messagesourceware) {((messagesourceware) ถั่ว) .setMessageSource (this.applicationContext); } if (Bean Instanceof ApplicationContextaware) {((ApplicationContextaware) Bean) .setApplicationContext (this.applicationContext); -มีกฎเพิ่มเติมสำหรับการใช้การรับรู้ ตัวอย่างเช่นรหัสต่อไปนี้สามารถรับรู้แอปพลิเคชันแอปพลิเคชัน หลังจากฤดูใบไม้ผลิสร้างถั่วนี้มันจะฉีด ApplicationContext เพื่อให้เราสามารถใช้บริบทนี้เพื่อให้การเผยแพร่เหตุการณ์เสร็จสมบูรณ์
คลาสสาธารณะ HelloBean ใช้ ApplicationContextAware {ApplicationContext Private ApplicationContext; สตริงส่วนตัว helloword = "สวัสดี! โลก!"; โมฆะสาธารณะ setApplicationContext (บริบท ApplicationContext) {this.applicationContext = บริบท; } โมฆะสาธารณะ sethelloword (String helloword) {this.helloword = helloword; } Public String GetHelloword () {ApplicationContext.publisheVent (ใหม่ PropertyGetTedEvent ("[" + Helloword + "] ได้รับ")); กลับ Helloword; - 3. BeanFactoryPostProcessor, postprocessor นี้มักจะใช้เพื่อจัดการอินเทอร์เฟซเพิ่มเติมที่สร้างโดย BeanFactory ตัวอย่างมีดังนี้ หลังจากฉีดถั่วนี้มันจะพิมพ์จำนวนถั่วฉีดโดยอัตโนมัติหลังจากการสร้าง beanfactory:
Public Class Beancounter ใช้ beanfactorypostprocessor {@Override โมฆะสาธารณะ postprocessbeanfactory (configurableListableBeanfactory beanfactory) พ่น beansexception {system.out.println - 4. FactoryBean FactoryBean เป็นถั่วพิเศษซึ่งช่วยให้ฉีดเข้าไปในภาชนะฤดูใบไม้ผลิและสร้างถั่วจริงดังนั้นจึงสามารถกำหนดด้วยวิธีนี้ โรงงานเบียนเป็นถั่วซึ่งมีความสามารถในการจัดหาถั่ว ต่อไปนี้เริ่มต้นด้วยการโทรหาโรงงานและพูดคุยเกี่ยวกับวิธีที่ฤดูใบไม้ผลิใช้ถั่วนี้
เพื่อแยกความแตกต่างระหว่างถั่วธรรมดาและโรงงานในฤดูใบไม้ผลิจะต้องมีกระบวนการตัดสินพวกเขาและจัดการกับพวกเขาเป็นพิเศษ กระบวนการนี้อยู่ใน getObjectorBeanInstance ของ AbstractBeanFactory
วัตถุที่ได้รับการป้องกัน getObjectForBeanInstance (Object beaninstance, ชื่อสตริง, สตริง Beanname, RootBeanDefinition MBD) {// อย่าปล่อยให้รหัสโทรพยายามทำโรงงานหากถั่วไม่ใช่โรงงาน if (beanfactoryutils.isfactorydereference (ชื่อ) &&! (Beaninstance Instanceof FactoryBean)) {โยน beanisnotafactoryexception ใหม่ (transformedBeanName (ชื่อ), beaninstance.getClass ()); } // ตอนนี้เรามีอินสแตนซ์ถั่วซึ่งอาจเป็นถั่วปกติหรือโรงงานเบียน // ถ้าเป็นโรงงานเราใช้มันเพื่อสร้างอินสแตนซ์ถั่วเว้นแต่ผู้โทร // ต้องการอ้างอิงถึงโรงงาน if (! (Instance Beaninstance ของ FactoryBean) || beanfactoryutils.isfactorydereference (ชื่อ)) {return beaninstance; } วัตถุวัตถุ = null; if (mbd == null) {object = getCachedObjectForForfactoryBean (BeanName); } if (object == null) {// return bean อินสแตนซ์จากโรงงาน FactoryBean <?> Factory = (FactoryBean <?>) Beaninstance; // Caches Object ที่ได้รับจากโรงงานเบียนถ้าเป็นซิงเกิลตัน if (mbd == null && containsBeanDefinition (beanName)) {mbd = getMergedLocalBeanDefinition (BeanName); } บูลีนสังเคราะห์ = (mbd! = null && mbd.issynthetic ()); Object = getObjectFromFactoryBean (โรงงาน, Beanname ,! สังเคราะห์); } return object; - จะเห็นได้ว่าหากเป็นถั่วธรรมดามันจะถูกส่งคืนโดยตรงและถ้าเป็นโรงงานเบียนการโทรครั้งสุดท้ายจะเรียกโรงงาน GetObject เพื่อส่งคืนวัตถุที่เฉพาะเจาะจง หากคุณคิดว่าฤดูใบไม้ผลิทั้งหมดเป็นโรงงานนามธรรมและเมื่อผลิตถั่วนามธรรมโรงงานเบียนเป็นโรงงานเฉพาะที่ผลิตวัตถุที่คุณต้องการ
มีการใช้ประโยชน์จากโรงงานมากมายในฤดูใบไม้ผลิ เพื่อให้ตัวอย่างที่ค่อนข้างธรรมดาเมื่อรวม SessionFactory ของ Hibernate, LocalSessionFactoryBean มักจะถูกฉีด แต่ SessionFactory นี้ไม่ใช่ถั่วธรรมดา มันสามารถผลิตได้ง่ายๆโดยการฉีดเข้าไปในไฟล์การกำหนดค่า มันมีชิ้นส่วนที่กำหนดเองมากมายดังนั้นฤดูใบไม้ผลิทำให้ถั่วนี้เป็นโรงงานและควบคุมวัตถุการผลิต