آلية انعكاس Java والوكالة الديناميكية تجعل Java أكثر قوة. يتم تنفيذ المفاهيم الأساسية لـ Spring IOC و AOP من خلال آلية الانعكاس والوكيل الديناميكي.
1 انعكاس جافا
مثال:
مستخدم المستخدم = مستخدم جديد () ؛ user.settime5flag ("اختبار") ؛ class <؟> cls = class.forname ("com.test.user") ؛ يجب أن تكون الواجهة عامة ، بغض النظر عما إذا كانت تستخدم داخليًا في هذه الفئة! إما استخدام cls.getDeclaredMethod () ، أو اجتياز لتعديل طريقة إمكانية الوصول = cls.getMethod ("getTime5Flag") ؛ string res1 = (String) method.invoke (user) ؛ System.out.println (res1) ؛ // إذا كنت تتضمن أنواعًا أساسية مثل int ، استخدم int.class! integer.class! = int.class! method = cls.getMethod ("setTime5Flag" ، string.class) ؛ method.invoke (المستخدم ، "Rollen") ؛ الطريقة = cls.getMethod ("getTime5Flag") ؛ string res2 = (string) method.invoke (user) ؛ system.out.println (res2) ؛الحصول على الحزمة الكاملة واسم الفئة من خلال كائن:
user.getClass (). getName () ؛ // اسم فئة المسار الكامل user.getClass ().
الحصول على الفصل:
class.forname ("com.test.user") ؛ com.test.user.class ؛ user.getClass () ؛ إنشاء كائن من خلال الفصلمستخدم المستخدم = (المستخدم) cls.newinstance () ؛ // يجب أن يكون هناك مُنشئ للمعلماتاحصل على جميع المنشئين
مُنشئ <؟> cons [] = cls.getConstructors () ؛ // Return Cons [0] .NewInstance () في أمر الإعلان ؛ // لا إعلان عرض ، ثم هناك مُنشئ افتراضياحصل على جميع الواجهات التي تنفذها الفصل
الفئة <؟> intes [] = cls.getInterfaces () ؛احصل على فئة الوالدين
cls.getSuperClass () ؛احصل على المعدل
int mo = cls.getModiFiers () ؛ int mo = cons [0] .getModifiers () ؛ int mo = method.getModifiers () ؛ modifier.toString (mo) ؛الحصول على معلمات الطريقة
method.getParameters () ؛ cons [0] .getParameters () ؛الحصول على نوع المعلمة الطريقة
method.getParametorTypes () ؛ cons [0] .getParametorTypes () ؛احصل على جميع أنواع الاستثناءات التي ألقيتها إعلان الطريقة
method.getExceptionTypes () ؛احصل على جميع الخصائص التي تم إعلانها في هذا الفصل
الحقل [] الحقل = cls.getDeclaredFields () ؛ // تشمل Privatefield [0] .getModifiers () ؛ الحقل [0] .gettype () ؛
احصل على جميع السمات العامة لهذه الفئة ، بما في ذلك إعلان فئة الوالدين ، وإعلان الواجهة ، وجميع السمات العامة لهذا الإعلان الفني
cls.getfields () ؛
قم بتعيين السمة المحددة للوصول
field.setAccessible (true) ؛ field.set (obj ، 'ces') ؛ field.get (obj) ؛
* الفرق بين getFields () و getDeclaredFields (): يمكن لـ GetFields () الوصول إلى الحقول فقط المعلنة باعتبارها عامة في الفصل. لا يمكنه الوصول إلى الحقول الخاصة ويمكنه الوصول إلى الحقول العامة الموروثة من فصول أخرى. يمكن لـ GetDeclaredFields () الوصول إلى جميع الحقول في الفصل ، والتي لا علاقة لها بالجمهور والخاص والحماية ، ولكن لا يمكن الوصول إلى الحقول الموروثة من فئات أخرى.
* الفرق بين getMethods () و getDeclaredMethods (): يمكن لـ getMethods () الوصول إلى طرق فقط المعلنة باعتبارها عامة في الفصل ، ولا يمكن الوصول إلى الأساليب الخاصة ، ويمكنها الوصول إلى الأساليب العامة الموروثة من فصول أخرى ؛ يمكن لـ GetDeclaredMethods () الوصول إلى جميع الحقول في الفصل ، والتي لا علاقة لها بالجمهور والخاص والحماية ، ولا يمكنها الوصول إلى الأساليب الموروثة من فئات أخرى.
* الفرق بين getConstructors () و getDeclaredConstructors (): يمكن لـ getConstructors () الوصول إلى مُنشئين فقط الذين تم الإعلان عنهما في الفصل ؛ يمكن لـ GetDeclaredConstructors () الوصول إلى جميع المنشئين في الفصل ، ولا علاقة له بالجمهور والخاص والحماية.
احصل على معلومات الصفيف وتعديلها من خلال التفكير
int [] temp = {1،2،3،4،5} ؛ class <؟> demo = temp.getClass (). getComponentType () ؛ system.out.println ("نوع Array:"+demo.getName () من المصفوفة: "+array.get (temp ، 0)) ؛ // 1array.set (temp ، 0 ، 100) ؛ system.out.println (" العنصر الأول من الصفيف بعد التعديل هو: "+Array.get (temp ، 0)) ؛ // 100) احصل على نوع الصفيفcls.getComponentType () ؛حدد ما إذا كان نوع صفيف
cls.isarray () ؛
2 Java Agent
نموذج الوكيل هو نموذج تصميم Java شائع الاستخدام. خاصتها هي أن فئة الوكيل وفئة المندوب لها نفس الواجهة. فئة الوكيل مسؤولة بشكل أساسي عن رسائل المعالجة المسبقة ، وتصفية الرسائل ، وإعادة توجيه الرسائل إلى فئة المندوب ، ومعالجة الرسائل بعد الحدث. عادة ما يكون هناك ارتباط بين فئة الوكيل وفئة المندوب. يرتبط كائن فئة الوكيل بكائن فئة مندوب. لا يقوم كائن فئة الوكيل نفسها بتنفيذ الخدمة حقًا ، ولكنه يوفر خدمات محددة من خلال استدعاء الأساليب ذات الصلة لكائن فئة المندوب.
وفقًا لفترة إنشاء الوكيل ، يمكن تقسيم فئات الوكيل إلى نوعين.
• الوكيل الثابت: تم إنشاؤه بواسطة المبرمجين أو إنشاء رمز المصدر تلقائيًا عن طريق أدوات محددة ثم يجمعها. قبل تشغيل البرنامج ، يوجد ملف .class لفئة الوكيل بالفعل.
• الوكيل الديناميكي: عند تشغيل البرنامج ، يتم إنشاء رمز BYTECODE ديناميكيًا بواسطة آلية انعكاس JAVA.
2.1 وكيل ثابت
عدد الواجهة العامة عدد {public void querycount () ؛} counttimpl countimpl public count {public void querycount () {system.out.println ("طريقة عرض طريقة حساب ...") ؛ }} // Proxy Class Public Cluperements count {private countimpl countimpl ؛ public countproxy (countimpl countimpl) {this.countimpl = countimpl ؛ } Override public void queryCount () {system.out.println ("قبل معالجة المعاملات") ؛ countimpl.querycount () ؛ // استدعاء طريقة فئة المندوبين ؛ System.out.println ("بعد معالجة المعاملات") ؛ }} // فئة الاختبار الفئة العامة TestCount {public static void main (string [] args) {countimpl countimpl = new countimpl () ؛ countproxy countproxy = new countproxy (countimpl) ؛ countproxy.querycount () ؛ }}راقب الرمز واكتشف أن كل فئة وكيل يمكن أن تخدم واجهة واحدة فقط ، بحيث يحدث الكثير من الوكيل حتماً في تطوير البرنامج. علاوة على ذلك ، جميع عمليات الوكيل باستثناء الطرق المختلفة للاتصال ، جميع العمليات الأخرى هي نفسها ، لذلك يجب تكرار الكود في هذا الوقت. أفضل طريقة لحل هذه المشكلة هي إكمال جميع وظائف الوكيل من خلال فئة وكيل ، لذلك يجب أن يتم ذلك باستخدام الوكيل الديناميكي في هذا الوقت.
2.2 الوكيل الديناميكي
يتم إنشاء رمز bytecode لفئة الوكيل الديناميكي ديناميكيًا بواسطة آلية انعكاس Java عند تشغيل البرنامج ، دون الحاجة إلى كتابة المبرمجين في رمز المصدر يدويًا. لا تقوم فئات الوكيل الديناميكي بتبسيط البرمجة فحسب ، بل تعمل أيضًا على تحسين قابلية توسيع نطاق أنظمة البرمجيات ، لأن آلية انعكاس Java يمكن أن تولد أي نوع من فئات الوكيل الديناميكية.
2.2.1 الوكيل الديناميكي JDK
توفر واجهات فئة الوكيل و InvocationHandler في حزمة java.lang.reflect القدرة على توليد فئات وكيل ديناميكي.
واجهة InvocationHandler:
الواجهة العامة InvocationHandler {
استدعاء الكائن العام (وكيل الكائن ، طريقة الطريقة ، الكائن [] args) رمي رمي ؛
}
وصف المعلمة:
وكيل الكائن: يشير إلى أن الكائن يجري الوكيل.
الطريقة: الطريقة التي سيتم استدعاؤها
كائن [] args: المعلمات المطلوبة عند استدعاء الطريقة
يمكنك التفكير في فئة فرعية لواجهة InvocationHandler باعتبارها فئة التشغيل النهائية من الوكيل ، لتحل محل proxysubject.
فئة الوكيل:
فئة الوكيل هي فئة تشغيل متخصصة في الوكيل. يمكن أن يولد فئات التنفيذ ديناميكيًا لواجهة واحدة أو أكثر من خلال هذه الفئة. يوفر هذا الفصل طرق التشغيل التالية:
كائن ثابت عام NewProxyInstance (Loader ClassLoader ، فئة <؟> [] واجهات ، invocationHandler H) يلقي alfictalargumentexception
وصف المعلمة:
تحميل classloader: تحميل فئة
فئة <؟> [] واجهات: احصل على جميع الواجهات
InvocationHandler H: الحصول على مثيل الفئة الفرعية لواجهة InvocationHandler
إذا كنت ترغب في إكمال وكيل ديناميكي ، فأنت بحاجة أولاً إلى تحديد فئة فرعية لواجهة InvocationHandler لإكمال التشغيل المحدد للوكيل.
Onterface Office {public string says (string name ، int age) ؛} class realSubject تنفذ الموضوع {Override public string يقول (اسم السلسلة ، int age) {return name + "" + age ؛ }} // JDK Dynamic Proxy Class MyInvocationHandler تنفذ InvocationHandler {private object target = null ؛ // ربط كائن المندوب وإرجاع كائن عام من فئة الوكيل (هدف الكائن) {هذا. الهدف = الهدف ؛ return proxy.newproxyinstance (target.getClass (). getClassloader () ، target.getClass (). // ربط الواجهة (CGLIB يتكون لهذا)} Override الكائن العام استدعاء (وكيل الكائن ، الطريقة ، الكائن [] args) يلقي رمي {system.out.println ("قبل الطريقة!") ؛ الكائن temp = method.invoke (الهدف ، args) ؛ System.out.println ("بعد الطريقة!") ؛ عودة درجة الحرارة. }} class hello {public static void main (string [] args) {myinvocationHandler demo = new myinvocationHandler () ؛ الموضوع الفرعي = (الموضوع) demo.bind (new realSubject ()) ؛ معلومات السلسلة = sub.say ("Rollen" ، 20) ؛ System.out.println (info) ؛ }} ومع ذلك ، يعتمد الوكيل الديناميكي لـ JDK على تنفيذ الواجهة. إذا لم تنفذ بعض الفئات واجهات ، فلن تتمكن من استخدام وكيل JDK ، لذلك يحتاجون إلى استخدام الوكيل الديناميكي CGLIB.
2.2.2 الوكيل الديناميكي CGLIB
لا يمكن لآلية الوكيل الديناميكي لـ JDK فقط فئات الوكيل التي تنفذ واجهات ، في حين أن الفئات التي لا تنفذ واجهات لا يمكنها تنفيذ الوكيل الديناميكي لـ JDK.
CGLIB ينفذ الوكيل للفصول. مبدأها هو إنشاء فئة فرعية للفئة المستهدفة المحددة وتجاوز تحسين تنفيذ الطريقة. ومع ذلك ، نظرًا لاستخدام الميراث ، لا يمكن أن يكون الفئة المعدلة النهائية وكيلًا.
الواجهة العامة bookfacade {public void addbook () ؛ } الفئة العامة bookfacadeimpl1 {public void addbook () {system.out.println ("الطريقة العادية لإضافة كتب ...") ؛ }} استيراد java.lang.reflect.method ؛ استيراد net.sf.cglib.proxy.enhancer ؛ استيراد net.sf.cglib.proxy.methodinterceptor ؛ استيراد net.sf.cglib.proxy.methodproxy ؛ // CGLIB Dynamic Proxy Class Public Class BookFacAdecglib تنفذ methodInterceptor {private Object Target ؛ // ربط كائن مندوب وإرجاع كائن عام من فئة الوكيل getInstance (هدف الكائن) {this.target = target ؛ Enhancer Enhancer = New Enhancer () ؛ ensancer.SetSuperClass (this.target.getClass ()) ؛ // طريقة رد الاتصال المحسّن. // إنشاء proxy object return ensancer.create () ؛ } Override // طريقة رد الاتصال ، اعتراض الكائن العام (Object OBJ ، طريقة الطريقة ، الكائن [] args ، methodproxy proxy) يلقي رمي {system.out.println ("الدالة start") ؛ الكائن temp = proxy.invokesuper (obj ، args) ؛ System.out.println ("وظيفة الوظيفة") ؛ عودة درجة الحرارة. }} الفئة العامة testcglib {public static void main (string [] args) {bookfacadecglib cglib = new bookfacadecglib () ؛ bookfacadeimpl1 bookcglib = (bookfacadeimpl1) cglib.getinstance (bookfacadeimpl1 () جديد) ؛ bookcglib.addbook () ؛ }}المناقشة الموجزة أعلاه حول انعكاس Java والوكالة هي كل المحتوى الذي أشاركه معك. آمل أن تتمكن من إعطائك مرجعًا وآمل أن تتمكن من دعم wulin.com أكثر.