ฉันเชื่อว่าไม่มีใครไม่รู้เกี่ยวกับ SSH Struts2+Spring+Hibernate, สถาปัตยกรรม "พื้นฐาน" ของการพัฒนาองค์กรทำไมพื้นฐานถึงมีเครื่องหมายคำพูด? เพราะรากฐานนี้เป็นสิ่งที่หลายคนคิด พื้นฐานที่สุดคือ servlet สถาบันการฝึกอบรมหลายแห่งไม่ได้สอนพื้นฐานมากมายและพวกเขาจะมีสามกรอบหลักโดยตรง SSH หรือ SSI ซึ่งทำให้หลายคนคิดว่าการพัฒนา Javaweb ต้องมีเฟรมเวิร์ก หากไม่มีกรอบมันก็เหมือนกับการสูญเสียมือ ไม่มีอันตรายใด ๆ ในสามกรอบหลักและพวกเขาใช้งานได้จริง หลาย บริษัท กำลังใช้พวกเขาและสามารถเริ่มพัฒนาได้โดยตรง แต่หลังจากสำเร็จการศึกษาฉันคิดว่าฉันไม่ได้ใช้สามเฟรมเวิร์กหลักมาเป็นเวลานาน ฤดูใบไม้ผลิมีประโยชน์โดยเฉพาะ SpringMVC มันให้ความรู้สึกที่น่าตื่นเต้นกว่าการใช้งานมากกว่า struts2 ที่จริงแล้วถ้าคุณคิดเกี่ยวกับมันฤดูใบไม้ผลิจะดูดซับข้อดีบางอย่างของเสาและด้วยสิ่งที่สงบสุขมันรู้สึกสนุกมากขึ้น แต่วันนี้เราจะไม่ดู SpringMVC และเราจะใช้เวลาในการดูส่วนที่หรูหราของ SpringMVC ในอนาคต
ไปถึงจุด SSH ได้รับการอัปเดตเวอร์ชันดังนั้นฉันยังต้องการพูดคุยเกี่ยวกับเวอร์ชันที่นี่มิฉะนั้นเพื่อนจำนวนมากจะดุฉัน ฉันใช้ 2.3.4 สำหรับ struts2 ฤดูใบไม้ผลิเป็น 3.2.2 ล่าสุดและไฮเบอร์เนตคือ 4.1.9 ซึ่งค่อนข้างใหม่
ก่อนที่จะเข้าสู่รหัสก่อนอื่นให้เข้าใจบทบาทที่เล่นโดยสามเฟรมเวิร์กหลัก
1) Struts: ทำไมเราถึงใช้ Struts? อะไรคือความแตกต่างระหว่างพวกเขากับ Servlets? ในความเป็นจริงเรายังสามารถทำ MVC ได้โดยไม่ต้องมีเสา แต่อาจจะหดหู่มากขึ้นในไฟล์การกำหนดค่า struts ส่วนใหญ่ช่วยให้เราตระหนักถึงฟังก์ชั่นของการแจกจ่ายแบ่งคำขอเฉพาะของเราออกเป็นคลาสเฉพาะและช่วยให้เราตั้งค่าคุณสมบัติ (ซึ่งทำผ่าน actionform ใน struts1.x) Struts2 มีความคืบหน้าอย่างมากเมื่อเทียบกับ struts1 มันตั้งค่าโดยอัตโนมัติไม่จำเป็นต้องมีการใช้งานหรือคลาสมรดกและมีชุดของแนวคิดเช่นโซ่คำขอ เนื่องจากสิ่งเหล่านี้ไม่ได้ใช้มากฉันจะไม่ทำให้คุณเข้าใจผิดพี่น้องดังนั้นฉันจะไม่พูดอะไรมากมาย
2) ฤดูใบไม้ผลิ: ฉันเชื่อว่า Daimyo ของฤดูใบไม้ผลิไม่ใช่ Java ไม่รู้ หลายคนควรเรียนรู้เกี่ยวกับฤดูใบไม้ผลิผ่าน IOC ในตอนแรกหรือพวกเขาไม่รู้อะไรเลยเพียงสามกรอบหลัก SSH มา มันไม่สำคัญว่าเมื่อเราใช้สามเฟรมเวิร์กหลักสปริงส่วนใหญ่เป็นเครื่องมือสำหรับคลาสลิงค์ เมื่อรวมกับเฟรมเวิร์กสำคัญอีกสองอันคือ SSI และ SSH พวกเขาเหมือนกัน ฤดูใบไม้ผลิมีเพียงเครื่องมือที่จะทำให้เราสะดวกมากขึ้นในการใช้เฟรมเวิร์กหลักสามประการ แน่นอนว่าโปรแกรมจำนวนมากในการผสมผสานกรอบการทำงานยังขึ้นอยู่กับ IOC ของฤดูใบไม้ผลิและแน่นอนว่าเราจะใช้ธุรกรรม AOP และสิ่งที่ก้าวหน้ากว่านี้ขึ้นอยู่กับความต้องการ หากมีข้อกำหนดการบันทึกและข้อกำหนดการสกัดกั้นใด ๆ จะเป็นการดีกว่าที่จะใช้ AOP เพื่อให้บรรลุ
3) ไฮเบอร์เนต: ไฮเบอร์เนตยังมีชื่อเสียงในโลกชวาซึ่งเป็นมาตรฐานของ ORM มันให้แคชระดับหนึ่งและระดับสองและยังมี HQL เราใช้อะไรเมื่อรวมสามเฟรมเวิร์กหลัก? แน่นอนว่ามันเป็นฟังก์ชั่นหลักของการทำแผนที่ ORM ดังนั้นเราจะไม่พิจารณาแคชในขณะนี้ หลายคนไม่เคยพิจารณาว่าทำไมพวกเขาถึงต้องการ ORM ในความเป็นจริงส่วนใหญ่เป็นเพราะความขัดแย้งระหว่างเขตข้อมูลและชั้นเรียน หากคุณใช้ JDBC เพื่อใช้งานและตั้งค่าฟิลด์ทีละฟิลด์คุณอาจจะบ้าหลังจากทำมันเป็นเวลานานดังนั้น ORM จึงปรากฏขึ้นในเวลานี้
สามกรอบหลักมีหน้าที่รับผิดชอบต่อสิ่งต่อไปนี้: struts2 - รับผิดชอบในการร้องขอการส่งต่อและการประมวลผลแบบฟอร์มที่สอดคล้องกันองค์กรสปริง - ชั้นเรียน (เช่น IOC) จัดการการกระทำเดิมที่จัดการโดย Struts2 เป็นถั่วและไฮเบอร์เนต - ORM แผนที่
หลังจากทำความเข้าใจกับการแบ่งงานทั่วไปของแรงงานแน่นอนเราเริ่มเขียนโค้ด สิ่งที่ลำบากที่สุดเกี่ยวกับสามกรอบหลักคือแพ็คเกจ หลายคนชอบใช้ myeclipse เป็นหลักเพราะมันสามารถช่วยเรานำเข้าแพ็คเกจของสามกรอบหลัก แต่ขอแนะนำว่าสามเณรไม่ควรใช้สิ่งนั้น ก่อนอื่น Myeclipse มีโครงสร้างโครงการของตัวเอง เมื่อคุณได้รับคู่มือ Eclipse คุณต้องตั้งค่าบางแง่มุมของโครงการซึ่งจะทำให้ผู้อื่นไม่สะดวก ประการที่สอง Myeclipse ไม่ค่อยใช้มันใน บริษัท ดังนั้นจึงเป็นการดีกว่าที่จะคุ้นเคยกับ Eclipse หรือจะดีถ้าคุณชอบความคิด
แพ็คเกจที่จำเป็นสำหรับ struts2 มีดังนี้: antlr, asm, xwork, struts2-core, ognl, การบันทึกทั่วไป, fileupload ทั่วไป, struts-spring-plugin อาจมีเพียงไม่กี่และมันอาจไม่ได้เขียนเต็ม คุณสามารถเพิ่มข้อผิดพลาดเมื่อเริ่มต้น ไม่แนะนำให้โยนแพ็คเกจทั้งหมดออกไปทันทีที่คุณเริ่ม แพ็คเกจบางอย่างในสามเฟรมเวิร์กมีความขัดแย้ง
แพ็คเกจที่ต้องการโดย Spring3 มีดังนี้: Spring-beans, Spring-Core, Spring-Context, Spring-Context-Support, Spring-Expression, Spring-orm (เราใช้สามเฟรมเวิร์กหลักและต้องการการสนับสนุน ORM), Spring-Web, Spring-TX (เราใช้ธุรกรรม แต่ไม่เกี่ยวข้องกับตัวอย่าง)
แพ็คเกจที่ต้องการโดย Hibernate4 มีดังนี้: Hibernate ดาวน์โหลดแพ็คเกจ JAR ทั้งหมดในโฟลเดอร์ที่ต้องการในแพ็คเกจ
เช่นเดียวกับแพ็คเกจเหล่านี้มันยังคงเป็นสิ่งเดียวกัน ไม่แนะนำให้วางแพ็คเกจทั้งหมดทันทีที่คุณเริ่มต้นเนื่องจากแพ็คเกจบางอย่างในสามเฟรมเวิร์กมีความขัดแย้งดังนั้นเพียงเพิ่มตามความเหมาะสมเมื่อจำเป็น เมื่อ classnotfound ปรากฏขึ้นให้วางแพ็คเกจ JAR ที่เกี่ยวข้องในไดเรกทอรี LIB
การเตรียมการสิ้นสุดที่นี่และเราเริ่มต้นอย่างเป็นทางการ
1) ก่อนอื่นเราต้องใช้ struts2 และเราต้องทำให้มันสกัดกั้นคำขอ
<silter> <filter-name> struts2 </filter-name> <filter-class> org.apache.struts2.dispatcher.ng.filter.strutsprepareandexecutefilter </filter--class> </filter> </ตัวกรองการทำแผนที่>
รหัสนี้อนุญาตให้ struts สกัดกั้นคำขอทั้งหมด แน่นอนว่าไม่ได้หมายความว่าคำขอทั้งหมดจะถูกสกัดกั้นโดยฤดูใบไม้ผลิ นอกจากนี้เรายังสามารถกำหนดค่า struts.xml เพื่อสกัดกั้นชื่อคำต่อท้ายที่เฉพาะเจาะจง โดยทั่วไปแล้วมันเป็นการกระทำ ดังนี้:
<constant name = "strutsObjectFactory" value = "Spring" /> <constant name = "struts.action.extension" value = "action" />
struts.action.extension กำหนดค่าชื่อต่อท้ายเริ่มต้นสำหรับการสกัดกั้นเพื่อให้ชื่อต่อท้ายจะถูกตรวจสอบเมื่อสกัดกั้นและสิ่งที่ตรงกันจะถูกส่งต่อโดย struts struts.ObjectFactory หมายความว่าระดับการประมวลผลการส่งต่อ struts ถูกส่งมอบให้กับฤดูใบไม้ผลิสำหรับการจัดการนั่นคือมันได้รับการจัดการเป็นถั่ว
2) โดยปกติเมื่อเราใช้ฤดูใบไม้ผลิโดยตรงเราจะเรียก *ApplicationContext แต่ตอนนี้เราอยู่ในเว็บดังนั้นเราจึงไม่สามารถเรียกได้ด้วยตนเอง ในความเป็นจริงสปริงมีวิธีการโทรในสถานการณ์เว็บด้วยเซิร์ฟเล็ต (ฉันไม่ได้ใช้สิ่งนี้ฉันไม่รู้วิธีใช้) ผู้ฟัง servlet สำหรับเซิร์ฟเวอร์แอปพลิเคชันที่ไม่รองรับตัวกรอง แต่ตอนนี้เราใช้ฟัง
<Sistener> <Sistener-Lass> org.springFramework.web.context.contextloaderListener </listener-class> </listener>
ในกรณีนี้กรณีส่วนใหญ่เมื่อฤดูใบไม้ผลิจำเป็นต้องรวมกับเฟรมเวิร์กอื่น ๆ เมื่อเราใช้ SpringMVC เท่านั้นเราสามารถกำหนดค่า DispatchERServlet โดยตรงเพื่อแทนที่ Servlet Struts ด้านบน มาดูรายละเอียดเมื่อใช้ SpringMVC ในภายหลัง
ในกรณีนี้ไฟล์ ApplicationContext.xml ในไดเรกทอรี Web-Inf โดยทั่วไปจะถูกโหลด เมื่อชื่อไฟล์ของคุณไม่ใช่นี้หรือเส้นทางไม่อยู่ที่นี่คุณสามารถกำหนดค่าคุณสมบัติ configcontextpath
<context-param> <param-Name> configContextPath </param-name> <param-value> web-inf/applicationcontext.xml </param-value> </context-param>
รองรับการใช้ ClassPath: คำนำหน้า ฯลฯ ฉันจะไม่พูดถึงที่นี่คุณสามารถอ่านไฟล์การกำหนดค่าของสปริงในรายละเอียด ด้วยวิธีนี้เราได้รวม struts และฤดูใบไม้ผลิจริง ๆ แต่เรายังไม่ได้ทำการกำหนดค่าถั่วและการส่งต่อ struts
3) ในฐานะ ORM ไฮเบอร์เนตได้รับการจัดการโดยฤดูใบไม้ผลิในเวลานี้ ฤดูใบไม้ผลิให้ LocalSessionFactory โปรดทราบว่าคลาสนี้ Hibernate3 และ 4 นั้นแตกต่างกันไปในฤดูใบไม้ผลิมีสองรายการ การกำหนดค่าต่อไปนี้อยู่ใน ApplicationContext.xml
<bean id = "sessionfactory"> <property name = "dataSource" ref = "dataSource"/> <property name = "MappingResources"> <list> </list> </property> <property name = "hibernateProperties">
ในความเป็นจริงการกำหนดค่าคล้ายกับในไฮเบอร์เนตดังนั้นฉันจะไม่พูดถึงรหัสเฉพาะที่นี่
4) ในอดีตเมื่อฤดูใบไม้ผลิ 2.5.x เราใช้ hibernatedaosupport มากที่สุด แต่ฤดูใบไม้ผลิ 3.x ไม่ได้ให้การสนับสนุนนี้ในตอนแรก เราจำเป็นต้องใช้เซสชันดั้งเดิมเพื่อใช้งาน (เพียงแค่ฉีด SessionFactory) แต่มีปัญหาจริง ๆ ที่นี่ หากเราเปิดและปิดการเชื่อมต่อสำหรับแต่ละคำขอมันจะใช้ทรัพยากรมากขึ้น แต่ถ้าเราไม่ปิดการเชื่อมต่อมันจะไม่ดีมาก ดังนั้นจึงมีโซลูชันการแลกเปลี่ยนและผู้จัดการเพื่อจัดการการเชื่อมต่อ ที่นี่ฤดูใบไม้ผลิมีการเปิดตัว OpenSessionInview ทุกครั้งที่มีการเปิดมุมมอง (โดยทั่วไปทุกคำขอ) เซสชั่นจะเปิดขึ้น เราจะเพิกเฉยต่อวิธีการจัดการภายในในตอนนี้
<silter> <silter-name> OpenSessionInviewFilter </filter-name> <filter-class> org.springframework.orm.hibernate4.support.opensessionInviewFilter </filter-class> <url-pattern>/*</url-pattern> </filter-mapping>
ที่นี่เรายังขอให้เขาสกัดกั้นคำขอทั้งหมด แน่นอนว่าสามารถกำหนดค่าให้สกัดกั้นการกระทำต่อท้ายการกระทำเท่านั้นดังนั้นจึงไม่จำเป็นต้องเสียทรัพยากร
5) โดยทั่วไปเฟรมเวิร์ก SSH ของเราถูกตั้งค่าและสิ่งต่อไปคือปัญหากับรหัส คุณจะต้องกำหนดค่าถั่วในไฟล์การกำหนดค่าสปริงหรือถ้าคุณชอบคำอธิบายประกอบคุณสามารถ @component (value = 'ชื่อถั่ว') โดยตรง แต่อย่าลืมเปิดใช้งานส่วนประกอบ-สแกนในไฟล์การกำหนดค่า
รหัสจะไม่ถูกเขียนในรายละเอียดดังนี้:
@Component (value = "userAction") คลาสสาธารณะ userAction {} <package name = "ผู้ใช้" ขยาย = "struts-default" namespace = "/ผู้ใช้"> <!-การเข้าสู่ระบบของผู้ใช้-> <action name = "login" method = "เข้าสู่ระบบ"> ในความเป็นจริงมันเพียงแค่ต้องปรับเปลี่ยนตัวชี้ในคลาสเป็น pointer bean
ฉันจะไม่โพสต์รหัสโดยละเอียดหลังจากทั้งหมดมันเป็นบทสรุป โดยทั่วไป SSH มีประโยชน์มากกว่าสำหรับรหัสข้อกำหนดของทีมเนื่องจากรหัสที่เขียนภายใต้ข้อกำหนดของกรอบงานโดยทั่วไปมีรูปแบบเฉพาะซึ่งดีกว่าสำหรับการบำรุงรักษาในอนาคต แต่สำหรับผู้เริ่มต้นขอแนะนำให้ไม่พึ่งพากรอบมากเกินไป หากคุณต้องใช้มันจริง ๆ คุณต้องเข้าใจโดยทั่วไปว่ากรอบนี้ทำอะไรสิ่งที่คุณต้องใช้ในสถานการณ์ใดและสถานการณ์ใดที่คุณไม่ควรใช้