บทความนี้แนะนำการเขียน AOP โดยใช้ Spring Boot และ JDK8 โดยรวมคำอธิบายประกอบที่กำหนดเองเพื่อให้ได้การตรวจสอบพารามิเตอร์อินเตอร์เฟสทั่วไป
เหตุผล
ปัจจุบันวิธีการตรวจสอบพารามิเตอร์ที่ใช้กันทั่วไปคือการเพิ่มคำอธิบายประกอบในคลาสเอนทิตี แต่สำหรับวิธีการที่แตกต่างกันกฎการตรวจสอบที่ใช้ก็แตกต่างกันเช่นกัน ตัวอย่างเช่นมีเอนทิตีบัญชี:
Public Class AccountVo {ชื่อสตริงส่วนตัว; // ชื่ออายุจำนวนเต็มส่วนตัว; // อายุ}สมมติว่ามีธุรกิจ: เมื่อผู้ใช้ลงทะเบียนเขาหรือเธอต้องกรอกชื่อของเขาหรือเธอและเมื่อผู้ใช้เข้าสู่ระบบเขาหรือเธอต้องการเพียงเติมชื่อของเขาหรือเธอ จากนั้นก็เห็นได้ชัดว่าไม่เหมาะสมที่จะเพิ่มกฎการตรวจสอบในคลาสเอนทิตี
ดังนั้นฉันจึงต้องการใช้การตรวจสอบพารามิเตอร์ระดับวิธีการเสมอ วิธีการที่แตกต่างกันสามารถใช้กฎการตรวจสอบที่แตกต่างกันสำหรับพารามิเตอร์เอนทิตีเดียวกันซึ่งให้กำเนิดเครื่องมือนี้และใช้ในการทำงานประจำวันเป็นเวลานาน
แนะนำ
มาดูวิธีใช้ก่อน:
@ServicePublic Class TestImpl ใช้ itestService {@Override @Check ({"ชื่อ", "อายุ"}) โมฆะสาธารณะ testValid (AccountVo Vo) {// ... }}คำอธิบายประกอบ @check บนวิธีนี้บ่งชี้ว่าคุณสมบัติชื่อและอายุในพารามิเตอร์บัญชีไม่สามารถว่างเปล่าได้ นอกเหนือจากการตรวจสอบที่ไม่ว่างเปล่าแล้วยังสนับสนุนการตัดสินขนาดและการตรวจสอบความเท่าเทียมกัน:
@Check ({"id> = 8", "ชื่อ! = aaa", "ชื่อเรื่อง <10"})ข้อความแสดงข้อผิดพลาดเริ่มต้นส่งคืนฟิลด์สาเหตุของข้อผิดพลาดและวิธีการที่เรียกว่า::
UpdateUserId ต้องไม่เป็นโมฆะในขณะที่การโทร testValidId ต้อง> = 8 ในขณะที่โทร testValidName ต้อง! = aaa ในขณะที่โทร testValid
ข้อมูลการส่งคืนข้อผิดพลาดที่กำหนดเองยังรองรับ:
@Check ({"title <= 8: จำนวนอักขระชื่อไม่เกิน 8 อักขระรวมถึงเครื่องหมายวรรคตอน"}) โมฆะสาธารณะ testValid (testpo po) {// ... }เพียงเพิ่ม: หลังจากกฎการตรวจสอบและเขียนข้อมูลที่กำหนดเองซึ่งจะแทนที่ข้อความแสดงข้อผิดพลาดเริ่มต้น
PS: หลักการหลักคือการได้รับค่าของฟิลด์ในเอนทิตีพารามิเตอร์ผ่านการสะท้อนและจากนั้นตรวจสอบตามกฎ ดังนั้นในปัจจุบันมีเพียงวิธีการที่มีพารามิเตอร์หนึ่งพารามิเตอร์เท่านั้นและพารามิเตอร์ไม่สามารถเป็นประเภทพื้นฐานได้
ใช้
วิธีการใช้ AOP ใน Spring-Boot ฉันจะไม่เข้าไปดูรายละเอียดที่นี่และส่วนใหญ่แนะนำรหัสหลักใน AOP
การพึ่งพา maven
นอกเหนือจากการพึ่งพาสปริงบูตแล้วการพึ่งพาของบุคคลที่สามที่จำเป็นนั้นไม่ใช่การพึ่งพาหลักและคุณสามารถเลือกได้ตามพฤติกรรมส่วนตัวของคุณ:
<!-สำหรับการตรวจสอบสตริง-> <การพึ่งพา> <loupId> org.apache.Commons </groupId> <ratifactId> Commons-Lang3 </artifactid> <Sersion> 3.3.2 </Servive> </การพึ่งพา> <!-สำหรับการพิมพ์บันทึก-> <Sersion> 1.7.25 </Servive> </predency>
คำอธิบายประกอบที่กำหนดเอง
นำเข้า java.lang.annotation.elementtype; นำเข้า java.lang.annotation.retention; นำเข้า java.lang.annotation.target; นำเข้า java.lang.lang.lang.lang.retentionpolicy.runtime;/*** */@target ({elementtype.type, elementType.method})@retention (รันไทม์) public @interface ตรวจสอบ {// กฎการตรวจสอบฟิลด์รูปแบบ: ชื่อฟิลด์รหัสหลัก
โดยการสกัดกั้นวิธีการเชื่อมต่อด้วยคำอธิบายประกอบ @Check ให้ทำการตรวจสอบพารามิเตอร์ก่อนที่จะดำเนินการวิธีการ หากมีข้อความแสดงข้อผิดพลาดจะถูกส่งคืนโดยตรง:
@Around (value = "@com.cipher.checker.check") // ที่นี่คุณต้องเปลี่ยนเป็นเส้นทางของการตรวจสอบวัตถุสาธารณะที่กำหนดเอง // การตรวจสอบพารามิเตอร์สตริง msg = docheck (จุด); if (! stringutils.isempty (msg)) {// ที่นี่คุณสามารถส่งคืนคลาสส่งคืนที่ห่อหุ้มการโยนใหม่ unledalargumentexception (MSG); } obj = point.proceed (); ส่งคืน obj;}วิธีการตรวจสอบหลักในวิธี Docheck หลักการหลักคือการได้รับชื่อฟิลด์และกฎการตรวจสอบที่ระบุไว้ในคำอธิบายประกอบได้รับค่าของฟิลด์ที่เกี่ยวข้องในเอนทิตีพารามิเตอร์ผ่านการสะท้อนกลับแล้วทำการตรวจสอบ:
/*** การตรวจสอบพารามิเตอร์** @param Point Point PointingJoinPoint* @return ข้อความแสดงข้อผิดพลาด*/สตริงส่วนตัว docheck (PointingJoinPoint Point) {// รับวัตถุค่าพารามิเตอร์ของเมธอด [] อาร์กิวเมนต์ = point.getArgs (); // รับวิธีการวิธีการ = getMethod (จุด); String methodInfo = stringUtils.isempty (method.getName ())? "": "ในขณะที่โทร" + method.getName (); สตริง msg = ""; if (ischeck (วิธีการอาร์กิวเมนต์)) {ตรวจสอบคำอธิบายประกอบ = method.getAnnotation (check.class); String [] ฟิลด์ = Annotation.value (); วัตถุ Vo = อาร์กิวเมนต์ [0]; if (vo == null) {msg = "param ไม่สามารถเป็น null"; } else {สำหรับ (ฟิลด์สตริง: ฟิลด์) {// การแยกวิเคราะห์ฟิลด์ฟิลด์ฟิลด์ข้อมูล = ResolveField (ฟิลด์, methodInfo); // รับค่าของค่าวัตถุฟิลด์ = reflectionUtil.invokegetter (vo, info.field); // ดำเนินการตรวจสอบกฎการตรวจสอบ isvalid = info.optenum.fun.apply (ค่า, info.operatornum); msg = isvalid? ผงชูรส: info.innermsg; }}} return msg;}คุณจะเห็นว่าตรรกะหลักคือ:
Parse Fields -> รับค่าของฟิลด์ -> ดำเนินการตามกฎการตรวจสอบ
ชั้นเรียนการแจงนับจะได้รับการดูแลภายในและมีการระบุการตรวจสอบที่เกี่ยวข้องใน IT:
/** * การดำเนินการ enum */enum operator {/** * มากกว่า */greater_than (">", checkparamaspect :: isgreaterthan),/** * มากกว่าหรือเท่ากับ */great_than_equal ("> =" / *** น้อยกว่าหรือเท่ากับ* / less_than_equal ("<=", checkparamaspect :: islessthanequal), / *** ไม่เท่ากับ* / not_equal ("! =", checkparamaspect :: isnotequal), / ** ค่าสตริงส่วนตัว bifunction ส่วนตัว <วัตถุ, สตริง, บูลีน> สนุก; ตัวดำเนินการ (ค่าสตริง, bifunction <วัตถุ, สตริง, บูลีน> สนุก) {this.value = value; this.fun = fun; - เนื่องจากเหตุผลด้านพื้นที่ฉันจะไม่ขยายรหัสทั้งหมดทีละรหัส เพื่อนที่สนใจสามารถรับซอร์สโค้ดทั้งหมดได้ตามที่อยู่ต่อไปนี้: Ciphermagic/Java-Learn/Sandbox/Checker
สิ่งที่ต้องทำ
ในที่สุด
ขอบคุณสำหรับการอ่าน เพื่อนที่ชอบมันสามารถชอบได้ใน GitHub หากคุณมีคำถามหรือคำแนะนำใด ๆ โปรดฝากข้อความไว้ด้านล่างและหวังว่าจะได้รับคำตอบจากคุณ
ข้างต้นเป็นเนื้อหาทั้งหมดของบทความนี้ ฉันหวังว่ามันจะเป็นประโยชน์ต่อการเรียนรู้ของทุกคนและฉันหวังว่าทุกคนจะสนับสนุน wulin.com มากขึ้น