ในส่วนก่อนหน้านี้ "การต่อสู้ครั้งแรกของ SSH Framework Online Mall Project: การรวมกันของ Struts2, Hibernate4.3 และ Spring4.2" เราได้สร้างสภาพแวดล้อมการพัฒนาสำหรับ Struts2, Hibernate และ Spring และรวมเข้าด้วยกัน ส่วนนี้ส่วนใหญ่เสร็จสิ้นการเพิ่มเติมพื้นฐานการลบการดัดแปลงและการค้นหารวมถึงการสกัดบริการ DAO และการกระทำ
1. การสกัดชั้นบริการ
ในส่วนก่อนหน้าเราเพียงแค่เขียนวิธีการบันทึกและอัปเดตในเลเยอร์บริการ ที่นี่เราเริ่มปรับปรุงรหัสในส่วนนี้แล้วแยกรหัสในเลเยอร์บริการ
1.1 ปรับปรุงเลเยอร์หมวดหมู่
การทำงานของฐานข้อมูลไม่มีอะไรมากไปกว่าการเพิ่มลบการแก้ไขและตรวจสอบ ก่อนอื่นให้ปรับปรุงอินเทอร์เฟซและการใช้งานเลเยอร์หมวดหมู่บริการ:
// CategoryService Interface Interface Public Interface Explates Baseservice <หมวดหมู่> {โมฆะสาธารณะบันทึก (หมวดหมู่หมวดหมู่); // แทรกการอัปเดตโมฆะสาธารณะ (หมวดหมู่); // อัปเดตโมฆะสาธารณะลบ (ID int); // ลบหมวดหมู่สาธารณะรับ (INT ID); // รับรายการสาธารณะหมวดหมู่ <หมวดหมู่> แบบสอบถาม (); // รับหมวดหมู่ทั้งหมด} การใช้งานเฉพาะของอินเทอร์เฟซ CategoryService:
คลาสสาธารณะ categoryserviceimpl ขยาย BaseserviceImpl <หมวดหมู่> ใช้หมวดหมู่ {private sessionfactory sessionfactory; // ฤดูใบไม้ผลิจะฉีดโมฆะสาธารณะ setSessionFactory (SessionFactory SessionFactory) {this.sessionFactory = SessionFactory; } การป้องกันเซสชัน getSession () {// รับเซสชันจากเธรดปัจจุบันหากไม่ได้สร้างเซสชันใหม่ return SessionFactory.getCurrentsession (); } @Override โมฆะสาธารณะบันทึก (หมวดหมู่หมวดหมู่) {getSession (). บันทึก (หมวดหมู่); } @Override การอัปเดตโมฆะสาธารณะ (หมวดหมู่หมวดหมู่) {getSession (). อัปเดต (หมวดหมู่); } @Override โมฆะสาธารณะลบ (ID int) { /*วิธีแรกมีข้อเสียนั่นคือคุณต้องสอบถามมันหนึ่งครั้งก่อนที่คุณจะลบออก Object OBJ = getSession (). get (category.class, id); ถ้า (obj! = null) {getSession (). ลบ (obj); }*/ string hql = "ลบหมวดหมู่ในขณะที่ id =: id"; getSession (). createquery (hql) // .setinteger ("id", id) // .executeUpdate (); } @Override หมวดหมู่สาธารณะรับ (int id) {return (หมวดหมู่) getSession (). get (category.class, id); } @Override รายการสาธารณะ <หมวดหมู่> query () {string hql = "จากหมวดหมู่"; return getSession (). createquery (HQL) .List (); - 1.2 การใช้งานการสกัดด้วยเลเยอร์บริการ
หลังจากเสร็จสิ้นหมวดหมู่บริการเราจะแยกการใช้งานขั้นพื้นฐานของเลเยอร์บริการ ความคิดมีดังนี้: เราแยกเบสเบสเบสเบสฐานและ baseserviceimpl และเมื่อพัฒนาในภายหลังหากจำเป็นต้องใช้บริการใหม่คุณจะต้องทำสองขั้นตอน: ก่อนอื่นให้กำหนดอินเตอร์เฟส XXXService ใหม่ จากนั้นกำหนดคลาสการใช้งานใหม่ XXXServiceImpl สืบทอด BaseserviceImpl และใช้อินเตอร์เฟส XXXService สิ่งนี้ทำให้ง่ายต่อการบำรุงรักษาโครงการ
ก่อนอื่นให้สร้างอินเทอร์เฟซ Baseservice ตามส่วนต่อประสานหมวดหมู่ด้านบน:
// Basic Interface Baseservice ใช้ฐานข้อมูลสาธารณะทั่วไป <t> {โมฆะสาธารณะบันทึก (t t); การอัปเดตโมฆะสาธารณะ (T T); โมฆะสาธารณะลบ (ID int); สาธารณะ t รับ (int id); รายการสาธารณะ <t> Query (); - จากนั้นสร้างคลาสการใช้งาน Baseservice Interface BaseserviceImpl ตามคลาสการใช้งาน CategoryServiceImpl:
/ ** * @description toDo (การสกัดโมดูลสาธารณะ) * @author eson_15 * */ @suppresswarnings ("ไม่ถูกตรวจสอบ") คลาสสาธารณะ BaseserviceImpl <t> ใช้ Baseservice <t> {คลาสส่วนตัว // ประเภทของการดำเนินการปัจจุบันถูกเก็บไว้ใน clazz นั่นคือ sessionfactory private t ทั่วไป Public BaseserviceImpl () {// ข้อมูลการพิมพ์สามรายการต่อไปนี้สามารถลบออกได้ นี่คือ system.out.println ("นี่หมายถึงวัตถุที่เรียกตัวสร้าง" + สิ่งนี้); System.out.println ("รับข้อมูลคลาสแม่ของวัตถุนี้ปัจจุบัน" + this.getClass (). getSuperClass ()); System.out.println ("รับข้อมูลคลาสแม่ของวัตถุปัจจุบัน (รวมถึงข้อมูลทั่วไป)" + this.getClass (). getGenericsuperclass ()); // รับประเภทพารามิเตอร์ของพารามิเตอร์ทั่วไป Type = (parameterizedType) this.getClass (). getGenericsuperClass (); clazz = (คลาส) type.getActualTypeArguments () [0]; } โมฆะสาธารณะ setSessionFactory (SessionFactory SessionFactory) {this.sessionFactory = SessionFactory; } การป้องกันเซสชัน getSession () {// รับเซสชันจากเธรดปัจจุบันหากไม่ได้สร้างเซสชันใหม่ return SessionFactory.getCurrentsession (); } @Override โมฆะสาธารณะบันทึก (t t) {getSession (). บันทึก (t); } @Override โมฆะสาธารณะอัปเดต (t t) {getSession (). อัปเดต (t); } @Override โมฆะสาธารณะลบ (int id) {system.out.println (clazz.getSimplename ()); String hql = "delete" + clazz.getSimplename () + "เป็น c โดยที่ c.id =: id"; getSession (). createquery (hql) // .setinteger ("id", id) // .executeUpdate (); } @Override สาธารณะ t รับ (int id) {return (t) getSession () รับ (clazz, id); } @Override รายการสาธารณะ <t> query () {string hql = "จาก" + clazz.getSimplename (); return getSession (). createquery (HQL) .List (); - หลังจากการสกัดเสร็จสมบูรณ์เราสามารถเขียนอินเทอร์เฟซหมวดหมู่บริการใหม่และคลาสการใช้งาน CategoryServiceImpl ดังนี้:
// categoryService อินเตอร์เฟสสืบทอด baseservice interface interface public categoryservice ขยาย baseservice <category> { / * * เพียงเพิ่มวิธีการใหม่ที่ต้องการโดย categoryService เอง วิธีการสาธารณะมีอยู่แล้วใน Baseservice * /} / ** * @description toDo (ตรรกะทางธุรกิจของโมดูลเอง) * @author ESON_15 * * / หมวดหมู่คลาสสาธารณะ วิธีการสาธารณะได้ถูกนำไปใช้ใน baseserviceimpl */} ดังที่เห็นได้จากรหัสบริการที่เพิ่มเข้ามาใหม่จะต้องสืบทอดอินเตอร์เฟส Baseservice แล้วเพิ่มตรรกะทางธุรกิจที่ต้องการโดยบริการไปยังอินเทอร์เฟซ ServiceImpl ที่เพิ่มเข้ามาใหม่จำเป็นต้องสืบทอด BaseserviceImpl และใช้ตรรกะทางธุรกิจที่เพิ่มขึ้นใหม่
แต่อย่าลืมจุดสำคัญ: มันคือ การปรับเปลี่ยนถั่วในไฟล์การกำหนดค่าของฤดูใบไม้ผลิ xml
<!-คลาสทั่วไปไม่สามารถสร้างอินสแตนซ์ได้ดังนั้นเพิ่มคุณสมบัติ Lazy-init-> <bean id = "baseservice" lazy-init = "true"> <property name = "sessionfactory" ref = "sessionfactory"/> </ebean> <bean id = "หมวดหมู่
ฆ่าทรัพย์สินในหมวดหมู่ดั้งเดิมจากนั้นเพิ่มคุณสมบัติหลักเพื่อระบุการสืบทอดของ Baseservice; จากนั้นกำหนดค่า Baseservice และกำหนดค่า SessionFactory เป็น Baseservice นอกจากนี้สิ่งหนึ่งที่ควรทราบ: ตั้งค่าคุณสมบัติ Lazy-init เป็น TRUE เพราะ Baseservice เป็นคลาสทั่วไปและคลาสทั่วไปไม่สามารถสร้างอินสแตนซ์ได้ ณ จุดนี้การสกัดของชั้นบริการจะเสร็จสิ้น
2. เพิ่มบัญชีในเลเยอร์บริการ
เลเยอร์บริการเพิ่งได้รับการสกัดดังนั้นตอนนี้มันง่ายมากที่จะเขียนบริการบัญชี:
ก่อนอื่นเขียนอินเทอร์เฟซ AccountService เพื่อสืบทอด Baseservice:
ส่วนต่อประสานสาธารณะ AccountService ขยาย Baseservice <account> {// โปรดทราบว่าทั่วไปใน Baseservice เป็นบัญชี / * * เพียงเพิ่มวิธีการใหม่ที่ต้องการโดย AccountService เองและวิธีการสาธารณะอยู่ใน Baseservice * /} จากนั้นเขียนคลาสการใช้งาน AccountServiceImpl เพื่อสืบทอดคลาสการใช้งาน BaseserviceImpl และใช้งานส่วนต่อประสานบัญชี:
Public Class AccountServiceImpl ขยาย BaseserviceImpl <account> ใช้งานบัญชี { / * * เพียงแค่ใช้วิธีการที่เพิ่มขึ้นใหม่ในส่วนต่อประสานบัญชี วิธีการสาธารณะได้ถูกนำไปใช้ใน BaseserviceImpl */// จัดการฟังก์ชั่นการเข้าสู่ระบบและจะปรับปรุงในภายหลัง} สุดท้ายเพิ่มการกำหนดค่าต่อไปนี้ในไฟล์ beans.xml:
<bean id = "accountService" parent = "baseservice" />
ด้วยวิธีนี้มีการเขียนบริการใหม่ หากคุณต้องการเพิ่มบริการในอนาคตคุณจะทำตามกระบวนการนี้ซึ่งสะดวกมาก
3. การสกัดการกระทำ
3.1 เก็บข้อมูลในการดำเนินการในโดเมน (คำขอเซสชันแอปพลิเคชัน ฯลฯ )
เรารู้ว่าในการดำเนินการคุณสามารถรับวัตถุ ActionContext โดยตรงผ่าน ActionContext.getContext () จากนั้นรับวัตถุโดเมนที่เกี่ยวข้องผ่านวัตถุ นอกจากนี้คุณยังสามารถฉีดวัตถุโดเมนที่เกี่ยวข้องได้โดยใช้อินเตอร์เฟส XXXAware ก่อนอื่นให้ดูที่สองวิธีนี้:
หมวดหมู่ระดับสาธารณะขยายการดำเนินการดำเนินการดำเนินการตามคำร้องขอ SessionAware, ApplicationAware {หมวดหมู่ส่วนตัว; หมวดหมู่ส่วนตัวหมวดหมู่บริการ; โมฆะสาธารณะ setCategoryService (หมวดหมู่บริการหมวดหมู่ Service) {this.CategoryService = categoryService; } การอัปเดตสตริงสาธารณะ () {System.out.println ("---- Update ----"); CategoryService.update (หมวดหมู่); กลับ "ดัชนี"; } สตริงสาธารณะบันทึก () {system.out.println ("---- บันทึก ----"); กลับ "ดัชนี"; } การสืบค้นสตริงสาธารณะ () {// โซลูชัน 1 ใช้แผนที่ที่เกี่ยวข้องเพื่อแทนที่วัตถุในตัวดั้งเดิมเพื่อไม่ให้พึ่งพา JSP แต่จำนวนของรหัสมีขนาดค่อนข้างใหญ่ // actionContext.getContext () ใส่ ("หมวดหมู่", หมวดหมู่ // ใส่ไว้ในฟิลด์คำขอ // actionContext.getContext (). getSession (). ใส่ ("หมวดหมู่", หมวดหมู่ Service.Query ()); // ใส่ไว้ในฟิลด์เซสชัน // actionContext.getContext (). getApplication (). ใส่ ("categoryList", categoryService.Query ()); // ใส่ลงในโดเมนแอปพลิเคชัน // โซลูชัน 2 ใช้อินเทอร์เฟซที่เกี่ยวข้อง (requestaware, sessionaware, applicationaware) และปล่อยให้การร้องขอการฉีดแผนที่ที่สอดคล้องกัน ("หมวดหมู่", categoryservice.query ()); session.put ("categorylist", categoryService.Query ()); Application.put ("CategoryList", categoryService.Query ()); กลับ "ดัชนี"; } หมวดหมู่สาธารณะ getCategory () {return category; } โมฆะสาธารณะ setCategory (หมวดหมู่หมวดหมู่) {this.category = หมวดหมู่; } แผนที่ส่วนตัว <สตริงวัตถุ> คำขอ; แผนที่ส่วนตัว <สตริงวัตถุ> เซสชัน; แผนที่ส่วนตัว <สตริงวัตถุ> แอปพลิเคชัน; @Override โมฆะสาธารณะ setapplication (แผนที่ <สตริงวัตถุ> แอปพลิเคชัน) {this.application = แอปพลิเคชัน; } @Override void setSession (แผนที่ <String, Object> เซสชัน) {this.session = เซสชัน; } @Override โมฆะสาธารณะ setRequest (แผนที่ <สตริง, วัตถุ> คำขอ) {this.request = คำขอ; - มันยังคงเป็นคลาสหมวดหมู่ที่รวมสามกรอบหลักในส่วนก่อนหน้า เราเพิ่มวิธีการสืบค้นในวิธีนี้ ในวิธีนี้เราจัดเก็บผลลัพธ์ของการสืบค้นลงในโดเมนคำขอโดเมนเซสชันและโดเมนแอปพลิเคชัน วิธีแรกคือการใช้ ActionContext โดยตรงเพื่อนำไปใช้ ไม่จำเป็นต้องใช้อินเทอร์เฟซ แต่รหัสมีขนาดใหญ่ วิธีที่สองใช้อินเทอร์เฟซ Requestaware, SessionAware และ ApplicationAware และวิธีการที่เป็นนามธรรมสามวิธีในการใช้คำขออินเตอร์เฟสการฉีดเข้าร่วมเซสชันและแอปพลิเคชันจากนั้นกำหนดให้กับตัวแปรสมาชิกที่เกี่ยวข้องเพื่อให้สามารถเก็บผลลัพธ์การสืบค้นในโดเมนในวิธีการสืบค้น ปริมาณรหัสนี้ดูเหมือนจะใหญ่กว่าวิธีแรก ... แต่เราสามารถแยกมันและอ่านมันลงก่อน
เราเพิ่มการเชื่อมต่อแบบสอบถามใหม่ลงใน index.jsp เพื่อทดสอบว่าสามารถแสดงผลลัพธ์การสืบค้นได้หรือไม่:
<%@ page language = "java" import = "java.util.*" pageencoding = "utf-8"%> <%@ taglib uri = "http://java.sun.com/jsp/jstl/core" prefix = "c"%> <html> <head> <title> หน้าเริ่มต้น jsp 'index.jsp' ของฉัน </title> </head> <body> <a href = "$ {pageContext.request.contextpath} /category_update.action?category.id=2&pate.type=gga href = "category_save.action"> เข้าถึงบันทึก </a> <a href = "category_query.action"> การสืบค้นหมวดหมู่ทั้งหมด </a> <br/> <c: foreach items = "$ {requestscope.categorylist}" var = "หมวดหมู่"> $ {category.id} | $ {category.type} | $ {category.hot} <br/> </c: foreach> <c: foreach items = "$ {sessionscope.categorylist}" var = "หมวดหมู่"> $ {category.id} | $ {category.type} | $ {category.hot} <br/> </c: foreach> <c: foreach items = "$ {applicationscope.categorylist}" var = "หมวดหมู่"> $ {category.id} | $ {category.type} | $ {category.hot} <br/> </c: foreach> </body> </html> 3.2 สารสกัด
ดังที่ได้กล่าวไว้ในขณะนี้วิธีที่สองมีปริมาณรหัสที่ใหญ่กว่า แต่เราสามารถแยกออกจาก baseaction เพื่อจัดการการดำเนินงานที่เกี่ยวข้องกับโดเมนเหล่านี้โดยเฉพาะ
Baseaction ระดับสาธารณะขยายการดำเนินการดำเนินการตามคำร้องขอ WorkAware, SessionAware, ApplicationAware {MAP ที่ได้รับการป้องกัน <String, Object> คำขอ; แผนที่ป้องกัน <String, Object> เซสชัน; แผนที่ป้องกัน <String, Object> แอปพลิเคชัน; @Override โมฆะสาธารณะ setapplication (แผนที่ <สตริงวัตถุ> แอปพลิเคชัน) {this.application = แอปพลิเคชัน; } @Override void setSession (แผนที่ <String, Object> เซสชัน) {this.session = เซสชัน; } @Override โมฆะสาธารณะ setRequest (แผนที่ <สตริง, วัตถุ> คำขอ) {this.request = คำขอ; - จากนั้นหากการกระทำของเราเองจำเป็นต้องใช้วัตถุโดเมนเหล่านี้เพื่อจัดเก็บข้อมูลเราสามารถสืบทอด baseaction โดยตรงและเราสามารถใช้การร้องขอเซสชันและวัตถุแอปพลิเคชันโดยตรง ดังนั้นหมวดหมู่ที่แก้ไขมีดังนี้:
หมวดหมู่ระดับสาธารณะขยาย baseaction {หมวดหมู่ส่วนตัว; <name pre = "code"> หมวดหมู่ส่วนตัวหมวดหมู่บริการ; โมฆะสาธารณะ setCategoryService (หมวดหมู่บริการหมวดหมู่ Service) {this.CategoryService = categoryService; } การอัปเดตสตริงสาธารณะ () {System.out.println ("--- อัปเดต ----"); categoryService.Update (หมวดหมู่); กลับ "ดัชนี"; } สตริงสาธารณะบันทึก () {system.out.println ("---- บันทึก -----"); return "index"; } การสืบค้นสตริงสาธารณะ () {request.put ("categoryList", categoryService.Query ()); session.put ("categorylist", categoryService.Query ()); Application.put ("CategoryList", categoryService.Query ()); กลับ "ดัชนี"; } หมวดหมู่สาธารณะ getCategory () {return category; } โมฆะสาธารณะ setCategory (หมวดหมู่หมวดหมู่) {this.category = หมวดหมู่; - การกระทำทั้งหมดที่ต้องใช้การร้องขอเซสชันและฟิลด์แอปพลิเคชันนั้นได้รับการสืบทอดโดยตรงซึ่งสะดวกมาก
3.3 รับพารามิเตอร์ (ModelDriven)
มาดูคลาสการทำหมวดหมู่ด้านบนกันเถอะ มีหมวดหมู่ตัวแปรสมาชิกซึ่งเป็น pojo การกำหนดตัวแปรนี้และการเขียนชุดและรับใช้สำหรับหน้า JSP ที่จะส่งผ่านผ่านพารามิเตอร์ที่แนบมากับ URL พารามิเตอร์เป็นแอตทริบิวต์ในวัตถุหมวดหมู่เช่น ID ประเภท ฯลฯ แต่พารามิเตอร์ใน URL จะต้องเขียนเป็นหมวดหมู่. id, category.type ฯลฯ ด้วยวิธีนี้ struts จะฉีดพารามิเตอร์การเขียนนี้ลงในวัตถุหมวดหมู่โดยอัตโนมัติและเราสามารถใช้วัตถุหมวดหมู่นี้โดยตรง เราสามารถใช้ ModelDriven เพื่อแก้ปัญหาได้ง่ายขึ้น
หมวดหมู่ระดับสาธารณะขยาย Baseaction ใช้ ModelDriven <S CATEGORY> {หมวดหมู่ส่วนตัว; // การใช้อินเทอร์เฟซ ModelDriven ต้องใช้วิธี getModel () วิธีนี้จะผลักดันรายการที่ส่งคืนไปที่ด้านบนของหมวดหมู่สาธารณะ @Override GetModel () {category = หมวดหมู่ใหม่ (); หมวดหมู่คืน; } <ชื่อก่อน = "รหัส"> หมวดหมู่ส่วนตัวหมวดหมู่บริการ; โมฆะสาธารณะ setCategoryService (หมวดหมู่บริการหมวดหมู่ Service) {this.CategoryService = categoryService; } การอัปเดตสตริงสาธารณะ () {System.out.println ("---- Update ----"); CategoryService.update (หมวดหมู่); กลับ "ดัชนี"; } สตริงสาธารณะบันทึก () {system.out.println ("---- บันทึก ----"); กลับ "ดัชนี"; } การสืบค้นสตริงสาธารณะ () {request.put ("categoryList", categoryService.Query ()); session.put ("categorylist", categoryService.Query ()); Application.put ("CategoryList", categoryService.Query ()); กลับ "ดัชนี"; - ด้วยวิธีนี้เราไม่จำเป็นต้องรวมพารามิเตอร์ที่น่าเบื่อเช่น category.id ในหน้าแผนกต้อนรับ JSP ดูส่วน ModelDriven ของหน้า JSP:
<%@ page language = "java" import = "java.util.*" pageencoding = "utf-8"%> <%@ taglib uri = "http://java.sun.com/jsp/jstl/core" prefix = "c"%> <html> <head> <title> หน้าเริ่มต้น jsp 'index.jsp' ของฉัน </title> </head> <body> <a href = "$ {pageContext.request.contextpath} /category_update.action?category.id=2&pate.type=gga href = "category_save.action? id = 1 & type = haha & hot = true"> test modeldriven </a> <a href = "category_query.action"> การสืบค้นหมวดหมู่ทั้งหมด </a> <br/> <c: foreach items = "$ {requestscope.cope $ {category.type} | $ {category.hot} <br/> </c: foreach> <c: foreach items = "$ {sessionscope.categorylist}" var = "หมวดหมู่"> $ {category.id} | $ {category.type} | $ {category.hot} <br/> </c: foreach> <c: foreach items = "$ {applicationscope.categorylist}" var = "หมวดหมู่"> $ {category.id} | $ {category.type} | $ {category.hot} <br/> </c: foreach> </body> </html> ผลการทดสอบคือสามารถรับ catgory ได้และแอตทริบิวต์ประเภทและแอตทริบิวต์ร้อนทั้งหมดได้รับมอบหมายอย่างดี เราจะเห็นได้ว่าโดยการใช้อินเทอร์เฟซ ModelDriven เราสามารถพกพาพารามิเตอร์ใน URL ได้อย่างง่ายดาย ในการดำเนินการเราจำเป็นต้องใช้วิธี GetModel และส่งคืนวัตถุใหม่ที่จะใช้ ณ จุดนี้มันเป็นเรื่องง่ายที่จะคิดว่าจะมีหลายรุ่นดังกล่าวใน struts ที่จำเป็นต้องได้รับดังนั้นเราจึงต้องแยกส่วนนี้ออกเป็น baseaction
3.4 สารสกัดจากโมเดล
ก่อนอื่นเราเพิ่มรหัสของส่วน modeldriven ลงใน baseaction ดังต่อไปนี้:
// เนื่องจากมีโมเดลที่แตกต่างกันมากมายที่ต้องใช้ ModelDriven เราจึงใช้ Baseaction ระดับสาธารณะทั่วไป <T> ขยายการดำเนินการดำเนินการ requestaware, SessionAware, ApplicationAware, ModelDriven <T> {MAP ที่ได้รับการป้องกัน <String, Object> คำขอ; แผนที่ป้องกัน <String, Object> เซสชัน; แผนที่ป้องกัน <String, Object> แอปพลิเคชัน; แบบจำลองที่ได้รับการป้องกัน @Override โมฆะสาธารณะ setapplication (แผนที่ <สตริงวัตถุ> แอปพลิเคชัน) {this.application = แอปพลิเคชัน; } @Override void setSession (แผนที่ <String, Object> เซสชัน) {this.session = เซสชัน; } @Override โมฆะสาธารณะ setRequest (แผนที่ <สตริง, วัตถุ> คำขอ) {this.request = คำขอ; } @Override สาธารณะ t getModel () {// ที่นี่ใหม่อินสแตนซ์ที่สอดคล้องกันใหม่โดยการแยกวิเคราะห์ t ที่ผ่านเข้ามาพารามิเตอร์ประเภท Type = (ParameterizedType) this.getClass (). getGenericsUperClass (); Class clazz = (คลาส) type.getActualTypeArguments () [0]; ลอง {model = (t) clazz.newinstance (); } catch (exception e) {โยน runtimeException ใหม่ (e); } ส่งคืนโมเดล; - หลังจากการสกัดรหัสในหมวดหมู่จะลดลงและลดลง:
// สืบทอด baseaction และเพิ่มหมวดหมู่ระดับสาธารณะทั่วไปขยาย baseaction <category> {หมวดหมู่ส่วนตัวหมวดหมู่บริการ; โมฆะสาธารณะ setCategoryService (หมวดหมู่บริการหมวดหมู่ Service) {this.CategoryService = categoryService; } การอัปเดตสตริงสาธารณะ () {System.out.println ("---- Update ----"); CategoryService.Update (รุ่น); // ใช้โมเดลส่งคืนโดยตรง "ดัชนี"; } สตริงสาธารณะบันทึก () {system.out.println ("---- บันทึก ----"); System.out.println (รุ่น); // ใช้โมเดลโดยตรงเพื่อส่งคืน "ดัชนี"; } การสืบค้นสตริงสาธารณะ () {request.put ("categoryList", categoryService.Query ()); session.put ("categorylist", categoryService.Query ()); Application.put ("CategoryList", categoryService.Query ()); กลับ "ดัชนี"; - ณ จุดนี้มีอีกสิ่งหนึ่งที่ไม่รู้สึกดีเกี่ยวกับมันซึ่งเป็นหมวดหมู่ตัวแปรสมาชิกซึ่งมีอยู่ในหมวดหมู่เสมอ เนื่องจากหมวดหมู่ใช้วิธีการในวัตถุหมวดหมู่บริการจะต้องสร้างวัตถุนี้และวิธีการตั้งค่าสามารถฉีดได้ สิ่งนี้นำไปสู่ข้อเสีย: หากการกระทำหลายอย่างจำเป็นต้องใช้หมวดหมู่บริการจะต้องสร้างวิธีการวัตถุและชุดในการกระทำของพวกเขา ยิ่งกว่านั้นหากมีการใช้วัตถุบริการที่แตกต่างกันหลายรายการในการดำเนินการทั้งหมดจะต้องสร้างขึ้นซึ่งจะซับซ้อนมาก
3.5 สารสกัดให้กับ baseaction
ในการตอบสนองต่อปัญหาข้างต้นเราได้แยกวัตถุบริการทั้งหมดในโครงการออกเป็น baseaction เพื่อสร้างมัน ด้วยวิธีนี้หลังจากการกระทำอื่น ๆ สืบทอด baseaction พวกเขาสามารถใช้บริการใดก็ได้ที่พวกเขาต้องการใช้:
// ฉันจำแนกเนื้อหาในชั้นเรียนสาธารณะ Baseaction <t> ขยายการดำเนินการดำเนินการ usproseWare, SessionAware, ApplicationAware, ModelDriven <t> {// บริการหมวดหมู่การป้องกันวัตถุบริการหมวดหมู่บริการ; บริการบัญชีที่ได้รับการป้องกัน โมฆะสาธารณะ setCategoryService (หมวดหมู่บริการหมวดหมู่ Service) {this.CategoryService = categoryService; } โมฆะสาธารณะ setAccountService (accountService) accountService) {this.accountService = accountService; } // แผนที่วัตถุโดเมนป้องกัน <String, Object> คำขอ; แผนที่ป้องกัน <String, Object> เซสชัน; แผนที่ป้องกัน <String, Object> แอปพลิเคชัน; @Override โมฆะสาธารณะ setapplication (แผนที่ <สตริงวัตถุ> แอปพลิเคชัน) {this.application = แอปพลิเคชัน; } @Override void setSession (แผนที่ <String, Object> เซสชัน) {this.session = เซสชัน; } @Override โมฆะสาธารณะ setRequest (แผนที่ <สตริง, วัตถุ> คำขอ) {this.request = คำขอ; } // แบบจำลองการป้องกัน T Modeldriven; @Override สาธารณะ t getModel () {parameterizedType type = (parameterizedType) this.getClass (). getGenericsUperClass (); Class clazz = (คลาส) type.getActualTypeArguments () [0]; ลอง {model = (t) clazz.newinstance (); } catch (exception e) {โยน runtimeException ใหม่ (e); } ส่งคืนโมเดล; }} สิ่งนี้ทำให้หมวดหมู่การรีเฟรชมากขึ้น: หมวดหมู่คลาสสาธารณะขยาย baseaction <หมวดหมู่> {การอัปเดตสตริงสาธารณะ () {system.out.println ("--- อัปเดต ----"); CategoryService.update (รุ่น); กลับ "ดัชนี"; } สตริงสาธารณะบันทึก () {system.out.println ("--- บันทึก ----"); System.out.println (รุ่น); กลับ "ดัชนี"; } การสืบค้นสตริงสาธารณะ () {request.put ("categoryList", categoryService.Query ()); session.put ("categorylist", categoryService.Query ()); Application.put ("CategoryList", categoryService.Query ()); กลับ "ดัชนี"; - บางคนอาจถามว่ามันจะไม่ซ้ำซ้อนหากวัตถุบริการจำนวนมากถูกฉีดเข้าไปใน baseaction? สิ่งนี้ไม่เป็นความจริงเพราะแม้ว่ามันจะไม่ได้เขียนไว้ใน baseaction คอนเทนเนอร์สปริงจะสร้างวัตถุนี้ซึ่งไม่สำคัญ ในทางตรงกันข้ามวัตถุบริการจะถูกวางไว้ใน baseaction และสะดวกกว่าสำหรับการพัฒนาของการกระทำอื่น ๆ ยิ่งไปกว่านั้น baseaction ไม่จำเป็นต้องกำหนดให้กับไฟล์ struts.xml เนื่องจากไม่มี JSP จะขอ baseaction มันเป็นเพียงการกระทำอื่น ๆ ที่จะสืบทอด
อีกสิ่งหนึ่งที่ต้องลืม: นั่นคือการปรับเปลี่ยนการกำหนดค่าใน beans.xml:
<!-ถ้าเป็นประเภทต้นแบบมันจะถูกสร้างขึ้นเมื่อใช้ไม่ได้โดยอัตโนมัติเมื่อเริ่มต้น-> <bean id = "baseaction" scope = "ต้นแบบ"> <property name = "categoryService" ref = "categoryService"> </property> parent = "baseaction"/>
เพิ่ม baseaction bean ใหม่จับคู่วัตถุบริการทั้งหมดในโครงการเป็นคุณสมบัติและฆ่าคุณสมบัติในหมวดหมู่ดั้งเดิม
ในอนาคตหากเราต้องการเขียน xxxaction ใหม่เราสามารถสืบทอด baseaction โดยตรง หากใช้บริการใน XXXAction เราสามารถใช้งานได้โดยตรง เราเพียงแค่ต้องเพิ่มถั่วที่สอดคล้องกับ xxxaction ในไฟล์ beans.xml และกำหนดค่าการกระโดดในไฟล์ struts.xml
4. เปลี่ยน XML เป็นคำอธิบายประกอบ
เราจะเห็นได้ว่าเมื่อโครงการมีขนาดใหญ่ขึ้นเรื่อย ๆ จะมีการกำหนดค่ามากขึ้นใน beans.xml และการกำหนดค่าจำนวนมากซ้ำซ้อน เพื่อให้การพัฒนาง่ายขึ้นตอนนี้เราเปลี่ยนการกำหนดค่า XML เป็นคำอธิบายประกอบ ก่อนอื่นให้ดูที่การกำหนดค่าใน beans.xml:
นี่คือถั่วที่เราเขียนเมื่อเราสร้างสภาพแวดล้อมและสกัด สิ่งเหล่านี้จำเป็นต้องถูกแปลงเป็นคำอธิบายประกอบ มาแทนที่ชิ้นส่วน: ก่อนแทนที่ส่วนบริการซึ่งมีสามส่วน: Baseservice, CategoryService และ AccountService แทนที่ดังนี้:
จากนั้นฆ่าส่วนที่เกี่ยวข้องใน beans.xml ถัดไปแก้ไขส่วนการดำเนินการส่วนใหญ่ baseaction หมวดหมู่และบัญชีและแทนที่ดังนี้:
จากนั้นฆ่าการกำหนดค่าของส่วนการกระทำใน beans.xml และในที่สุดก็เพิ่มการกำหนดค่าต่อไปนี้ในไฟล์ beans.xml และคุณสามารถใช้คำอธิบายประกอบได้
<บริบท: Component-Scan base-package = "cn.it.shop .. "/>
บางคนอาจถามว่าทำไมบริการและการกระทำจึงแตกต่างกันเมื่อใช้คำอธิบายประกอบ? @Service ใช้ในบริการและ @Controller ใช้ในการดำเนินการหรือไม่? ในความเป็นจริงมันเหมือนกันเพียงเพื่อแยกแยะพวกเขาออกจากชั้นที่แตกต่างกันของถั่วเพื่อให้อ่านง่าย
ซอร์สโค้ดดาวน์โหลดที่อยู่ของโครงการทั้งหมด: //www.vevb.com/article/86099.htm
ที่อยู่ดั้งเดิม: http://blog.csdn.net/eson_15/article/details/51297698
ข้างต้นเป็นเนื้อหาทั้งหมดของการต่อสู้ครั้งที่สองของโครงการ SSH Framework Online Mall ฉันหวังว่ามันจะเป็นประโยชน์ต่อการเรียนรู้ของทุกคนและฉันหวังว่าทุกคนจะสนับสนุน wulin.com มากขึ้น