AOP คืออะไร
AOP (การเขียนโปรแกรมที่มุ่งเน้นด้านการเขียนโปรแกรมเชิงภาพ) สามารถกล่าวได้ว่าเป็นอาหารเสริมและการปรับปรุง OOP (การเขียนโปรแกรมเชิงวัตถุ) OOP แนะนำแนวคิดเช่นการห่อหุ้มมรดกและความหลากหลายเพื่อสร้างลำดับชั้นของวัตถุเพื่อจำลองการรวบรวมพฤติกรรมสาธารณะ เมื่อเราจำเป็นต้องแนะนำพฤติกรรมสาธารณะกับวัตถุที่กระจัดกระจาย OOP ดูเหมือนจะไร้อำนาจ นั่นคือ OOP ช่วยให้คุณกำหนดความสัมพันธ์จากบนลงล่าง แต่ไม่เหมาะสำหรับการกำหนดความสัมพันธ์จากซ้ายไปขวา ตัวอย่างเช่นฟังก์ชั่นการบันทึก รหัสบันทึกมักจะกระจัดกระจายในแนวนอนในทุกระดับวัตถุโดยไม่มีความสัมพันธ์ใด ๆ กับฟังก์ชันการทำงานหลักของวัตถุที่มันกระจัดกระจาย เช่นเดียวกับรหัสประเภทอื่น ๆ เช่นความปลอดภัยการจัดการข้อยกเว้นและความโปร่งใส รหัสที่ไม่เกี่ยวข้องประเภทนี้กระจัดกระจายไปทุกหนทุกแห่งเรียกว่ารหัสตัดข้าม ในการออกแบบ OOP มันทำให้เกิดการทำซ้ำรหัสจำนวนมากซึ่งไม่เอื้อต่อการใช้ซ้ำของแต่ละโมดูล
ในทางตรงกันข้ามเทคโนโลยี AOP ใช้เทคนิคที่เรียกว่า "การตัดขวาง" เพื่อผ่าด้านในของวัตถุที่ห่อหุ้มและห่อหุ้มพฤติกรรมทั่วไปที่ส่งผลกระทบต่อหลายคลาสลงในโมดูลที่นำมาใช้ซ้ำได้ การลดการมีเพศสัมพันธ์ระหว่างโมดูลและส่งเสริมการปฏิบัติงานในอนาคตและการบำรุงรักษา AOP แสดงถึงความสัมพันธ์ในแนวนอน หาก "วัตถุ" เป็นทรงกระบอกกลวงให้ห่อหุ้มคุณสมบัติและพฤติกรรมของวัตถุ จากนั้นวิธีการเขียนโปรแกรมที่มุ่งเน้นด้านนั้นก็เหมือนใบมีดที่คมชัดตัดกระบอกสูบกลวงเหล่านี้เพื่อรับข้อมูลภายใน ส่วนที่ถูกตัดออกคือสิ่งที่เรียกว่า "ใบหน้า" จากนั้นมันก็คืนค่าส่วนที่ถูกตัดออกด้วยมือที่ฉลาดโดยไม่ทิ้งร่องรอยใด ๆ
ด้วยการใช้เทคโนโลยี "crosscutting" AOP แบ่งระบบซอฟต์แวร์ออกเป็นสองส่วน: ความกังวลหลักและความกังวลข้ามการตัดข้าม กระบวนการหลักของการประมวลผลทางธุรกิจคือการมุ่งเน้นหลักและส่วนที่มีส่วนเกี่ยวข้องเพียงเล็กน้อยคือโฟกัสแบบตัดขวาง ลักษณะหนึ่งของความกังวลเกี่ยวกับการตัดข้ามคือพวกเขามักจะเกิดขึ้นในความกังวลหลักหลายประการและมีความคล้ายคลึงกันทุกที่ ตัวอย่างเช่นการตรวจสอบสิทธิ์การอนุญาตการบันทึกและการประมวลผลธุรกรรม บทบาทของ AOP คือการแยกข้อกังวลต่าง ๆ ในระบบและแยกความกังวลหลักออกจากข้อกังวลข้ามการตัด ในขณะที่ Adam Magee สถาปนิกอาวุโสของ Avanade กล่าวว่าแนวคิดหลักของ AOP คือการ“ แยกตรรกะทางธุรกิจในแอปพลิเคชันจากบริการทั่วไปที่สนับสนุน”
เทคโนโลยีในการใช้ AOP ส่วนใหญ่แบ่งออกเป็นสองประเภท: หนึ่งคือการใช้เทคโนโลยีพร็อกซีแบบไดนามิกและใช้วิธีการสกัดกั้นข้อความเพื่อตกแต่งข้อความเพื่อแทนที่การดำเนินการของพฤติกรรมวัตถุดั้งเดิม อีกอย่างคือการใช้วิธีการทอผ้าแบบคงที่เพื่อแนะนำไวยากรณ์เฉพาะเพื่อสร้าง "ใบหน้า" เพื่อให้คอมไพเลอร์สามารถสานรหัสที่เกี่ยวข้องกับ "ใบหน้า" ในระหว่างการรวบรวม
สถานการณ์การใช้งาน AOP
AOP ใช้เพื่อห่อหุ้มข้อกังวลข้ามการตัดซึ่งสามารถใช้ในสถานการณ์ต่อไปนี้:
สิทธิ์การตรวจสอบสิทธิ์
แคชแคช
บริบทผ่านเนื้อหา
การจัดการข้อผิดพลาด
ขี้เกียจโหลด
การดีบัก
การบันทึกการติดตามการทำโปรไฟล์และการตรวจสอบ
การเพิ่มประสิทธิภาพประสิทธิภาพ
การคงอยู่
การรวมทรัพยากร
การซิงโครไนซ์
การทำธุรกรรม
แนวคิดที่เกี่ยวข้องกับ AOP
แง่มุม: โมดูลาร์ของโฟกัสที่อาจข้ามวัตถุหลายชิ้น การจัดการธุรกรรมเป็นตัวอย่างที่ดีของข้อกังวลข้ามการตัดในแอปพลิเคชัน J2EE ด้านนี้ใช้โดยใช้ที่ปรึกษาหรือสกัดกั้นของฤดูใบไม้ผลิ
JoinPoint: จุดที่ชัดเจนในระหว่างการดำเนินการของโปรแกรมเช่นการโทรวิธีหรือข้อยกเว้นเฉพาะที่ถูกโยนทิ้ง
คำแนะนำ: การกระทำที่ดำเนินการโดย AOP Framework ณ จุดเชื่อมต่อที่เฉพาะเจาะจง การแจ้งเตือนประเภทต่าง ๆ รวมถึง "รอบ", "ก่อน" และ "การโยน" การแจ้งเตือน ประเภทการแจ้งเตือนจะกล่าวถึงด้านล่าง เฟรมเวิร์ก AOP จำนวนมากรวมถึงฤดูใบไม้ผลิใช้ตัวดักจับเป็นแบบจำลองการแจ้งเตือนเพื่อรักษาจุดเชื่อมต่อ "รอบ" ห่วงโซ่ " มีการกำหนดคำแนะนำสี่ประการในฤดูใบไม้ผลิ: beforeadvice, aftervide, throwadvice และ dynamicintroductionadvice
PointCut: ระบุคอลเลกชันของจุดเชื่อมต่อที่การแจ้งเตือนจะถูกเรียกใช้ เฟรมเวิร์ก AOP จะต้องอนุญาตให้นักพัฒนาระบุจุดเข้า: ตัวอย่างเช่นการใช้นิพจน์ทั่วไป สปริงกำหนดอินเทอร์เฟซ PointCut ซึ่งใช้เพื่อรวม MethodMatcher และ ClassFilter ซึ่งสามารถเข้าใจได้อย่างชัดเจนผ่านชื่อ MethodMatcher ใช้เพื่อตรวจสอบว่าวิธีการของคลาสเป้าหมายสามารถใช้เพื่อใช้การแจ้งเตือนนี้หรือไม่ในขณะที่ ClassFilter ใช้เพื่อตรวจสอบว่าควรใช้ pointcut กับคลาสเป้าหมายหรือไม่
บทนำ: เพิ่มวิธีการหรือฟิลด์ในคลาสที่ได้รับแจ้ง สปริงอนุญาตให้มีการแนะนำอินเทอร์เฟซใหม่ให้กับวัตถุใด ๆ ที่ได้รับแจ้ง ตัวอย่างเช่นคุณสามารถทำให้การแคชง่ายขึ้นโดยใช้บทนำที่ช่วยให้วัตถุใด ๆ สามารถใช้อินเตอร์เฟส Ismodified ได้ หากต้องการใช้บทนำในฤดูใบไม้ผลิคุณสามารถใช้ DelegatingIntroductionInterceptor เพื่อใช้การแจ้งเตือนและใช้ DefaultIntroductionAdvisor เพื่อกำหนดค่าอินเทอร์เฟซเพื่อใช้คำแนะนำและคลาสพร็อกซี
วัตถุเป้าหมาย: วัตถุที่มีจุดเชื่อมต่อ ยังเป็นที่รู้จักกันในชื่อวัตถุที่ได้รับการแจ้งเตือนหรือพร็อกซี ปอโจ
AOP Proxy: วัตถุที่สร้างขึ้นโดย AOP Framework ซึ่งมีการแจ้งเตือน ในฤดูใบไม้ผลิพร็อกซี AOP สามารถเป็นพร็อกซีไดนามิก JDK หรือพร็อกซี CGLIB
การทอผ้า: ประกอบเพื่อสร้างวัตถุที่ได้รับการแจ้งเตือน ซึ่งสามารถทำได้ในเวลาคอมไพล์ (ตัวอย่างเช่นการใช้คอมไพเลอร์ APPERSJ) หรือที่รันไทม์ ฤดูใบไม้ผลิเช่นเดียวกับเฟรมเวิร์ก Java AOP บริสุทธิ์อื่น ๆ เสร็จสิ้นการทอผ้าที่รันไทม์
สปริงส่วนประกอบ AOP
แผนภาพคลาสต่อไปนี้แสดงรายการส่วนประกอบ AOP หลักในฤดูใบไม้ผลิ
วิธีใช้สปริง AOP
สปริง AOP สามารถใช้ในไฟล์การกำหนดค่าหรือวิธีการเขียนโปรแกรม
การกำหนดค่าสามารถทำได้ผ่านไฟล์ XML และมีประมาณสี่วิธี:
1. กำหนดค่า ProxyFactoryBean, ที่ปรึกษาที่ตั้งไว้อย่างชัดเจนคำแนะนำ, เป้าหมาย ฯลฯ
2. กำหนดค่า autoproxycreator ด้วยวิธีนี้ถั่วที่กำหนดยังคงใช้เหมือนเดิม แต่สิ่งที่คุณได้รับจากคอนเทนเนอร์เป็นวัตถุพร็อกซีจริง
3. กำหนดค่าผ่าน <AOP: config>
4. กำหนดค่าผ่าน <AOP: ASPACTJ-AUTOPROXY> และใช้คำอธิบายประกอบด้านเพื่อระบุการแจ้งเตือนและจุดเข้า
คุณยังสามารถใช้ ProxyFactory โดยตรงเพื่อใช้ Spring AOP โดยทางโปรแกรม ด้วยวิธีการที่จัดทำโดย ProxyFactory คุณสามารถตั้งค่าวัตถุเป้าหมายที่ปรึกษาและการกำหนดค่าอื่น ๆ ที่เกี่ยวข้องและในที่สุดก็รับวัตถุพร็อกซีผ่านวิธี getProxy ()
ตัวอย่างเฉพาะของการใช้งานสามารถเป็น Google ละเว้นที่นี่
การสร้างวัตถุพร็อกซีฤดูใบไม้ผลิ AOP
ฤดูใบไม้ผลิมีสองวิธีในการสร้างวัตถุพร็อกซี: jdkproxy และ cglib วิธีการเฉพาะของการสร้างถูกกำหนดโดย AOPProxyFactory ตามการกำหนดค่าของวัตถุที่แนะนำ นโยบายเริ่มต้นคือการใช้เทคโนโลยีพร็อกซีไดนามิก JDK หากคลาสเป้าหมายเป็นอินเทอร์เฟซมิฉะนั้นใช้ CGLIB เพื่อสร้างพร็อกซี มาศึกษาว่าฤดูใบไม้ผลิใช้ JDK เพื่อสร้างวัตถุพร็อกซีอย่างไร รหัสการสร้างเฉพาะถูกวางไว้ในคลาส JDKDYNAMICAPROXY และรหัสที่เกี่ยวข้องจะถูกเพิ่มโดยตรง:
/** * <ol> * <li> รับอินเทอร์เฟซที่จะนำไปใช้โดยคลาสพร็อกซี นอกเหนือจากการกำหนดค่าในวัตถุที่ได้รับคำแนะนำแล้ว SpringProxy จะถูกเพิ่มแนะนำ (opaque = false) * <li> ตรวจสอบว่ามีอินเทอร์เฟซที่กำหนดเท่ากับหรือ hashcode ในอินเทอร์เฟซที่ได้รับข้างต้น * <li> การเรียก proxy.newproxyinstance เพื่อสร้างวัตถุพร็อกซี (logger.isdebugenabled ()) {logger.debug ("การสร้างพร็อกซีไดนามิก JDK: แหล่งเป้าหมายคือ" +this.adh.getTargetSource ()); } คลาส [] proxiedInterfaces = aopproxyutils.completeproxiedinterfaces (this.vised); finddefinedequalsandhashcodeMethods (proxiedinterfaces); ส่งคืน proxy.newproxyinstance (classloader, proxiedinterfaces, this); - แล้วนี่ก็ชัดเจนมาก ฉันได้เขียนความคิดเห็นอย่างชัดเจนแล้วและจะไม่ทำซ้ำอีกครั้ง
คำถามต่อไปนี้คือวัตถุพร็อกซีถูกสร้างขึ้นพื้นผิวที่ถูกตัดจะทออย่างไร?
เรารู้ว่า InvocationHandler เป็นแกนหลักของพร็อกซี JDK Dynamic และวิธีการเรียกใช้ของวัตถุพร็อกซีที่สร้างขึ้นจะได้รับการมอบหมายไปยังเมธอด InvocationHandler.invoke () ผ่านลายเซ็นของ Jdkdynamicaopproxy เราจะเห็นได้ว่าคลาสนี้ใช้งานจริง ลองมาดูกันว่า Spring AOP สานเข้ากับส่วนโดยการวิเคราะห์วิธีการของ Invoke () ที่ใช้ในชั้นเรียนนี้อย่างไร
PublicObject revoke (พร็อกซีวัตถุวิธีวิธี, วัตถุ [] args) throwsthrowable {methodInvocation chocation = null; Object OldProxy = null; บูลีน setProxyContext = false; TargetSource TargetSource = this.adhised.targetSource; คลาส targetClass = null; เป้าหมายวัตถุ = null; ลองใช้เมธอด {// eqauls () วัตถุเป้าหมายไม่ได้ใช้วิธีนี้ถ้า (! this.equalsdefined && aoputils.isequalsmethod (วิธีการ)) {return (equals (args [0])? boolean.true: boolean.false); } // วิธีการ HashCode () วัตถุเป้าหมายไม่ได้ใช้วิธีนี้ถ้า (! this.hashCodeDefined && aoputils.ishashCodeMethod (วิธีการ)) {return newInteger (hashCode ()); } // คำแนะนำอินเทอร์เฟซหรือวิธีการที่กำหนดไว้ในส่วนต่อประสานหลักสะท้อนการโทรโดยตรงและไม่ได้ใช้การแจ้งเตือนถ้า (! this.advised.opaque && method.getDeclaringClass (). isInterface () && method.getDeclaringClass () aoputils.invokejoinpointusingrefletion (this.vised, method, args); } วัตถุ retval = null; if (this.advised.exposeproxy) {// ทำการเรียกใช้งานที่จำเป็น oldproxy = aopcontext.setCurrentProxy (พร็อกซี); setProxyContext = true; } // รับเป้าหมายคลาสของวัตถุเป้าหมาย = targetSource.getTarget (); if (target! = null) {targetClass = target.getClass (); } // รับรายการ interceptor ที่สามารถนำไปใช้กับวิธีการนี้ list chain = this.adhing.getInterceptorsandDynamicInterceptionAdvice (วิธีการ, targetClass); // หากไม่มีการแจ้งเตือนที่สามารถนำไปใช้กับวิธีนี้ (interceptor) วิธีการโทรสะท้อนโดยตรงนี้ invoke (เป้าหมาย, args) ถ้า (chain.isempty ()) {retval = aoputils.invokejoinpointusingrefletion (เป้าหมาย, วิธีการ, args); } else {// สร้าง methodInvocation Invocation = newRefleCtiveMethodInVocation (พร็อกซี, เป้าหมาย, วิธี, args, targetClass, โซ่); retval = rachation.proceed (); } // ค่าคืนการนวดหากจำเป็น if (retval! = null && retval == target && method.getReturntype (). isinstance (พร็อกซี) &&! rawtargetaccess.class.isassignablefrom (method.getDeclaringClass ()) {// กรณีพิเศษ: สังเกตว่าเราไม่สามารถช่วยได้หากเป้าหมายตั้งค่า // การอ้างอิงถึงตัวเองที่ส่งคืนวัตถุ retval = พร็อกซี; } return retval; } ในที่สุด {ถ้า (target! = null &&! targetSource.isstatic ()) {// ต้องมา FromTargetSource TargetSource.releasetarget (เป้าหมาย); } if (setProxyContext) {// คืนค่าพร็อกซีเก่า aopcontext.setCurrentProxy (oldproxy); - กระบวนการหลักสามารถอธิบายได้สั้น ๆ ว่า: การได้รับห่วงโซ่การแจ้งเตือนที่สามารถนำไปใช้กับวิธีนี้ (ห่วงโซ่ interceptor) หากมีให้ใช้การแจ้งเตือนและดำเนินการ joinpoint; หากไม่มีให้สะท้อนถึงจุดเข้าร่วมโดยตรง กุญแจสำคัญในที่นี้คือวิธีการที่ได้รับการแจ้งเตือนและวิธีการดำเนินการ มาวิเคราะห์ทีละคน
ก่อนอื่นจากรหัสข้างต้นเราจะเห็นได้ว่าห่วงโซ่การแจ้งเตือนนั้นได้มาจากวิธีการที่ได้รับคำแนะนำ GetInterceptorSandDynamicInterceptionAdvice () มาดูการใช้วิธีนี้กันเถอะ:
รายการสาธารณะ <Ojrop> GetInterceptorSandDynamicInterceptionAdvice (วิธีการ, คลาส targetClass) {MethodCacheyCycheky Key = methodCachekey ใหม่ (วิธีการ); รายการ <jobch> cached = this.methodcache.get (cachekey); if (cached == null) {cached = this.advisorchainfactory.getInterceptorsandDynamicInterceptionAdvice (นี่, วิธี, targetClass); this.methodcache.put (cachekey, แคช); } returncached; - จะเห็นได้ว่างานซื้อกิจการที่เกิดขึ้นจริงนั้นทำจริงโดย AdvisorChainfactory วิธี GetInterceptorsandDynamicInterceptionAdvice () และผลลัพธ์ที่ได้จะถูกแคช
มาวิเคราะห์การใช้วิธีนี้ด้านล่าง:
/*** รับรายการที่ปรึกษาจากการกำหนดค่าอินสแตนซ์การกำหนดค่าที่ให้ไว้และสำรวจที่ปรึกษาเหล่านี้ หากเป็น IntroductuctionAdvisor ให้พิจารณาว่าที่ปรึกษานี้สามารถนำไปใช้กับ Target Class TargetClass ได้หรือไม่ หากเป็น PointCutAdvisor ให้พิจารณา * ว่าที่ปรึกษานี้สามารถนำไปใช้กับวิธีการเป้าหมายได้หรือไม่ ที่ปรึกษาที่ตรงตามเงื่อนไขจะถูกแปลงเป็นรายการ interceptor ผ่านที่ปรึกษา */ PublicList GetInterceptorSandDynamicInterceptionAdvice (แนะนำการกำหนดค่า, วิธีการ, คลาส targetClass คลาส) {// นี่เป็นเรื่องยุ่งยาก ... เราต้องดำเนินการแนะนำตัวก่อน // แต่เราต้องรักษาลำดับในรายการสุดท้าย รายการ interceptorList = arrayList ใหม่ (config.getAdvisors (). ความยาว); // ตรวจสอบว่า introductionAdvisor boolean hasintroductions = hasmatchingIntroductions (config, targetClass); // ในความเป็นจริงชุดของ Advisoradapters ได้ลงทะเบียนที่นี่เพื่อแปลงที่ปรึกษาให้เป็น MethodInterceptor Advisoradapterregistry Registry = GlobalAdvisoradapterRegistry.getInstance (); ที่ปรึกษา [] ที่ปรึกษา = config.getAdvisors (); สำหรับ (int i = 0; i <ที่ปรึกษาความยาว; i ++) {ที่ปรึกษาที่ปรึกษา = ที่ปรึกษา [i]; if (ที่ปรึกษาอินสแตนซ์ของ PointCutAdvisor) {// เพิ่มอย่างมีเงื่อนไข PointCutAdvisor PointCutAdvisor = (PointCutAdvisor) ที่ปรึกษา; if (config.isprefiltered () || pointcutadvisor.getpointcut (). getClassFilter (). การจับคู่ (targetClass)) {// todo: ตำแหน่งของวิธีการทั้งสองนี้สามารถเปลี่ยนได้ในสถานที่นี้ // แปลงที่ปรึกษา // ตรวจสอบว่า pointcut ของที่ปรึกษาปัจจุบันสามารถจับคู่วิธีการปัจจุบัน methodmatcher mm = pointcutadvisor.getpointcut (). getMethodmatcher (); ถ้า (methodMatchers.matches (mm, method, targetClass, hasIntroductions)) {ถ้า (mm.isruntime ()) {// การสร้างอินสแตนซ์ newobject ในเมธอด getInterceptors () // ไม่ใช่ปัญหา สำหรับ (intj = 0; j <interceptors.length; j ++) {interceptorlist.add (ใหม่ interceptoranddynamicmethodmatcher (interceptors [j], mm)); }} else {interceptorlist.addall (array.aslist (interceptors)); }}}} อื่นถ้า (ที่ปรึกษาอินสแตนซ์ของบทนำ Advisor) {บทนำ Advisor ia = (บทนำ Advisor) ที่ปรึกษา; if (config.isprefiltered () || ia.getClassFilter (). การจับคู่ (targetClass)) {interceptor [] interceptors = registry.getInterceptors (ที่ปรึกษา); interceptorlist.addall (array.aslist (interceptors)); }} else {interceptor [] interceptors = registry.getInterceptors (ที่ปรึกษา); interceptorlist.addall (array.aslist (interceptors)); }} return interceptorList; - หลังจากใช้วิธีนี้แล้วที่ปรึกษาทั้งหมดที่กำหนดค่าในคำแนะนำที่สามารถนำไปใช้กับจุดเชื่อมต่อหรือคลาสเป้าหมายจะถูกแปลงเป็น methodInterceptor
ต่อไปลองมาดูกันว่าห่วงโซ่ interceptor ที่ได้รับการทำงานอย่างไร
if (chain.isempty ()) {retval = aoputils.invokejoinpointusingrefletion (เป้าหมาย, วิธี, args); } else {// สร้าง methodInvocation Invocation = newRefleCtiveMethodInVocation (พร็อกซี, เป้าหมาย, วิธี, args, targetClass, โซ่); retval = rachation.proceed (); - จากรหัสนี้เราจะเห็นได้ว่าหากห่วงโซ่ interceptor ที่ได้รับนั้นว่างเปล่าวิธีการเป้าหมายจะถูกเรียกโดยตรง มิฉะนั้นจะมีการสร้าง methodInvocation วิธีการกระบวนการจะถูกเรียกและการดำเนินการของห่วงโซ่ interceptor จะถูกเรียกใช้ มาดูรหัสเฉพาะ
วัตถุสาธารณะดำเนินการต่อ () โยนได้ {// เราเริ่มต้นด้วยดัชนี -1 และเพิ่มขึ้นก่อน if (this.currentInterceptorIndex == this.interceptorsandDynamicMethodmatchers.size ()- 1) {// ถ้า interceptor เสร็จสิ้นการดำเนินการเสร็จสิ้นให้ดำเนินการ jointion return invokejoinpoint (); } Object interceptororInterceptionAdvice = this.interceptorsandDynamicMethodmatchers.get (++ this.currentInterceptorIndex); // หากคุณต้องการจับคู่ joinpoint แบบไดนามิกถ้า (InterceptororInterceptionAdvice Instance ของ InterceptorandDynamicMethodmatcher) {// ประเมินวิธีการจับคู่วิธีการไดนามิกที่นี่: ส่วนคงที่จะมี // ได้รับการประเมินและพบว่าตรงกับ InterceptorandDynamicMethodmatcher DM = (InterceptorandDynamicMethodmatcher) InterceptororInterceptionAdvice; // การจับคู่แบบไดนามิก: ไม่ว่าจะเป็นพารามิเตอร์รันไทม์ตรงกับเงื่อนไขการจับคู่หรือไม่ถ้า (dm.methodmatcher.matches (this.method, this.targetClass, this.arguments)) {// ดำเนินการ intercetpordmentdm.interceptor.invoke (นี้); } else {// เมื่อการจับคู่แบบไดนามิกล้มเหลวให้ข้าม intercetpor ปัจจุบันและเรียกขั้นตอนการส่งคืน interceptor ถัดไป (); }} else {// มันเป็น interceptor ดังนั้นเราเพิ่งเรียกใช้มัน: pointcutwill มี // ได้รับการประเมินแบบคงที่ก่อนที่วัตถุนี้จะถูกสร้างขึ้น // ดำเนินการส่งคืน intercetpor ปัจจุบัน ((methodInterceptor) interceptororInterceptionAdvice) .invoke (นี่); -รหัสนั้นค่อนข้างง่ายดังนั้นฉันจะไม่เข้าไปดูรายละเอียดที่นี่
ข้างต้นเป็นเนื้อหาทั้งหมดของบทความนี้ ฉันหวังว่ามันจะเป็นประโยชน์ต่อการเรียนรู้ของทุกคนและฉันหวังว่าทุกคนจะสนับสนุน wulin.com มากขึ้น