คำนำ
ทุกวันนี้แอปพลิเคชั่น Java เกือบทั้งหมดเช่น Tomcat, Struts2, Netty ฯลฯ ซึ่งเราคุ้นเคยไม่สามารถนับได้
เพื่อตอบสนองความเป็นสากลไฟล์การกำหนดค่ามีให้สำหรับผู้ใช้ในการปรับแต่งฟังก์ชั่น
แม้จะมีเฟรมเวิร์กเครือข่ายบางอย่างเช่น Netty ที่มีการกำหนดค่าเกือบทั้งหมดและเรามักจะเรียกซอฟต์แวร์ดังกล่าวว่า "สถาปัตยกรรม Microker"
ไม่ว่าคุณจะกำหนดค่าอะไรมันคือสิ่งที่มันเป็น
มันคือสิ่งที่คุณกำหนดค่าให้เป็น
รูปแบบไฟล์การกำหนดค่าที่พบมากที่สุดคือ XML คุณสมบัติและไฟล์อื่น ๆ
บทความนี้กล่าวถึงสถานการณ์ที่พบบ่อยที่สุดและทั่วไปในการโหลดการกำหนดค่าซึ่งคือการแมปไฟล์การกำหนดค่าลงในวัตถุ POJO ใน Java
และอภิปรายวิธีการใช้วิธีการโหลดที่แตกต่างกัน ตัวอย่างเช่นการกำหนดค่าบางอย่างจะถูกโหลดจากไฟล์ XML ในเครื่องในขณะที่การกำหนดค่าบางอย่างจำเป็นต้องโหลดจากไฟล์คุณสมบัติท้องถิ่นและอื่น ๆ ดังนั้นการกำหนดค่าบางอย่างจำเป็นต้องโหลดผ่านเครือข่าย
วิธีการใช้กลไกการโหลดการกำหนดค่าดังกล่าวเพื่อให้หลังจากเรามีกลไกนี้การกำหนดค่าการโหลดรหัสจะไม่แพร่กระจายไปทุกที่และสามารถปรับขนาดได้และสามารถจัดการได้
กำหนดค่าตัวโหลด
ก่อนอื่นเราต้องใช้ตัวโหลดการกำหนดค่าและตัวโหลดการกำหนดค่านี้สามารถมีวิธีการโหลดที่แตกต่างกันมากมาย ดังนั้นเราจึงใช้อินเทอร์เฟซเพื่ออธิบายดังนี้:
/** * * * @author bean * @date 21 มกราคม 2016 เวลา 11:47:12 น
แต่ทำไมเราต้องประกาศทั่วไป <T> ในอินเทอร์เฟซนี้?
เห็นได้ชัดว่าเมื่อเราต้องการใช้ตัวโหลดการกำหนดค่าคุณต้องบอกตัวโหลดการกำหนดค่านี้ว่าผลลัพธ์ที่คุณต้องได้รับหลังจากโหลด
ตัวอย่างเช่นหากคุณต้องการโหลดการกำหนดค่าและรับวัตถุ AppleConFig คุณสามารถใช้อินเทอร์เฟซที่กำหนดไว้ด้านบน:
iconfigloader <PapteconFig> loader = ใหม่ apperConFigLoader <PapteconFig> (); AppleConfig config = loader.load ();
ดังนั้นคุณจึงแปลงข้อมูลในไฟล์การกำหนดค่าเป็นวัตถุ AppleConFig และคุณสามารถรับอินสแตนซ์ออบเจ็กต์ AppleConfig นี้ได้
จนถึงตอนนี้ดูเหมือนว่าตราบใดที่ Appleconfigloader ของเราใช้แรงงานเฉพาะของวิธีการโหลดไฟล์การกำหนดค่าเราสามารถโหลดการกำหนดค่าได้อย่างง่ายดาย
อาจกล่าวได้ว่า แต่ไม่ใช่ว่าการกำหนดค่าอาจโหลดในรูปแบบที่แตกต่างกันเช่นการโหลดผ่านคุณสมบัติ DOM, SAX หรือการโหลดผ่านไลบรารีโอเพนซอร์สของบุคคลที่สาม
ดังนั้นนอกเหนือจากการกำหนดค่าตัวโหลดแล้วเรายังต้องการบทบาทอื่นผู้ให้บริการการกำหนดค่าวิธีการโหลด เรียกมันว่า iconfigprovider
กำหนดค่าผู้ให้บริการวิธีการโหลด
ผู้ให้บริการวิธีการโหลดการกำหนดค่าสามารถให้วิธีการโหลดไปยังตัวโหลดการกำหนดค่าในคำอื่น ๆ ให้วัตถุไปยังตัวโหลดการกำหนดค่า
หากโหลดผ่าน DOM ผู้ให้บริการจะให้วัตถุเอกสารไปยังตัวโหลด
หากโหลดผ่านคุณสมบัติผู้ให้บริการจะให้วัตถุคุณสมบัติให้กับตัวโหลด หากโหลดผ่านวิธีการที่จัดทำโดยไลบรารีคลาสบุคคลที่สามเช่น Apache-Commons-Digester3 (การโหลดการกำหนดค่า Tomcat) ผู้ให้บริการจะให้วัตถุบ่อหมักให้กับผู้ให้บริการโหลดเดอร์ นั่นคือทั้งหมดที่ให้วัตถุที่จำเป็นในการกำหนดค่าตัวโหลด แต่มันไม่ได้มีส่วนร่วมในการกำหนดค่าการโหลด
เราใช้ IconFigProvider อินเทอร์เฟซเพื่อกำหนดผู้ให้บริการนี้
/** * * * @author bean * @date 21 มกราคม 2016 เวลา 11:54:28 น. * @version 1.0 * */ส่วนต่อประสานสาธารณะ iconfigprovider <t> {/** * จัดเตรียมแหล่งที่มาสำหรับการโหลด config * * @return * @throws configexception */สาธารณะ ทำไมถึงมี <t> ที่นี่เพื่อประกาศทั่วไป?
หากคุณต้องการผู้ให้บริการอย่างน้อยคุณต้องบอกผู้ให้บริการว่าควรให้อะไร
ดังนั้นสิ่งที่ผู้ให้บริการจะได้รับจะถูกกำหนดโดยสิ่งนี้
ในเวลาเดียวกันเราสามารถสร้างโรงงานก่อนและปล่อยให้มันผลิตผู้ให้บริการเฉพาะ:
/** * * * @author bean * @date 21 มกราคม 2016 เวลา 11:56:28 น. * @version 1.0 * */คลาสสาธารณะ configproviderfactory {private configproviderfactory () {โยน unsupportedoperationexception ใหม่ ("ไม่สามารถเริ่มต้นคลาสโรงงาน:" + getClass () } public iconfigProvider <Ocporive> createDocumentProvider (String FilePath) {ส่งคืน DocumentProvider ใหม่ (FilePath); } public iconfigprovider <Properties> createPropertiesProvider (String filePath) {ส่งคืนคุณสมบัติใหม่ PropertiesProvider (FilePath); } public iconfigprovider <Gugester> credentIgesterprovider (String filepath) {ส่งคืน DigesterProvider ใหม่ (FilePath); -คุณสามารถเริ่มใช้ตัวโหลดการกำหนดค่าเฉพาะได้หรือไม่?
ยังไม่โอเค!
ณ จุดนี้สมมติว่าเรามีไฟล์กำหนดค่าที่เรียกว่า Apple.xml และเราจำเป็นต้องโหลด Apple.xml นี้ลงในวัตถุ AppleConfig ผ่าน DOM
ดังนั้นก่อนอื่นฉันต้องการสร้างผู้ให้บริการที่สามารถให้เอกสารผ่านโรงงานผู้ให้บริการ จากนั้นฉันได้รับผู้ให้บริการนี้และฉันสามารถเรียกวิธีการให้ของมันเพื่อรับวัตถุเอกสาร
ด้วยวัตถุเอกสารฉันสามารถเริ่มโหลดการกำหนดค่า
อย่างไรก็ตามหากคุณต้องการโหลด bananaconfig, pearconfig ...... ขั้นตอนก็เหมือนกัน ดังนั้นเราจึงต้องมีคลาสนามธรรมเพื่อใช้พฤติกรรมทั่วไปเริ่มต้นบางอย่าง
/** * * * @author bean * @date 21 มกราคม 2016 เวลา 11:59:19 น. * @version 1.0 * */บทคัดย่อระดับสาธารณะ AbstractConfigloader <t, u> ใช้ไอคอน iConfigloader <t> ได้รับการป้องกัน AbstractConfigloader (IconFigProvider <u> ผู้ให้บริการ) {this.provider = ผู้ให้บริการ; } / * * @See ICONFIGLOADER#load () * / @Override สาธารณะ t load () พ่น configException {return load (getProvider (). ให้ ()); } บทคัดย่อสาธารณะ T LOAD (U Loadersource) พ่น configException; IconFigProvider ที่ได้รับการป้องกัน <u> getProvider () {return this.provider; -ตัวโหลดการกำหนดค่าแต่ละตัวมีตัวสร้างพารามิเตอร์ที่ได้รับผู้ให้บริการ
ทั่วไประบุว่าฉันต้องการโหลด appleconfig หรือ bananconfig <u> ทั่วไประบุว่าวิธีการโหลดใดที่จะโหลดเป็นเอกสารคุณสมบัติหรืออย่างอื่น
ตัวอย่างการใช้งานจริง
มีตลาดการกำหนดค่าตลาดผัก. xml ซึ่งกำหนดค่าผลิตภัณฑ์ของตลาดผักรวมถึงผลิตภัณฑ์สองรายการ ได้แก่ แอปเปิ้ลและไข่
<markes> <parple> <color> สีแดง </color> <ราคา> 100 </ราคา> </sapple> <ged> <ed weight> 200 </eedion> </gg> </market>
นอกจากนี้ยังมีไฟล์การกำหนดค่าสำหรับชื่อของผู้บังคับบัญชาในแต่ละแผง, เจ้าของ. properties
พอร์ต 1 = Steve JobSport2 = Bill Gatesport3 = Kobe Bryant
มากำหนดคลาสต่อไปนี้ก่อน:
MarketConfig.java
/** * * * @author bean * @date 21 มกราคม 2016 เวลา 11:03:37 น. * @version 1.0 * */marketconfig คลาสสาธารณะ {Private Appleconfig Appleconfig; EggConfig Private EggConfig; Private Ownerfig OwnerConfig; Public AppleConfig getAppleConfig () {return apperconfig; } โมฆะสาธารณะ setappleConfig (apperConfig apperconfig) {this.appleConfig = appleConfig; } public EggConfig getEggConfig () {return eggConfig; } โมฆะสาธารณะ seteggconfig (EggConfig EggConfig) {this.eggConfig = EggConfig; } Public OwnerConfig getOwnerConfig () {return OwnerConfig; } โมฆะสาธารณะ setownerConfig (OwnerConfig OwnerConfig) {this.OwnerConfig = OwnerConfig; -Appleconfig.java
/** * * * @author bean * @date 21 มกราคม 2016 เวลา 11:03:45 น. * @version 1.0 * */คลาสสาธารณะ Appleconfig {ราคา int ส่วนตัว; สีสตริงส่วนตัว โมฆะสาธารณะ setPrice (ราคา int) {this.price = ราคา; } public int getPrice () {return this.price; } โมฆะสาธารณะ setColor (สีสตริง) {this.color = color; } สตริงสาธารณะ getColor () {return this.color; -EggConfig.java
/** * * * @author bean * @date 21 มกราคม 2016 เวลา 11:03:58 PM * @version 1.0 * */คลาสสาธารณะ EggConfig {น้ำหนัก int ส่วนตัว; โมฆะสาธารณะ setweight (น้ำหนัก int) {this.weight = น้ำหนัก; } public int getweight () {return this.weight; - OwnerConfig.java
/** * * * @author bean * @date 21 มกราคม 2016 เวลา 11:04:06 น. * @version 1.0 * */คลาสสาธารณะ anderconfig {แผนที่ส่วนตัว <สตริงสตริง> เจ้าของ = ใหม่ hashmap <สตริงสตริง> (); โมฆะสาธารณะ addowner (พอร์ตสตริง, เจ้าของสตริง) {this.owner.put (portname, เจ้าของ); } สตริงสาธารณะ getOwnerByportName (พอร์ตสตริง) {return.owner.get (PortName); } แผนที่สาธารณะ <สตริง, สตริง> getOwners () {return collections.unmodifiablemap (this.Owner); - มีวิธีการโหลดการกำหนดค่าสองวิธีสำหรับตัวอย่างนี้คือ DOM และวิธีการโหลดคุณสมบัติ
ดังนั้นผู้ให้บริการของเราจำเป็นต้องสร้างโรงงานที่มีผู้ให้บริการสองราย
และตัวโหลดการกำหนดค่าสองตัวต้องถูกกำหนดคือ:
OwnerConfigloader
/** * * * @author bean * @date 21 มกราคม 2016 เวลา 23:24:50 น. * @version 1.0 * */คลาสสาธารณะ OwnererConfigloader ขยายบทคัดย่อ AbstractConfigloader <OwnerConFig, Properties> {/** ** @param } / * * @See AbstractConfigloader#load (java.lang.Object) * / @Override Public Public OwnerConfig Load (Properties Props) พ่น configexception {OwnerConfig OwnerConfig = ใหม่ OwnerConFig (); / ** * ใช้อุปกรณ์ประกอบฉากเพื่อตั้งค่าคุณสมบัติของ OwnerConfig * * รหัสที่นี่ถูกละเว้น */ return OwnerConfig; -จากนั้นก็มี MarketConfigloader
นำเข้า org.w3c.dom.document;/** * * @author bean * @date 21 มกราคม 2016 เวลา 23:18:56 น. * @version 1.0 * */MarketConfigloader ระดับสาธารณะ Super (ผู้ให้บริการ); } / * * AbstractConfigloader#load (java.lang.Object) * / @Override Public MarketConfig Load (เอกสารเอกสาร) พ่น configexception {MarketConfig MarketConfig = ใหม่ MarketConfig (); appleConfig appleconfig = ใหม่ apperconfig (); EggConfig EggConfig = New EggConfig (); / ** * ประมวลผลเอกสารที่นี่จากนั้นคุณจะได้รับ * appleconfig และ EggConfg * * รหัสที่นี่ถูกละเว้น */ marketConfig.setAppleConfig (apperConfig); MarketConfig.seteggconfig (EggConfig); / ** * เนื่องจาก OwnerConfig ต้องการคุณสมบัติในการโหลดจึงไม่ใช่ XML * ดังนั้นที่นี่เราจำเป็นต้องสร้าง OwnerConfigloader ใหม่และมอบหมายให้โหลด OwnerConfig */ OwnerConfigloader OwanderConFigloader = new OwnerConFigloader OwnerConfig OwnerConfig = OwnerConfigloader.load (); MarketConfig.setOwnerConfig (OwnerConfig); Return MarketConfig; -ถ้าอย่างนั้นเราจะได้รับตลาดในระดับแอปพลิเคชันได้อย่างไร?
MarketConfigloader MarketConfigloader = ใหม่ MarketConfigloader (configProviderFactory.CreatedocumentProvider (your_file_path));
MarketConfig MarketConfig = MarketConfigloader.load ();
อาจมีสถานที่ที่ผู้คนอาจประหลาดใจ เห็นได้ชัดว่ามีคลาสการกำหนดค่าสี่คลาสดังนั้นทำไมจึงมีตัวโหลดการกำหนดค่าเพียงสองตัวเท่านั้น?
เนื่องจาก MarketConfig, EggConfig และ AppleConfig ทั้งหมดถูกโหลดจากไฟล์การกำหนดค่า XML เดียวกันตราบใดที่ใช้วัตถุเอกสารจึงสามารถโหลดผ่าน MarketConfigloader ได้
OwnerConfig เป็นวิธีการโหลดที่แตกต่างกันดังนั้นจึงจำเป็นต้องมีตัวโหลดอีกตัว
จบ
กลไกการโหลดการกำหนดค่าที่เสนอในบทความนี้ไม่สามารถช่วยโหลดการกำหนดค่าได้ สิ่งนี้ควรถูกทิ้งไว้กับ DOM, SAX และไลบรารีโอเพ่นซอร์สอื่น ๆ เช่น DOM4J และ DIGESTER
อย่างไรก็ตามกลไกการโหลดการกำหนดค่าที่เสนอในบทความนี้สามารถทำให้กลไกการโหลดการกำหนดค่ามีความยืดหยุ่นและง่ายต่อการขยายและสามารถรวมวิธีการโหลดการกำหนดค่าหลายวิธีรวมเข้ากับกลไกเดียวและเล่นจุดของตัวเอง
ในความเป็นจริงซอฟต์แวร์บางตัวมักจะต้องโหลดการกำหนดค่าจากไฟล์การกำหนดค่าในหลายรูปแบบในเวลาเดียวกันเช่น struts2 และซอฟต์แวร์มิดเดิลแวร์ฐานข้อมูลโอเพ่นซอร์สในประเทศที่ฉันได้ทำการวิจัยและอาเจียนเลือดเมื่อเร็ว ๆ นี้
หากไม่มีกลไกการโหลดการกำหนดค่าที่สมบูรณ์รหัสจะกระจัดกระจายมากขึ้นและบำรุงรักษาน้อยกว่า มันสามารถทำให้คนอาเจียนเลือดได้อย่างง่ายดาย