บทความนี้ส่วนใหญ่วิเคราะห์แนวคิดการออกแบบของสถาปัตยกรรมกระดูกของกรอบฤดูใบไม้ผลิของกรอบฤดูใบไม้ผลิ ทำไมส่วนประกอบเหล่านี้ถึงต้องการส่วนประกอบเหล่านี้? พวกเขารวมเข้าด้วยกันเพื่อสร้างสถาปัตยกรรมโครงกระดูกของฤดูใบไม้ผลิได้อย่างไร? ฟีเจอร์ AOP ของ Spring ใช้สถาปัตยกรรมโครงกระดูกพื้นฐานเหล่านี้ทำงานได้อย่างไร มีการใช้โมเดลการออกแบบแบบใดในฤดูใบไม้ผลิเพื่อให้การออกแบบนี้เสร็จสมบูรณ์ แรงบันดาลใจของแนวคิดการออกแบบนี้คือการออกแบบซอฟต์แวร์ในอนาคตของเราคืออะไร? บทความนี้จะตอบคำถามเหล่านี้โดยละเอียด
สถาปัตยกรรมโครงกระดูกของฤดูใบไม้ผลิ
มีส่วนประกอบมากกว่าหนึ่งโหลในฤดูใบไม้ผลิ แต่มีเพียงไม่กี่องค์ประกอบหลักที่แท้จริง
รูปที่ 1. แผนภาพสถาปัตยกรรมโดยรวมของกรอบการทำงานของ Thespring
จะเห็นได้จากรูปด้านบนว่ามีเพียงสามองค์ประกอบหลักในกรอบฤดูใบไม้ผลิ: แกนบริบทและถั่ว พวกเขาสร้างสถาปัตยกรรมโครงกระดูกฤดูใบไม้ผลิทั้งหมด หากไม่มีพวกเขามันเป็นไปไม่ได้ที่จะมีลักษณะของชั้นบนเช่น AOP และเว็บ ด้านล่างนี้จะวิเคราะห์สปริงส่วนใหญ่จากองค์ประกอบทั้งสามนี้
แนวคิดการออกแบบของฤดูใบไม้ผลิ
ดังที่ได้กล่าวไว้ก่อนหน้านี้ส่วนประกอบหลักของฤดูใบไม้ผลิจะถูกนำมาใช้ ถั่วเป็นตัวเอกที่แท้จริงในฤดูใบไม้ผลิ
บทบาทของ Bean ในฤดูใบไม้ผลินั้นเหมือนกับความหมายของ OPPLING ต่อ OOP เช่นเดียวกับขั้นตอนการแสดง แต่ไม่มีนักแสดง เหตุใดจึงมีความสำคัญในการออกแบบถั่วในฤดูใบไม้ผลิ จัดการไฟล์การกำหนดค่าซึ่งเป็นกลไกการฉีดพึ่งพาของเขา และความสัมพันธ์ในการฉีดนี้ได้รับการจัดการในคอนเทนเนอร์ IOC แล้ววัตถุของภาชนะ IOC นั้นถูกห่อหุ้มด้วยถั่วอะไร ฤดูใบไม้ผลิเป็นจุดประสงค์ในการจัดการวัตถุเหล่านี้และการดำเนินการเพิ่มเติมบางอย่างโดยการบรรจุวัตถุในถั่ว
กลยุทธ์การออกแบบนั้นคล้ายคลึงกับแนวคิดการออกแบบของ Java ที่จะใช้ OOP แน่นอน สภาพแวดล้อมนี้ในสภาพแวดล้อมนี้ตามกฎบางอย่าง คิดเกี่ยวกับมันคิดเกี่ยวกับเฟรมเวิร์กอื่น ๆ ที่เราใช้ในแนวคิดการออกแบบที่คล้ายกันขนาดใหญ่
วิธีการทำงานร่วมกับองค์ประกอบหลัก
ดังที่ได้กล่าวไว้ก่อนหน้านี้ Bean เป็นปัจจัยสำคัญในฤดูใบไม้ผลิ หากคุณเป็นนักแสดงในการแสดงบริบทเป็นพื้นหลังของการแสดงนี้และหลักควรเป็นอุปกรณ์ประกอบฉากของประสิทธิภาพ เมื่อพวกเขาอยู่ด้วยกันพวกเขาสามารถมีเงื่อนไขพื้นฐานที่สุดที่สามารถแสดงได้ดี แน่นอนว่าเงื่อนไขพื้นฐานที่สุดไม่สามารถทำให้การแสดงนี้โดดเด่นและการแสดงที่เขาแสดงนั้นน่าตื่นเต้นพอสมควร
เรารู้ว่าถั่วเป็นวัตถุและวัตถุต้องมีข้อมูล พวกเขาและเพื่อรักษาความสัมพันธ์นี้ ดังนั้นบริบทคือคอลเลกชันของความสัมพันธ์ถั่ว ดังนั้นการใช้องค์ประกอบหลักคืออะไร? ในความเป็นจริงหลักคือคอลัมน์บางอย่างที่จำเป็นสำหรับความสัมพันธ์ระหว่างถั่วแต่ละตัวที่จะค้นพบสร้างและรักษาความสัมพันธ์ระหว่างถั่วแต่ละตัว
พวกเขาสามารถแสดงได้ด้วยรูปด้านล่าง:
รูปที่ 2. ความสัมพันธ์องค์ประกอบสามประการ
คำอธิบายโดยละเอียดเกี่ยวกับองค์ประกอบหลัก
ที่นี่เราจะแนะนำความสัมพันธ์แบบลำดับชั้นของแต่ละองค์ประกอบโดยละเอียดรวมถึงคำสั่งซื้อที่รันไทม์ เราควรให้ความสนใจกับการใช้ฤดูใบไม้ผลิ
ส่วนประกอบถั่ว
ความสำคัญของส่วนประกอบถั่วถึงฤดูใบไม้ผลิได้รับการอธิบายก่อนหน้านี้ ส่วนประกอบถั่วได้รับการบรรจุภายใต้ org.springframework.beans ของฤดูใบไม้ผลิ หมวดหมู่ทั้งหมดภายใต้แพ็คเกจนี้จะแก้ปัญหาสามสิ่งได้: คำจำกัดความของถั่วการสร้างถั่วและการวิเคราะห์ถั่ว สำหรับผู้ใช้ในฤดูใบไม้ผลิสิ่งเดียวที่ต้องมีการดูแลคือการสร้างถั่ว
รูปแบบโรงงานทั่วไปของ Springbean ถูกสร้างขึ้น
รูปที่ 4. ความสัมพันธ์ในการสืบทอดของโรงงาน
BeanFactory มีสามคลาสย่อย: ListableBeanFactory, HierarchicalBeanFactory และโรงงานถั่วที่มีความสามารถ AutoWire แต่จากรูปด้านบนเราสามารถพบว่าคลาสการใช้งานเริ่มต้นขั้นสุดท้ายคือ defaultlistableBeanFactory และเขาใช้อินเทอร์เฟซทั้งหมด เหตุใดจึงกำหนดอินเทอร์เฟซหลายระดับ ตรวจสอบซอร์สโค้ดและคำแนะนำของอินเทอร์เฟซเหล่านี้ กระบวนการดำเนินการ ตัวอย่างเช่นอินเทอร์เฟซ ListableBeanFactory บ่งชี้ว่าถั่วเหล่านี้มีรายชื่อและลำดับชั้น beanfactory หมายความว่าถั่วเหล่านี้มีความสัมพันธ์ในการสืบทอดนั่นคือถั่วแต่ละตัวอาจมีถั่วพ่อ อินเทอร์เฟซ AutoWireCapableBeanFactory กำหนดกฎการประกอบอัตโนมัติของ Bean อินเทอร์เฟซทั้งสี่นี้ร่วมกันกำหนดคอลเลกชันของถั่วความสัมพันธ์ระหว่างถั่วและพฤติกรรมถั่ว
คำจำกัดความของถั่วส่วนใหญ่รวมถึงคำอธิบาย beandefinition
รูปที่ 5 แผนภาพความสัมพันธ์แบบลำดับชั้นของชั้นเรียนที่กำหนดโดย BEAN
คำจำกัดความของถั่วเป็นคำอธิบายที่สมบูรณ์ของข้อมูลทั้งหมดในโหนดที่คุณกำหนดไว้ในไฟล์การกำหนดค่าของฤดูใบไม้ผลิรวมถึงไฟล์ย่อยต่างๆ เมื่อสปริงวิเคราะห์โหนดที่คุณกำหนดได้สำเร็จเขาจะถูกเปลี่ยนเป็นวัตถุ beandefinition ภายในฤดูใบไม้ผลิ การดำเนินการทั้งหมดจะทำสำหรับวัตถุนี้ในอนาคต
กระบวนการวิเคราะห์ของ Bean นั้นซับซ้อนมากและฟังก์ชั่นแบ่งออกเป็นรายละเอียดเนื่องจากมีสถานที่มากมายที่จะขยายที่นี่และพวกเขาจะต้องมั่นใจในความยืดหยุ่นเพียงพอที่จะรับมือกับการเปลี่ยนแปลงที่เป็นไปได้ การวิเคราะห์ของ Bean ส่วนใหญ่จะวิเคราะห์ไฟล์การกำหนดค่าสปริง กระบวนการวิเคราะห์นี้ส่วนใหญ่เสร็จสิ้นผ่านชั้นเรียนในรูปด้านล่าง:
รูปที่ 6. คลาสวิเคราะห์ของ BEAN
แน่นอนว่ายังมีการวิเคราะห์แท็กเฉพาะ
ส่วนประกอบบริบท
บริบทได้รับการบรรจุภายใต้ org.springframework.context ของฤดูใบไม้ผลิ ลองมาดูกันว่าสภาพแวดล้อมนี้สร้างขึ้นได้อย่างไร
ApplicationContext เป็นคลาสหลักของบริบท ด้านล่างนี้เป็นแผนภาพโครงสร้างของบริบท:
รูปที่ 7.Context -ไดอะแกรมโครงสร้างคลาสที่เกี่ยวข้อง
จะเห็นได้จากรูปด้านบนว่าแอปพลิเคชันแอปพลิเคชันสืบทอด beanfactory ซึ่งแสดงให้เห็นว่าวัตถุหลักของคอนเทนเนอร์สปริงคือถั่วนอกจากนี้มันจะถูกอธิบายในรายละเอียดในแกน
คลาสย่อยของ ApplicationContext ส่วนใหญ่มีสองด้าน:
ConfiguRableapplicationContext ระบุว่าบริบทได้รับการแก้ไขนั่นคือผู้ใช้สามารถเพิ่มหรือแก้ไขข้อมูลการกำหนดค่าที่มีอยู่ในบริบท
WebApplicationContext เป็นชื่อของชื่อซึ่งเป็นบริบทที่เตรียมไว้สำหรับเว็บ
จากนั้นการลดลงคือการสร้างประเภทของบริบทตามด้วยวิธีการเข้าถึงบริบท ระดับระดับแรกดังกล่าวถือเป็นระดับบริบทที่สมบูรณ์
โดยทั่วไปแล้ว ApplicationContext จะต้องกรอกข้อมูลต่อไปนี้:
◆สร้างสภาพแวดล้อมแอปพลิเคชัน
◆ใช้ beanfactory เพื่อสร้างวัตถุถั่ว
◆บันทึกตารางความสัมพันธ์ของวัตถุ
◆สามารถจับเหตุการณ์ต่าง ๆ ได้
ในฐานะที่เป็นคอนเทนเนอร์ Spring IOC บริบทโดยทั่วไปรวมคุณสมบัติส่วนใหญ่ของฤดูใบไม้ผลิหรือเป็นพื้นฐานของคุณสมบัติส่วนใหญ่
องค์ประกอบหลัก
ส่วนประกอบหลักซึ่งเป็นองค์ประกอบหลักของฤดูใบไม้ผลิมีหมวดหมู่ที่สำคัญมากมาย วิธีนี้ในการสรุปทรัพยากรทั้งหมดลงในอินเทอร์เฟซที่คุ้มค่าในการเรียนรู้ในการออกแบบในอนาคต มาดูบทบาทของส่วนนี้ในฤดูใบไม้ผลิ
รูปด้านล่างคือแผนภาพโครงสร้างที่เกี่ยวข้องกับทรัพยากรที่เกี่ยวข้อง:
รูปที่ 8.Rsource ไดอะแกรมโครงสร้างคลาสที่เกี่ยวข้อง
จะเห็นได้จากรูปด้านบนว่าอินเทอร์เฟซทรัพยากรห่อหุ้มประเภททรัพยากรที่เป็นไปได้ต่าง ๆ นั่นคือความแตกต่างในประเภทไฟล์ถูกบล็อกสำหรับผู้ใช้ สำหรับผู้ให้บริการทรัพยากรวิธีการบรรจุทรัพยากรให้กับคนอื่น ๆ เพื่อใช้มันเป็นปัญหา ด้วยวิธีนี้ทรัพยากรทั้งหมดสามารถรับได้ผ่านคลาส InputStream ดังนั้นผู้ให้บริการทรัพยากรจึงได้รับการป้องกัน ปัญหาอีกประการหนึ่งคือปัญหาของการโหลดทรัพยากรนั่นคือโหลดเดอร์ของทรัพยากรจะต้องรวมเป็นหนึ่ง
ลองมาดูกันว่าบริบทและทรัพยากรได้สร้างความสัมพันธ์อย่างไร? ก่อนอื่นดูแผนภาพความสัมพันธ์ของพวกเขา:
รูปที่ 9. แผนภาพความสัมพันธ์ของ Concontext และทรัพยากร
ดังที่เห็นได้จากรูปด้านบนบริบทมอบความไว้วางใจในการทำงานของการโหลดการวิเคราะห์และคำอธิบายของทรัพยากรให้กับคลาส Patternresolver ที่จะเสร็จสิ้น มีหลายวิธีที่คล้ายกันกับองค์ประกอบหลัก
วิธีการทำงานในคอนเทนเนอร์ IOC
ดังที่ได้กล่าวไว้ก่อนหน้านี้โครงสร้างและการพึ่งพาซึ่งกันและกันขององค์ประกอบหลักส่วนประกอบถั่วและส่วนประกอบบริบท
วิธีสร้างโรงงานผลิตถั่ว
ตามที่อธิบายไว้ในรูปที่ 2 คอนเทนเนอร์ IOC เป็นเครือข่ายความสัมพันธ์ถั่วรวมกับองค์ประกอบอีกสององค์ประกอบ ทางเข้าในตัวอยู่ในวิธีการรีเฟรชของคลาส AbstractApplicationContext รหัสของวิธีนี้มีดังนี้:
รายการ 1.ABSTRACTAPPLICATIONCONTEXT.REFRESH
Public Void Refresh () พ่น beansexception, unglimalstateException {synchronized (this.startupshutdownmonitor) {// เตรียมบริบทนี้สำหรับการรีเฟรช บริบท ลงทะเบียนโปรเซสเซอร์ที่ bean crea tion subclasses Catch (Beansexception Ex) {// ทำลาย Alream สร้าง Singletons เพื่อหลีกเลี่ยงทรัพยากร Dangl ing ();วิธีนี้คือการสร้างรหัสที่สมบูรณ์สำหรับกระบวนการคอนเทนเนอร์ IOC ทั้งหมดและเข้าใจว่าแต่ละบรรทัดของรหัสภายในนั้นเข้าใจถึงหลักการและฟังก์ชั่นของฤดูใบไม้ผลิส่วนใหญ่
รหัสนี้ส่วนใหญ่มีขั้นตอนดังกล่าว:
◆สร้าง beanfactory ตามลำดับ
◆เหตุการณ์อาจมีความสนใจในการลงทะเบียน
◆สร้างวัตถุอินสแตนซ์ถั่ว
◆เรียกเหตุการณ์ที่ฟัง
ด้านล่างรวมกับการวิเคราะห์รหัสของกระบวนการเหล่านี้
ประโยคที่สองและสามคือการสร้างและกำหนดค่า beanfactory นี่คือการรีเฟรชนั่นคือรีเฟรชการกำหนดค่า ต่อไปนี้เป็นรหัสวิธีสำหรับการอัปเดต beanfactory:
รายการ 2.
ได้รับการป้องกันครั้งสุดท้าย refreshbeanfactory () โยน beansexception {ถ้า (hasbeanfactory ()) {destroybeans (); ;วิธีนี้ตระหนักถึงวิธีการนามธรรมของ AbstractApplicationContext RefreshBeanFactory โปรดทราบว่าประเภทของวัตถุ beanfactory มีประเภทของวัตถุหลากหลายประเภท วัตถุดั้งเดิมของ Beanfactory คือ defaultlistablebeanfactory
รูปที่ 10.DefaultListableBeanFactory คลาสไดอะแกรมการสืบทอด
นอกเหนือจากชั้นเรียนที่เกี่ยวข้องกับ Beanfactory แล้วยังพบว่ามันเกี่ยวข้องกับการลงทะเบียนของถั่ว ในวิธี RefreshBeanFactory มีบรรทัดของ LoadBeanDefinitions (beanfactory) ที่จะค้นหาคำตอบ ภาชนะบรรจุ
กระบวนการนี้สามารถอธิบายได้ในแผนที่ลำดับต่อไปนี้:
รูปที่ 11. สร้างคำนำเวลาของ beanfactory
การวิเคราะห์และกระบวนการลงทะเบียนของถั่วมีดังนี้:
มะเดื่อ
หลังจากสร้าง beanfactory ให้เพิ่มคลาสเครื่องมือบางอย่างที่จำเป็นโดย Spring เอง
รหัสสามบรรทัดถัดไปใน AbstractApplicationContext มีบทบาทสำคัญในการขยายฟังก์ชั่นของฤดูใบไม้ผลิ สองบรรทัดแรกได้รับอนุญาตให้แก้ไขการกำหนดค่าของ beanfactory ในตัวในตอนนี้ ดังนั้นพวกเขาทั้งหมดขยายฟังก์ชั่นของฤดูใบไม้ผลิดังนั้นเราต้องเรียนรู้ที่จะใช้ส่วนนี้ของการใช้สปริง
ในหมู่พวกเขาในวิธีการของ InvokeBeanFactoryPostProcessors ส่วนใหญ่จะได้รับ subclasses เพื่อใช้งานอินเตอร์เฟส BeanFactoryPostProcessor และดำเนินการวิธีการ postprocessbeanfactory คำสั่งของวิธีนี้มีดังนี้:
รายการ 3.BeanFactoryPostProcessor.postProcessBeanFactory
เป็นโมฆะ postprocessbeanfactory (configurablelistablebeanfactory beanfactory) พ่น beansexception;
พารามิเตอร์ของมันคือ beanfactory ซึ่งระบุว่าสามารถแก้ไขได้โดย Beanfactory ข้อมูล
เมธอด registerBeanPostProcessors ยังสามารถรับคลาสย่อยของคำจำกัดความของผู้ใช้ของอินเทอร์เฟซ BeanPostProcessor และดำเนินการกับตัวแปร BeanPostProcessors ในวัตถุ beanfactory ทั้งสองวิธีได้รับการประกาศใน beanpostprocessor: postprocessbeforeinitialization และ postprocessafterinilization ใช้เพื่อดำเนินการในระหว่างการเริ่มต้นของวัตถุถั่ว สามารถดำเนินการที่ผู้ใช้กำหนด
รหัสสายหลังคือการลงทะเบียนของการเริ่มต้นของเหตุการณ์การตรวจสอบและผู้ฟังคนอื่น ๆ ของระบบ
วิธีสร้างอินสแตนซ์ถั่วและสร้างเครือข่ายความสัมพันธ์ของถั่ว
ต่อไปนี้เป็นรหัสอินสแตนซ์ของถั่วซึ่งเริ่มต้นด้วยวิธีการ finisbeanfactoryinitity
รายการ 4.ABSTRACTAPPLICITIONCONTEXT.FinishBeanFactoryInitialization
Void Void FinishBeanFactoryInitialization (configurawlistablebeanfactory beanfactory) {// หยุดโดยใช้ tempossloader สำหรับการจับคู่ประเภท Lazy-init) Singletonsจะพบได้ว่าตัวอย่างของถั่วสามารถพบได้ใน beanfactory รหัสของวิธี preinstantiatesingletons มีดังนี้:
รายการ 5.DefaultListableBeanFactory.preinstantialsingletons
โมฆะสาธารณะ preinstantiatesingletons () พ่น beansexception {ถ้า (this.logger.isinfoenabled ()) {this.logger.info ("singletons pre-instantiating ใน";} ซิงโครไนซ์ BEANDEFINITIONNES) {RootBeanDefinition BD = GetMergedLocalBeandEfinition (Beanname); iseagerinit; ถ้า (system.getSecurityManager ()! = null &&; startoryof smartfactorybean) {isea gerinit = accessController.doprivileged (& nb sp; ใหม่ . Iiseagerinit (); ;}}}}}}}}มีถั่วที่สำคัญมากที่นี่ -factorybean มันสามารถกำหนดวิธีการสร้างวัตถุอินสแตนซ์ตราบใดที่วิธีการ getObject ของเขาถูกนำไปใช้ อย่างไรก็ตามวัตถุอินสแตนซ์ของถั่วนี้ในสปริงคือโรงงาน เป้าหมายของการได้รับสปริงของสปริงนั้นเสร็จสมบูรณ์ด้วย & เพื่อให้เสร็จสมบูรณ์
วิธีการสร้างวัตถุอินสแตนซ์ของถั่วและวิธีการสร้างคีย์หลักในความสัมพันธ์ที่เกี่ยวข้องระหว่างวัตถุอินสแตนซ์ถั่วต่อไปนี้เป็นแผนผังลำดับงานของกระบวนการนี้
รูปที่ 13. แผนภูมิการสร้างอินสแตนซ์อินสแตนซ์
หากเป็นถั่วธรรมดาเขาจะสร้างอินสแตนซ์ของเขาโดยตรงโดยเรียกวิธีการรับเบียน ต่อไปนี้เป็นแผนที่เวลา -ลำดับของการสร้างอินสแตนซ์ถั่ว:
รูปที่ 14. แผนภูมิการสร้างอินสแตนซ์แบบเบียน
อีกส่วนที่สำคัญมากคือการสร้างความสัมพันธ์ระหว่างอินสแตนซ์วัตถุถั่ว
รูปที่ 15. การจัดตั้งความสัมพันธ์ระหว่างวัตถุ
จุดขยายของคอนเทนเนอร์ IOC
ปัญหาอีกประการหนึ่งคือวิธีการทำให้วัตถุถั่วเหล่านี้มีความสามารถในการขยายบางอย่างนั่นคือการดำเนินการบางอย่างสามารถเพิ่มได้ แล้วส่วนขยายคืออะไร? ฤดูใบไม้ผลิเรียกส่วนขยายเหล่านี้อย่างไร?
สำหรับคอนเทนเนอร์ IOC ของฤดูใบไม้ผลิมีมากมาย BeanFactoryPostProcessor, BeanPostProcessor พวกเขาจะถูกเรียกเมื่อสร้าง beanfactory และการสร้างวัตถุถั่ว มีการเริ่มต้นเบียนและ disposablebean ผู้ใช้สามารถใช้วิธีการที่กำหนดไว้ในอินเทอร์เฟซเหล่านี้และสปริงจะเรียกพวกเขาในเวลาที่เหมาะสม อีกอย่างคือ FactoryBean
จุดขยายตัวเหล่านี้มักจะเป็นที่ที่เราใช้สปริงเพื่อทำภารกิจเฉพาะของเราให้เสร็จสมบูรณ์ . คุณสามารถใช้คำอุปมาต่อไปนี้เพื่ออธิบาย
เราเปรียบเทียบคอนเทนเนอร์ IOC กับกล่องหนึ่งกล่องนี้มีลูกบอลหลายรุ่น จากนั้นความสัมพันธ์ที่สอดคล้องกันของพวกเขาคือ beanfactory คือรูปแบบการทำเครื่องโหมดลูกคือถั่วและลูกบอลของโหมดลูกเป็นอินสแตนซ์ของถั่ว ส่วนขยายที่กล่าวถึงก่อนหน้านี้อยู่ที่ไหน BeanFactoryPostProcessor สอดคล้องกับการสร้างแบบจำลองลูกบอลและคุณจะมีโอกาสในการแก้ไขมันนั่นคือเขาสามารถช่วยคุณปรับเปลี่ยนโหมดลูก InitializingBean และ DisposableBean อยู่ที่จุดเริ่มต้นและจุดสิ้นสุดของรุ่นบอลและคุณสามารถเตรียมการและงานที่ทำให้เสร็จได้ BeanPostProcessor ช่วยให้คุณสามารถแก้ไขโหมดบอลได้อย่างเหมาะสม ในที่สุดก็มีโรงงานเบียนซึ่งเป็นแบบจำลองลูกบอลวิเศษ โหมดบอลนี้ไม่ได้ล่วงหน้า แต่คุณจะกำหนดรูปร่างของเขา ลูกบอลที่คุณต้องการ
วิธีใช้คอนเทนเนอร์ IOC สำหรับฉัน
การแนะนำก่อนหน้านี้ของกระบวนการก่อสร้างของภาชนะฤดูใบไม้ผลิฤดูใบไม้ผลิสามารถทำอะไรให้เราได้และคอนเทนเนอร์ IOC ของฤดูใบไม้ผลิสามารถทำอะไรได้บ้าง? เราต้องสร้างคอนเทนเนอร์ IOC โดยใช้สปริง
IOC กำลังสร้างลูกบาศก์ของ Rubik สำหรับคุณ แล้วเราจะเข้าร่วมได้อย่างไร? นี่คือสิ่งที่ฉันพูดก่อนหน้านี้เพื่อทำความเข้าใจส่วนขยายบางอย่างในฤดูใบไม้ผลิและเราเปลี่ยนพฤติกรรมร่วมกันของฤดูใบไม้ผลิโดยการบรรลุจุดขยายเหล่านั้น สำหรับวิธีการบรรลุจุดขยายเพื่อให้ได้ผลลัพธ์บุคลิกภาพที่เราต้องการมีตัวอย่างมากมายในฤดูใบไม้ผลิ ใช้สำหรับการอ้างอิง
คำอธิบายโดยละเอียดเกี่ยวกับคุณสมบัติ AOP ในฤดูใบไม้ผลิ
หลักการของการดำเนินงานของพร็อกซีแบบไดนามิก
เพื่อให้เข้าใจถึง AOP ของฤดูใบไม้ผลิหลักการของหน่วยงานไดนามิกจะต้องเข้าใจก่อนเพราะ AOP ถูกนำไปใช้ตามพร็อกซีแบบไดนามิก ตัวแทนไดนามิกจะต้องเริ่มต้นด้วย JDK เอง
มีชั้นเรียนพร็อกซีภายใต้แพ็คเกจ java.lang.reflet ของ JDK ซึ่งเป็นทางเข้าสู่ระดับเอเจนซี่ โครงสร้างของคลาสนี้:
รูปที่ 16. โครงสร้างโครงสร้าง
จากภาพด้านบนทั้งสี่เป็นวิธีการสาธารณะ วิธีสุดท้าย Newproxyinstance เป็นวิธีการสร้างวัตถุพร็อกซี ซอร์สโค้ดของวิธีนี้มีดังนี้:
รายการ 6.proxy.newproxyinstance
วัตถุสแตติกสาธารณะ newproxyinstance (classloader loader, class> [] อินเตอร์เฟส, InvocatchHandler h) พ่นผิดกฎหมาย {ถ้า (h == null) {แถวใหม่ nullpointerexception ();} cl = getproxyclass (โหลด = cl.getConstructor (ConstructorParams); ;วิธีนี้ต้องใช้พารามิเตอร์สามตัว: classloader ซึ่งใช้ในการโหลดคลาสพร็อกซีคลาสโหลดเดอร์ อินเทอร์เฟซคืออินเทอร์เฟซที่จะแสดง InvocationHandler ใช้เพื่อดำเนินการการดำเนินงานของผู้ใช้ที่ถูกปรับแต่งโดยผู้ใช้นอกเหนือจากวิธีการในอินเทอร์เฟซพร็อกซี ผู้ใช้เรียกวิธีการเป้าหมายโดยวิธีที่ไม่ซ้ำกันที่กำหนดไว้ในคลาส InvacationHandler เรียกใช้ จะอธิบายอย่างละเอียดในภายหลัง
มาดูกันว่าพร็อกซีสร้างคลาสพร็อกซีได้อย่างไร มันถูกเปิดเผยด้านล่าง
รูปที่ 17. สร้างวัตถุพร็อกซี
ในความเป็นจริงมันสามารถพบได้จากรูปด้านบนว่าคลาสตัวแทนอยู่ในวิธีการของ GenerateProxyclass ของ Proxygenerator คลาส Proxygientor ถูกห่อหุ้มด้วย Sun.misc
หากมีอินเทอร์เฟซดังกล่าวดังนี้:
รายการ 7. คลาส SimpleProxy
อินเทอร์เฟซสาธารณะ SimpleProxy {โมฆะสาธารณะ sizemethod1 ();โครงสร้างคลาสที่สร้างโดยตัวแทนมีดังนี้:
รายการ 8. $ proxy2 คลาส
ระดับสาธารณะ $ proxy2 ขยาย java.lang.rang.reflect.proxy ใช้ simpleproxy {java.lang.reflect.method m0; วิธีการ M3;วิธีการในคลาสนี้จะเรียกวิธีการเรียกใช้ของ InvocationHandler และแต่ละวิธีจะสอดคล้องกับตัวแปรคุณสมบัติ นี่คือวิธีที่ตัวแทนทั้งหมดรับรู้
วิธีการบรรลุ Springaop
จากหลักการของเอเจนต์ก่อนหน้านี้เรารู้ว่าจุดประสงค์ของพร็อกซีคือเมื่อมีการเรียกวิธีการเป้าหมายเราสามารถเรียกใช้วิธีการเรียกใช้ของคลาส ravecocationhandler ดังนั้นวิธีการสร้างบทความเกี่ยวกับการเรียกร้องให้เป็นกุญแจสำคัญในการใช้ AOP .
การดำเนินการ AOP ของฤดูใบไม้ผลิเป็นข้อตกลงที่จะปฏิบัติตามพันธมิตร AOP ในเวลาเดียวกันฤดูใบไม้ผลิได้ขยายออกไปเพิ่มอินเทอร์เฟซบางอย่างเช่น PointCut และ Advisor เพื่อให้มีความยืดหยุ่นมากขึ้น
ด้านล่างนี้เป็นแผนภาพคลาสของพร็อกซีไดนามิก JDK:
รูปที่ 18.JDK ไดอะแกรมคลาสพร็อกซีแบบไดนามิก
ภาพด้านบนแสดงอินเทอร์เฟซที่กำหนดโดยคำจำกัดความของ AOP Alliance อย่างชัดเจน อย่าพูดถึงว่า Spring ขยาย AOP Alliance อย่างไร
รายการ 9. กำหนดค่าถั่วพร็อกซี
<bean id = "testbeansingleton"> <property name = "ProxyInterfaces"> <value> org.springframework.ap.framework.prototypettests $ testbean value> p roperty> <property name = "target"> <ref local = "testebeantarget" > ref> คุณสมบัติ> <property name = "Singleton"> <dange> TrueValue> คุณสมบัติ> <property name = "interceptors"> <list> <dalue> testinterceptorValue> <val ue> testinterceptor2Value> รายการ> bean> bean> bean> bean> bean> bean> bean>
ในการกำหนดค่าดูว่าอินเทอร์เฟซของเอเจนต์ถูกตั้งค่าคลาสการใช้งานของอินเทอร์เฟซคือคลาสเป้าหมายและการสกัดกั้นจะถูกเรียกก่อนที่จะดำเนินการวิธีการเป้าหมาย แก่นแท้
มาดูกันว่าฤดูใบไม้ผลิจะเสร็จสิ้นตัวแทนและวิธีการเรียกตัวดักจับ
ดังที่ได้กล่าวไว้ก่อนหน้านี้สปริง AOP ยังได้รับการขยายตัวของตัวเองเพื่อให้คุณได้รับคุณสมบัตินี้ แน่นอนว่าวัตถุพร็อกซีควรสร้างแบบไดนามิกผ่านคลาสพร็อกซี
ต่อไปนี้เป็นแผนภูมิเวลาของวัตถุพร็อกซีที่สร้างขึ้นโดยฤดูใบไม้ผลิ:
รูปที่ 19. การเกิดขึ้นของวัตถุวัตถุ
หลังจากฤดูใบไม้ผลิสร้างวัตถุพร็อกซีเมื่อคุณเรียกวิธีการบนวัตถุเป้าหมายคุณจะถูกแสดงในวิธีการเรียกร้องของคลาส InvocationHandler ซึ่งได้รับการอธิบายก่อนหน้านี้ ที่นี่คลาส JDKDYNAMICAPPROXY ใช้อินเทอร์เฟซ INHECATIONHANDLER
ลองมาดูกันว่าฤดูใบไม้ผลิเรียกว่าการสกัดกั้น
รูปที่ 20.Spring เรียกตัวดักจับ
ข้างต้นเป็นตัวแทนไดนามิกของ JDK
การวิเคราะห์โหมดการออกแบบในฤดูใบไม้ผลิ
นอกจากนี้ยังมีรูปแบบการออกแบบมากมายที่ใช้ในฤดูใบไม้ผลิเช่นโหมดโรงงานโหมดซิงเกิ้ลโหมดเทมเพลต ฯลฯ ใน "รูปแบบสถาปัตยกรรมและการออกแบบของเฟรมเวิร์ก Webx", "สถาปัตยกรรมระบบของ Tomcat และการวิเคราะห์การออกแบบโหมด" แนะนำแล้ว ที่นี่เราแนะนำโหมดเอเจนซี่และโหมดกลยุทธ์เป็นหลัก
โหมดพร็อกซี
หลักการโหมดพร็อกซี
โหมดพร็อกซีคือการสร้างวัตถุพร็อกซีสำหรับวัตถุบางอย่างและวัตถุพร็อกซีควบคุมการอ้างอิงไปยังวัตถุดั้งเดิมและการสร้างวัตถุพร็อกซีนี้สามารถเพิ่มการดำเนินการเพิ่มเติมบางอย่างให้กับวัตถุดั้งเดิม ด้านล่างนี้เป็นโครงสร้างของโหมดพร็อกซี:
รูปที่ 21. โครงสร้างของโหมดพร็อกซี
หัวเรื่อง: ชุดรูปแบบนามธรรมมันเป็นอินเทอร์เฟซที่จะรับรู้วัตถุจริงของวัตถุตัวแทน
Proxysubject: นอกเหนือจากอินเทอร์เฟซของคำจำกัดความของธีมนามธรรมคลาสพร็อกซีจะต้องมีการอ้างอิงของวัตถุตัวแทน
RealSubject: คลาสของเอเจนต์คือวัตถุเป้าหมาย
วิธีการใช้โหมดพร็อกซีในฤดูใบไม้ผลิ
JDK Dynamic Agent ใน Spring AOP ทำได้โดยใช้เทคโนโลยีโหมดเอเจนซี่ นอกเหนือจากอินเทอร์เฟซของวัตถุพร็อกซีในฤดูใบไม้ผลิแล้วยังมี org.springframework.aop.springproxy และ org.springframework.apork.advise ตัวสร้างของการใช้โหมดพร็อกซีในฤดูใบไม้ผลิมีดังนี้:
รูปที่ 22. แผนภาพโครงสร้างของโหมดพร็อกซีใช้ในการเดินสาย
$ พร็อกซีเป็นวัตถุพร็อกซีที่สร้างขึ้นและหัวเรื่องเป็นธีมที่เป็นนามธรรมและวัตถุพร็อกซีคือการอ้างอิงถึงวัตถุเป้าหมายผ่านการเรียกร้อง
โครงสร้างวัตถุพร็อกซีจริงในฤดูใบไม้ผลิมีดังนี้:
รายการ 10 พร็อกซีวัตถุ $ proxy4
ระดับสาธารณะ $ proxy4 ขยาย java.lang.reflect.proxy ใช้ org.springframework.ap.framework.prototypettests $ testbean work.aop.springproxy org.springframework.aop.framework Reflect.mether M9; .Method M26; java.lang.reflect.Method M6; java.lang.reflect.method m28; java.lang.reflethod m14; java.lang. Reflect.method m12; java . Lang.reflet.Method M27; java.lang .reflect.method m11; java.lang.reflect.method m22; java.lang.reflect.Method m3; java.lang.reflect.Method java.lang.reflect. Method m4; java.lang.reflet.method m19; java .lang.reflect.Method M7; java.lang.reflet.method m15; java.lang.reflet.method m20; left.Method M10; java. LANG.Reflect.Method M1; java.lang.reflect.Method M17; java .lang.reflect.Method M21; java.lang.reflect.Method m0; ava.lang.reflet.method m24; int HashCode (); int indexof (org.SpringFramework.aop.advisor); int interxof (org.aopalliance. aip.advice); ject); java.lang.string tostring (); void sayhello (); void dosomething (); void dosometHing2 (); java.lang.class getProxiedIndIndIndIndIndIndIRFACES (); ProxytargetClass (); Org.SpringFramework.aop .advisor; getadvisors (); void addvisor (int, org.springframework.aip.advisor) Throws org.SpringFramework.aP.framework.aPConfigeXception; void addadvisor (ORG.Sprin gframework.aop.advisor) Throws org.SpringFramework.aop. framework.aPConfigeXception; void SetTargetsource (ORG .springframework.aop.targetsource); ORG.SpringFramework.aop.Targetsource GetTARGETSource (); d (); Boolean IsinterfaceProxied (java.lang.class); Boolean Removeadvisor (org.SpringFramework.aP. advisor );; Boolean SOR, ORG.SpringFramework.aP.Advisor) Throws org.SpringFramework.aop.framework.aPConfigeXception; void addAdvice (ORG.AOPALLIANCE.AOP.ADVICE) Throws org.SpringFramework.aP.framework.aPConfigexception; void addvice (int, org.aopalliance.aop.advic e) Throws org.Springframework.aP.framework.aPConfigeXception; .aop.advice); java.lang.string toproxyconfigstring (); Boolean isfrozen (); void setexposeProxy (Boolean);
策略模式
策略模式原理
策略模式顾名思义就是做某事的策略,这在编程上通常是指完成某个操作可能有多种方法,这些方法各有千秋,可能有不同的适应的场合,然而这些操作方法都有可能用到。各一个操作方法都当作一个实现策略,使用者可能根据需要选择合适的策略。
下面是策略模式的结构:
图23.策略模式的结构
Context:使用不同策略的环境,它可以根据自身的条件选择不同的策略实现类来完成所要的操作。它持有一个策略实例的引用。创建具体策略对象的方法也可以由他完成。
◆Strategy:抽象策略,定义每个策略都要实现的策略方法
◆ConcreteStrategy:具体策略实现类,实现抽象策略中定义的策略方法
◆Spring中策略模式的实现
◆Spring中策略模式使用有多个地方,如Bean定义对象的创建以及代理对象的创建等。这里主要看一下代理对象创建的策略模式的实现。
前面已经了解Spring的代理方式有两个Jdk动态代理和CGLIB代理。这两个代理方式的使用正是使用了策略模式。它的结构图如下所示:
图24.Spring中策略模式结构图
在上面结构图中与标准的策略模式结构稍微有点不同,这里抽象策略是AopProxy接口,Cglib2AopProxy和JdkDynamicAopProxy分别代表两种策略的实现方式,ProxyFactoryBean就是代表Context角色,它根据条件选择使用Jdk代理方式还是CGLIB方式,而另外三个类主要是来负责创建具体策略对象,ProxyFactoryBean是通过依赖的方法来关联具体策略对象的,它是通过调用策略对象的getProxy (ClassLoaderclassLoader)方法来完成操作。
สรุป
本文通过从Spring的几个核心组件入手,试图找出构建Spring框架的骨骼架构,进而分析Spring在设计的一些设计理念,是否从中找出一些好的设计思想,对我们以后程序设计能提供一些思路。接着再详细分析了Spring中是如何实现这些理念的,以及在设计模式上是如何使用的。