เมื่อเราพัฒนาแอปพลิเคชันตามฤดูใบไม้ผลิเรามักจะวางการกำหนดค่าฐานข้อมูลในไฟล์คุณสมบัติ
บทสรุปของจุดความรู้ที่เกี่ยวข้องในการวิเคราะห์รหัส:
1. smandespacehandler parses เนมสเปซแบบกำหนดเองในไฟล์กำหนดค่า XML
2. concontextnamespacehandler parser ที่เกี่ยวข้องกับบริบทที่นี่กำหนดตัวแยกวิเคราะห์เฉพาะสำหรับการแยกวิเคราะห์ผู้ถือทรัพย์สิน-สถานที่
3.BEANDEFINITIONPARSER แยกวิเคราะห์ส่วนต่อประสานของคำจำกัดความถั่ว
4.BeanFactoryPostProcessor หลังจากโหลดคำจำกัดความของถั่วแล้วสามารถแก้ไขได้
.
มาดูการใช้งานเฉพาะก่อน
การใช้ทรัพย์สิน
กำหนดค่าไฟล์คุณสมบัติในไฟล์ XML
<? xml version = "1.0" การเข้ารหัส = "utf-8"?> <beans xmlns = "http://www.springframework.org/schema/beans" xmlns: xsi = "http://ww.w3.org/2001/xml xmlns: context = "http://www.springframework.org/schema/context" xsi: schemalocation = "http://www.springframework.org/schema/beans http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd "> <บริบท
ด้วยวิธีนี้ไฟล์ /src/main/resources/foo.properties จะโหลดโดยฤดูใบไม้ผลิ
หากคุณต้องการใช้ไฟล์การกำหนดค่าหลายไฟล์คุณสามารถเพิ่มฟิลด์คำสั่งซื้อเพื่อจัดเรียง
ใช้ PropertySource เพื่อกำหนดค่าคำอธิบายประกอบการกำหนดค่า
Spring 3.1 ได้เพิ่มคำอธิบายประกอบ @PropertySource เพื่ออำนวยความสะดวกในการเพิ่มไฟล์คุณสมบัติให้กับสภาพแวดล้อม
@configuration @propertySource ("classpath: foo.properties") คุณสมบัติระดับสาธารณะ withjavaconfig {@bean ทรัพย์สินคงที่สาธารณะแหล่งที่มาของสถานที่ให้บริการทรัพย์สินผู้ให้บริการทรัพย์สินที่อยู่อาศัย -การฉีดและการใช้คุณสมบัติ
1. ใช้คำอธิบายประกอบ @Value เพื่อรับใน Java
@Value ("$ {jdbc.url}") สตริงส่วนตัว jdbcurl;คุณยังสามารถเพิ่มค่าเริ่มต้น
@Value ("$ {jdbc.url: adefaulturl}") สตริงส่วนตัว jdbcurl;1. รับในไฟล์กำหนดค่า XML ของ Spring
<bean id = "dataSource"> <property name = "url" value = "$ {jdbc.url}" /> </ebean>การวิเคราะห์ซอร์สโค้ด
การโหลดข้อมูลการกำหนดค่าคุณสมบัติ
สปริงจะเริ่มต้นการเริ่มต้นคอนเทนเนอร์ผ่าน AbstractApplicationContext#Refresh เมื่อเริ่มต้นและในช่วงเวลานี้ LoadBeanDefinitions จะได้รับความไว้วางใจให้แยกวิเคราะห์ไฟล์การกำหนดค่า XML
ได้รับการป้องกันขั้นสุดท้าย Void RefreshBeanFactory () พ่น beansexception {ถ้า (hasbeanfactory ()) {destroybeans (); CloseBeanFactory (); } ลอง {DefaultListableBeanFactory beanfactory = createBeanFactory (); beanfactory.setserializationid (getid ()); CustomizeBeanFactory (beanfactory); LoadBeanDefinitions (beanfactory); ซิงโครไนซ์ (this.BeanFactoryMonitor) {this.beanfactory = beanfactory; }} catch (ioexception ex) {โยน applicationcontextexception ใหม่ ("I/O ข้อผิดพลาดการแยกวิเคราะห์แหล่งที่มาของถั่วสำหรับ" + getDisplayName (), ex); -LoadBeanDefinitions ผ่านการมอบหมายแบบเลเยอร์โดยเลเยอร์ค้นหา defaultBeandEfinitionDocumentReader#parsebeanDefinition เพื่อแยกวิเคราะห์ถั่วเฉพาะเจาะจง
Void ParsebeanDefinitions (Element Root, BeanDefinitionParserDelegate Delegate) {ถ้า (Delegate.isdefaultNamespace (root)) {nodelist nl = root.getChildNodes (); สำหรับ (int i = 0; i <nl.getLength (); i ++) {node node = nl.item (i); if (Node Instancef Element) {Element Ele = (Element) Node; if (delegate.isdefaultnamespace (ele)) {parsedefaultelement (ele, ผู้แทน); } else {Delegate.parSecustomelement (ELE); }}}} else {Delegate.parSecustomelement (root); - เนื่องจากนี่ไม่ใช่คำจำกัดความของคลาสมาตรฐานจึงได้รับความไว้วางใจจาก BeanDefinitionParserDelegate เพื่อแยกวิเคราะห์
ค้นหาโปรเซสเซอร์ที่เกี่ยวข้องผ่าน NamespaceHandler เพื่อค้นหา contextnamespaceHandler จากนั้นค้นหา PropertyPlaceHolderBeandEfinitionParser Parser การวิเคราะห์ผ่าน ID
@Override โมฆะสาธารณะ init () {// นี่คือตัวแยกวิเคราะห์ที่เรากำลังมองหา registerBeandEfinitionParser ("ผู้ถือทรัพย์สิน-สถานที่", PropertyPlaceHolderBeanDefinitionParser ()); RegisterBeanDefinitionParser ("Property-Override", ใหม่ PropertyOverrideBeanDefinitionParser ()); registerBeanDefinitionParser ("คำอธิบายประกอบ-Config", หมายเหตุใหม่ NENTATIONCONFIGBEANDEFINITIONPARSER ()); registerBeanDefinitionParser ("Component-Scan", ใหม่ ComponentsCanBeanDefinitionParser ()); registerBeanDefinitionParser ("โหลดเวลาโหลด", LoadTimeWeaverBeanDefinitionParser () ใหม่); RegisterBeanDefinitionParser ("Spring-Configured", SpringConfiguredBeanDefinitionParser () ใหม่); RegisterBeanDefinitionParser ("MBean-Export", ใหม่ MBeanExportBeanDefinitionParser ()); RegisterBeanDefinitionParser ("MBean-Server", MBeanServerBeandEfinitionParser ใหม่ ()); - PropertyPlaceHolderBeandEfinitionParser เป็นจุดสนใจของการวิเคราะห์รหัสรอบนี้
มาดูชั้นเรียนของผู้ปกครองกันเถอะ
1.BeanDefinitionParser
ใช้โดย DefaultBeanDefinitionDocumentReader เพื่อแยกวิเคราะห์แท็กส่วนบุคคล
มีเพียง API ที่แยกวิเคราะห์เท่านั้นที่มีการกำหนดองค์ประกอบของการแยกวิเคราะห์
อินเทอร์เฟซสาธารณะ beanDefinitionParser {beanDefinition parse (องค์ประกอบองค์ประกอบ, parsercontext parsercontext);} 2.ABSTRACTBEANDEFINITIONPARSER
การใช้งานบทคัดย่อเริ่มต้นของอินเทอร์เฟซ BeanDefinitionParser ฤดูใบไม้ผลินั้นดี มันมี API ที่สะดวกสบายมากมายที่นี่และใช้รูปแบบการออกแบบวิธีการเทมเพลตเพื่อให้ตะขอการใช้งานที่กำหนดเองสำหรับคลาสย่อย
ลองมาดูตรรกะการประมวลผลเฉพาะเมื่อแยกวิเคราะห์: โทรหา hook parseinternal parse
3. บทคัดย่อ
วิเคราะห์กำหนดคลาสแม่แบบนามธรรมของ beandefinition เดียว
ใน parseinternal, parse parentname, beanclass, แหล่งที่มา; และห่อหุ้มโดยใช้ beandefinitionbuilder
4. AbstractPropertyloadingBeanDefinitionParser
วิเคราะห์คุณสมบัติที่เกี่ยวข้องกับคุณสมบัติเช่นที่ตั้ง, คุณสมบัติ-รีฟ, การเข้ารหัสไฟล์, การสั่งซื้อ ฯลฯ
.
มีไม่กี่สิ่งที่จะจัดการที่นี่เพียงแค่ตั้งค่าโหมด inore-unresolvable และ system-preperties-mode
การโหลดไฟล์คุณสมบัติการสร้างอินสแตนซ์ของถั่ว
ต่อไปลองมาดูกันว่าถั่วนี้มีการสร้างอินสแตนซ์ การสร้างอินสแตนซ์ของชั้นเรียนทั่วไปมีสองประเภท หนึ่งในอินสแตนซ์เมื่อระบบ Singleton เริ่มต้นขึ้น อีกอันหนึ่งจะถูกสร้างอินสแตนซ์เมื่อ Non-Singleton (หรือ Singleton Lazy Loading) เมื่อ GetBean อินสแตนซ์
ทริกเกอร์ที่นี่คือผ่าน beanfcatorypostprocessor
BeanFactoryPostProcessor ปรับเปลี่ยนคำจำกัดความของถั่วก่อนการสร้างอินสแตนซ์ถั่ว ตัวอย่างเช่นตัวยึดสถานที่ในนิยามถั่วได้รับการแก้ไขที่นี่และคุณสมบัติที่เราใช้อยู่ตอนนี้ได้รับการแก้ไขที่นี่
สิ่งนี้ถูกนำมาใช้ผ่าน PostprocessorRegistrationDelegate#InvokeBeanFactoryPostProcessors
สแกน beanfactorypostprocessor ในคอนเทนเนอร์ค้นหาทรัพย์สินของผู้จัดหาสถานที่ให้บริการผู้จัดหางานที่ต้องการที่นี่และสร้างอินสแตนซ์ผ่าน getbean ของคอนเทนเนอร์
เป็นโมฆะที่ได้รับการป้องกัน InvokeBeanFactoryPostProcessors (configurableListableBeanFactory beanfactory) {postprocessorregistrationDelegate.invokeBeanFactoryPostProcessors (beanfactory, getBeanFactoryPostProcessors (); -หลังจากการสร้างอินสแตนซ์ของ PropertySourcesplaceHolderConfigurer เสร็จสมบูรณ์แล้วมันจะถูกเรียกใช้โดยตรงและโหลดข้อมูล
OrderComparator.sort (PriorityOrderEdPostProcessors); InvokeBeanFactoryPostProcessors (PriorityOrderEdPostProcessors, beanfactory);
ลองมาดูระบบมรดกของทรัพย์สิน SourcesplaceholderConfigurer
1. BeanFactoryPostProcessor
กำหนดอินเทอร์เฟซสำหรับการแก้ไขคุณสมบัติของนิยามถั่วในคอนเทนเนอร์ คลาสการใช้งานจะถูกสร้างอินสแตนซ์ก่อนที่จะใช้คลาสทั่วไปและคุณสมบัติของคลาสอื่น ๆ ได้รับการแก้ไข
เห็นได้ชัดว่าแตกต่างจาก BeanPostProcessor ซึ่งปรับเปลี่ยนอินสแตนซ์ของถั่ว
2. propertiesloadersupport
คลาสนามธรรมที่โหลดไฟล์คุณสมบัติ
ตรรกะการโหลดที่เฉพาะเจาะจงที่นี่คือการมอบความไว้วางใจให้กับ PropertiesLoadEutiluTils#fillproperties เพื่อนำไปใช้
3. ผู้จัดหาผู้จัดหางาน
การเปลี่ยนตำแหน่งผู้ถือครองในนิยามถั่วถูกนำมาใช้โดยคลาสนามธรรมนี้
ใช้ beanfactorypostprocessor#postprocessbeanfactory, ซ้ำผ่านคำจำกัดความของคลาสในคอนเทนเนอร์และแก้ไขมัน
วิธีการแก้ไขมันถูกนำไปใช้โดยการส่งไปยังคลาสย่อยผ่าน hook processproperties
4. PlaceHolderConfigurersupport
ใช้รูปแบบการออกแบบผู้เข้าชมเพื่ออัปเดตคุณสมบัติผ่าน BeanDefinitionVisitor และ StringValueresolver
StringValueresolver เป็นอินเทอร์เฟซที่แปลงข้อมูลประเภทสตริง การใช้งาน API ที่อัพเดทคุณสมบัติอย่างแท้จริงอยู่ในนั้น
PropertyPlaceHolderHelper#parsestringValue
5. Propertysourcesplaceholderconfigurer
แทนที่กระบวนการแยกวิเคราะห์ API PostprocessorBeanFactory API
ข้างต้นเป็นเนื้อหาทั้งหมดของบทความนี้ ฉันหวังว่ามันจะเป็นประโยชน์ต่อการเรียนรู้ของทุกคนและฉันหวังว่าทุกคนจะสนับสนุน wulin.com มากขึ้น