1. وضع الوكيل
يسمى نموذج الوكيل بالوكيل أو البديل باللغة الإنجليزية ، ويمكن ترجمة كلاهما على أنه "وكيل" باللغة الصينية. يعني ما يسمى الوكيل أن شخصًا أو مؤسسة ما يتخذ إجراءً نيابة عن شخص آخر أو مؤسسة أخرى. في بعض الحالات ، لا يريد العميل أو لا يمكنه الإشارة مباشرة إلى كائن ، ويمكن أن يعمل كائن الوكيل كوسيط بين العميل والكائن الهدف.
اشرح الاختلافات بين مختلف العوامل عن طريق محاكاة عملية تنفيذ المعاملات ببساطة
1.1 وكيل ثابت
يتم إنشاء التعليمات البرمجية المصدر بواسطة المبرمجين أو تم إنشاؤها تلقائيًا بواسطة أدوات محددة ثم تم تجميعها. قبل تشغيل البرنامج ، يوجد ملف .class لفئة الوكيل بالفعل.
الواجهة العامة persondao {void savePerson () ؛} الطبقة العامة persondaoimpl تنفذ persondao {Override public void savePerson () {system.out.println ("Save Person") ؛ }} معاملة الفئة العامة {void beginTransaction () {system.out.println ("start transaction") ؛ } void commice () {system.out.println ("commit") ؛ }}بعد ذلك ، اكتب فئة وكيل ثابت --- قم بتنفيذ واجهة persondao
/*** فئة الوكيل الثابت* Author qjc*/الطبقة العامة persondaoproxy تنفذ persondao {persondao persondao ؛ معاملة المعاملة ؛ persondaoproxy العام (persondao persondao ، معاملة المعاملة) {this.persondao = persondao ؛ this.transaction = المعاملة ؛ } override public void savePerson () {this.transaction.begintransaction () ؛ this.persondao.saveperson () ؛ this.transaction.commit () ؛ }}امتحان
/*** Test static proxy* Author qjc*/public class testpersonproxy {test public void testSave () {persondao persondao = new persondaoimpl () ؛ معاملة المعاملة = معاملة جديدة () ؛ persondaoproxy proxy = new persondaoproxy (persondao ، Transaction) ؛ proxy.saveperson () ؛ }}تلخيص:
1. وضع الوكيل الثابت لا يعيد استخدام المعاملات
2. لنفترض أن هناك 100 فئة و 100 وكيل. كم عدد الطرق الموجودة في الواجهة ، وعدد الطرق التي يجب تنفيذها في طبقة الوكيل ، وعدد المعاملات التي يجب فتحها وتقديمها أكبر عدد من الطرق.
3. إذا قام الوكيل بتنفيذ واجهات متعددة ، إذا تم تغيير أحد الواجهات (تمت إضافة طريقة) ، فيجب أن يتغير الوكيل أيضًا وفقًا لذلك.
1.2 الوكيل الديناميكي JDK
فئة الوكيل الديناميكي: يتم إنشاؤه ديناميكيًا باستخدام آلية الانعكاس عند تشغيل البرنامج.
يجب أن يفي الوكيل الديناميكي لـ JDK بأربعة شروط: 1. الواجهة الهدف 2. الفئة الهدف 3. اعتراض 4.
باستخدام واجهة persondao ، فئة persondaoimpl و الطبقة المعاملة في المثال السابق
اكتب اعتراضًا
استيراد java.lang.reflect.invocationHandler ؛ استيراد java.lang.reflect.method ؛/** * interceptor * 1. استيراد فئة الهدف في * 2. // Target Class Private Transaction ؛ اعتراض عام (هدف الكائن ، معاملة المعاملة) {this.target = target ؛ this.transaction = المعاملة ؛ ) {String methodName = method.getName () ؛ if ("SavePerson" .equals (methodName) || "deleteperson" .equals (methodName) || "updatePerson" .equals (methodName)) {this.transaction.begintransaction () ؛ // تمكين طريقة المعاملة. invoke (الهدف) ؛ // استدعاء الطريقة الهدف this.transaction.commit () ؛ // إرسال المعاملة} آخر {method.invoke (target) ؛ } إرجاع فارغ ؛ }}امتحان
/*** Test JDK Dynamic Proxy* Author qjc*/public class testjdkproxy {test public void testSave () {/*** 1. إنشاء كائن مستهدف* 2. إنشاء معاملة* 3. إنشاء اعتراض* 4. معاملة المعاملة = معاملة جديدة () ؛ اعتراض اعتراض = اعتراض جديد (الهدف ، المعاملة) ؛ /*** المعلمة 1: قم بتعيين محمل الفئة المستخدمة بواسطة الكود ، والذي يستخدم عمومًا نفس فئة محمل الفئة مثل المعلمة الفئة*: اضبط الواجهة التي يتم تنفيذها بواسطة فئة الوكيل ، واستخدم نفس الواجهة مثل الفئة الهدف* المعلمة 3: تعيين كائن الاتصال. عندما يتم استدعاء طريقة كائن الوكيل ، سيتم استدعاء طريقة الاستدعاء للكائن المحدد*/ persondao persondao = (persondao) proxy.newproxyinstance (target.getclass (). getClassloader () ، target.getClass (). persondao.saveperson () ؛ }}تلخيص :
1. نظرًا لأن فئة الوكيل التي تم إنشاؤها بواسطة JDKProxy تنفذ الواجهة ، يتم تضمين جميع الطرق في الفئة المستهدفة في فئة الوكيل.
2. جميع طرق فئة الوكيل التي تم إنشاؤها تعترض جميع طرق الفئة المستهدفة. محتوى طريقة الاستدعاء في التقاطع هو بالضبط تكوين كل طريقة لفئة الوكيل.
3. يجب أن توجد واجهات عند استخدام JDKProxy.
4. يمكن للمعلمات الثلاثة في طريقة Invoke الوصول إلى واجهة برمجة التطبيقات للطريقة المدعومة ، ومعلمات الطريقة المدعوين ، ونوع الإرجاع للطريقة المتصلة بالفئة الهدف.
عيب:
1. في الاعتراض ، باستثناء استدعاء طريقة الهدف للكائن الهدف ، تكون الوظيفة واحدة نسبيًا. في هذا المثال ، يمكن معالجة المعاملات فقط.
2. إن بيان الحكم لطريقة الاستدعاء في التقاطع غير موثوق به في بيئة تطوير حقيقية ، لأنه بمجرد وجود العديد من البيانات ، يجب كتابة ذلك.
1.3 الوكيل الديناميكي CGLIB
استخدم فئة PersondaOimpl و Crasse في المثال السابق (بدون واجهة)
اكتب فئات اعتراض
استيراد net.sf.cglib.proxy.enhancer ؛ استيراد net.sf.cglib.proxy.MethodInterceptor ؛ استيراد net.sf.cglib.proxy.methodproxy ؛/*** cglib interceptor* @author qjc*/public class interceptor etterceptor {private confite targetor ؛ // Proxy Target Class Transaction Transaction ؛ اعتراض عام (هدف الكائن ، معاملة المعاملة) {this.target = target ؛ this.transaction = المعاملة ؛ } / ** * قم بإنشاء كائن وكيل للكائن الهدف * * regurn * / كائن عام CreateProxy () {// code endancement endancer ensancer = new ensancer () ؛ // يتم استخدام هذه الفئة لإنشاء محسن كائن الوكيل. // المعلمة هي المحسّن التقاطع. // إنشاء كائن وكيل}/ *** param obj مثيل من فئة بروكسي كائن الهدف* طريقة طريقة طريقة param التي تستدعي طريقة الفئة الأصل على مثيل الوكيل* param args args shen surray من الكائنات التي تم تمريرها في قيم المعلمة method على مثيل proxy* param methodeproxy استخدمها لاستدعاء طريقة الوالد* Object [] args ، methodproxy methodproxy) يلقي رمي {this.transaction.begintransaction () ؛ method.invoke (Target) ؛ this.transaction.commit () ؛ العودة لاغية. }}امتحان
/*** اختبار cglib الوكيل الديناميكي* كائن الوكيل الذي تم إنشاؤه من خلال CGLIB ، فئة الوكيل هي فئة فرعية للفئة الهدف* Author qjc*/فئة عامة testcglibproxy {test public void testSave () {object = new persondaoimpl () ؛ معاملة المعاملة = معاملة جديدة () ؛ اعتراض اعتراض = اعتراض جديد (الهدف ، المعاملة) ؛ persondaoimpl persondaoimpl = (persondaoimpl) interceptor.createproxy () ؛ persondaoimpl.saveperson () ؛ }}تلخيص:
1. CGLIB هي مكتبة فئة قوية وتوليد الكود عالية الجودة. يمكن أن تمدد فصول Java وتنفيذ واجهات Java أثناء وقت التشغيل.
2. استخدم CGLIB لإنشاء فئة بالوكالة كفئة فرعية للفئة المستهدفة.
3. لا يلزم وجود واجهة لإنشاء فئات وكيل باستخدام CGLIB
4. فئة الوكيل التي تم إنشاؤها بواسطة CGLIB تتجاوز طرق الفئة الأصل.
5. محتوى طريقة التقاطع في التقاطع هو بالضبط الفرق بين الطريقة Cglib و JDK الوكيل الديناميكي في فئة الوكيل:
JDK:
تنفذ الفئة المستهدفة وفئة الوكيل واجهة مشتركة
يجب أن يقوم المعترض بتنفيذ واجهة InvocationHandler ، ومحتوى هيكل طريقة الاستدعاء في هذه الواجهة هو محتوى هيكل طريقة كائن الوكيل.
cglib:
الفئة المستهدفة هي الفئة الأم لفئة الوكيل
يجب أن ينفذ التقاطع واجهة MethodInterceptor ، وأن طريقة التقاطع في الواجهة هي هيئة فئة الوكيل ، ويتم استخدام آلية تعزيز Bytecode لإنشاء كائن الوكيل.
2. البرمجة الموجهة نحو
OOP (البرمجة الموجهة للكائن): التغليف ، الميراث ، تعدد الأشكال ، التجريد
التغليف ، الإدارة الأساسية والمعيارية للرمز. قد يكون لكل فصل وظائفه الخاصة. إذا حدث خطأ ما ، فقط ابحث عن شخص ما لمناقشة الأمر. من منظور التعديل ، قد يكون من المخاطرة تعديل الكود مباشرة. هذا ليس حلًا طويل الأجل. الشيء الأكثر طبيعية هو التغيير من تغليف النوع. ومع ذلك ، كيفية دمج الأنواع الجديدة والأنظمة القديمة ، لذلك من الضروري إنشاء علاقة دم بين الطبقات. ثم هذا هو شرط الميراث. من خلال الميراث ، يمكنك أن تجد أن هذه الفئات مرتبطة وهناك علاقة الأب والابن بينهما. ثم ، على أساس الميراث ، تعدد الأشكال لها خصائص حاسمة. لذلك ، يُعتقد عمومًا أن الميزة الأكثر جوهرية للموجهة نحو الكائن هي في الواقع تعدد الأشكال. القلة الأولى هي جميع وضع الأساس. تعدد الأشكال هو الميزة الأساسية. تمثل طريقة إعادة الكتابة في الفئة الفرعية امتداد هذا المستوى ، ويمكن دمجها في النظام القديم ويمكن أن تعمل بشكل طبيعي. هذا هو إعادة استخدام هذا المستوى ، والأساليب الجديدة ، والأنظمة القديمة ، والإضافات وإعادة الاستخدام.
AOP (البرمجة الموجهة نحو القسم):
البرمجة الأساسية هي تقنية تضيف وظائف ديناميكية إلى البرامج دون تعديل الكود المصدر من خلال الوكيل الديناميكي للوقت المسبق.
الفرق بين OOP و AOP:
OOP: يتم تنفيذ التغليف التجريدي على الكيانات وخصائصها وسلوكياتها في عملية معالجة الأعمال للحصول على تقسيم أوضح من الوحدات المنطقية.
AOP: يستخرج منطق الشق المتقاطع في عملية الأعمال. يواجه خطوة أو مرحلة معينة في العملية للحصول على تأثير عزل الاقتران المنخفض بين أجزاء عملية المنطق. هاتان أفكار التصميم لهما اختلافات أساسية في الأهداف. حقق AOP إعادة استخدام كتل الكود.
آلية بروكسي الربيع AOP:
1. إذا كان الكائن المستهدف ينفذ عدة واجهات ، فإن Spring يستخدم JDK's Java.lang.reflect.proxy proxy.
المزايا: نظرًا لوجود واجهة ، يكون النظام مقترنًا بشكل أكثر فضفاضة
العيوب: قم بإنشاء واجهات لكل فئة مستهدفة
2. إذا كان الكائن الهدف لا ينفذ أي واجهة ، فإن Spring يستخدم مكتبة CGLIB لإنشاء فئة فرعية من الكائن الهدف.
المزايا: نظرًا لأن فئة الوكيل والفئة المستهدفة موروثة ، فليس هناك حاجة لوجود واجهة.
العيوب: نظرًا لعدم وجود واجهة مستخدمة ، فإن اقتران النظام ليس جيدًا مثل الوكيل الديناميكي باستخدام JDK.
باستخدام واجهة persondao ، فئة persondaoimpl ، وفئة المعاملات
اكتب تكوين الربيع
<bean id = "persondao"> </bean> <bean id = "Transaction"> </bean> <aop: config> <!-تعبير pointcut يحدد الفئة الهدف-> <aop: pointcut expression = "execution (* cn.qjc.aop.xml.persondaoimpl.* (..) ref = "Transaction"> <aop: قبل method = "startransaction" pointcut-ref = "perform"/> <aop: method-reghensing method = "comming" pointcut-ref = "perform"/> </aop: side> </ aop: config> </bans>
امتحان
/*** اختبار Spring Spring Dynamic Proxy* Author qjc*/Class Public TransactionTest {test public void testSave () {ApplicationContext context = new ClassPathMlapPlicationContext ("CN/QJC/AOP/XML/ApplicationContext.xml") ؛ persondao persondao = (persondao) context.getBean ("persondao") ؛ persondao.saveperson () ؛ }}مبدأ الربيع AOP
1. عند بدء تشغيل حاوية الربيع ، يتم تحميل فاصوليا وتثبيتها.
2. عندما تقوم حاوية Spring بتوزيع ملف التكوين إلى <aOP: config> ، تحليل التعبير النقوي ويتطابق مع حبوب محتوى حاوية الزنبرك وفقًا للتعبير المقطوع.
3. إذا نجحت المباراة ، قم بإنشاء كائن وكيل للفول
4. عندما يستخدم العميل context.getBean للحصول على كائن ، إذا كان الكائن يحتوي على كائن وكيل ، فإنه يعيد كائن الوكيل. إذا لم يكن هناك كائن وكيل ، فإنه يعيد الكائن نفسه.
ما سبق هو كل محتوى هذه المقالة. آمل أن يكون ذلك مفيدًا لتعلم الجميع وآمل أن يدعم الجميع wulin.com أكثر.