نموذج الوكيل هو نموذج تصميم Java شائع الاستخدام. خاصتها هي أن فئة الوكيل وفئة المندوب لها نفس الواجهة. فئة الوكيل مسؤولة بشكل أساسي عن رسائل المعالجة المسبقة ، وتصفية الرسائل ، وإعادة توجيه الرسائل إلى فئة المندوب ، ومعالجة الرسائل بعد الحدث. عادة ما يكون هناك ارتباط بين فئة الوكيل وفئة المندوب. يرتبط كائن فئة الوكيل بكائن فئة مندوب. لا يقوم كائن فئة الوكيل نفسها بتنفيذ الخدمة حقًا ، ولكنه يوفر خدمات محددة من خلال استدعاء الأساليب ذات الصلة لكائن فئة المندوبين.
مقارنة بين العديد من تطبيقات الوكيل الديناميكي لجافا
واجهة
واجهة addInterface {int add (int a ، int b) ؛} الواجهة الفرعية {int sub (int a ، int b) ؛} فئة التنفيذ
أدوات الحساب الفئة AddInterface ، واجهة فرعية {Override Public int sub (int a ، int b) {return ab ؛ } Override public int add (int a ، int b) {return a+b ؛ }}الطريقة 1: الوكيل الديناميكي مدمج في JDK
1. طريقة التنفيذ
تتيح لنا آلية الوكيل الديناميكي التي أدخلتها Java بعد JDK1.3 إنشاء فئات وكيل ديناميكي أثناء التشغيل. يتطلب تطبيق AOP باستخدام الوكيل الديناميكي أربعة أدوار: فئة الوكيل ، وواجهة فئة الوكيل ، وجهاز النسيج ، و InvocationHandler. يستخدم جهاز النسيج آلية انعكاس الواجهة لإنشاء فئة وكيل ، ثم نسج رمز في فئة الوكيل هذه. فئة الوكيل هو الهدف المذكور في AOP. InvocationHandler هو قسم ، يحتوي على نصيحة و pointcut.
2. تنفيذ واجهة VinvocationHandler
class jdkdpqueryHandler تنفذ invocationHandler {private arithmetic real ؛ العام jdkdpqueryHandler (الحساب الحقيقي) {this.real = real ؛ } Override public object invoke (Proxy Object ، method method ، Object [] args) remable {string methodName = method.getName () ؛ system.out.println (method) ؛ System.out.println ("الطريقة:" + methodname + "start ، المعلمات:" + arrays.aslist (args)) ؛ نتيجة الكائن = method.invoke (حقيقي ، args) ؛ System.out.println ("الطريقة:"+methodname+"تنتهي ، النتيجة:"+نتيجة) ؛ نتيجة العودة }}3. قم بإنشاء فئة وكيل واتصل بفئة الوكيل
الطبقة العامة الرئيسية {private static int a = 4 ، b = 2 ؛ كائن ثابت عام createjdkproxy (حساب حقيقي) {كائن proxyarithmetic = proxy.newproxyinstance (real.getClass (). getClassloader () ، real.getClass (). إرجاع البروكسياريتميتيك ؛ } public static void main (string [] args) {arithmetic real = new Arithmetic () ؛ الكائن proxyarithmetic = createJdkProxy (حقيقي) ؛ ((addInterface) proxyarithmetic) .add (a ، b) ؛ ((واجهة فرعية) proxyarithmetic) .sub (a ، b) ؛ }}الطريقة 2: توليد باخرة ديناميكية (CGLIB)
1. طريقة التنفيذ
المحسن والمستقبل. يمكن استخدام المحسن لإنشاء فئة ديناميكية ، والتي يمكن أن ترث فئة محددة وتنفيذ بعض الواجهات المحددة. في الوقت نفسه ، يحتاج المحسن إلى تحديد رد اتصال قبل إنشاء فصل. عندما يتم استدعاء طريقة الفصل ، يتم تعيين تنفيذ الطريقة لهذا رد الاتصال. MethodInterceptor عبارة عن واجهة أكثر استخدامًا ورثتها من رد الاتصال ، ولديها فقط إعلان طريقة واحدة.
2. مقارنة بين الواجهة invocationHandler (في JDK) و interface MethodInterceptor (في CGLIB)
يمتد MethodInterceptor الواجهة العامة Callback {اعتراض الكائن العام (Object OBJ ، Java.lang.reflect.method method ، Object [] args ، methodproxy proxy) رمي رمي ؛ } الواجهة العامة invocationHandler {الكائن العام استدعاء (وكيل الكائن ، طريقة الطريقة ، الكائن [] args) رمي رمي ؛ } من حيث تكوين المعلمة ، فإن معلمات الإدخال من مفهوم MethodInterpector هي 1 أكثر من InvOcketHandler. في الواقع ، فإن معنى كائنات المعلمة الثلاثة الأولى هو نفس معنى InvocationHandler.
تشير المعلمة الأولى إلى كائن طريقة الاتصال التي تأتي منها ؛
تمثل المعلمة الثانية كائن الطريقة الذي يدعو الطريقة ؛
تمثل المعلمة الثالثة قائمة معلمات الإدخال لهذه المكالمة ؛
المعلمات الإضافية هي من نوع methodproxy ، والتي يجب أن تكون كائنًا تم إنشاؤه بواسطة CGLIB لاستبدال كائن الطريقة. سيؤدي استخدام MethodProxy إلى تحسين الكفاءة من استدعاء طريقة طريقة JDK الخاصة مباشرة.
3. إدراك 1
تنفيذ واجهة InternInterceptor
class cglibdPqueryInterceptor تنفذ methodInterceptor {private arithmetic real ؛ cglibdPqueryInterceptor العامة (الحساب الحقيقي) {this.real = real ؛ } override اعتراض الكائن العام (هدف الكائن ، طريقة الطريقة ، الكائن [] args ، methodproxy proxy) يلقي رمي {string methodname = method.getName () ؛ system.out.println (method) ؛ System.out.println ("الطريقة:" + methodname + "start ، المعلمات:" + arrays.aslist (args)) ؛ // object result = method.invoke (real ، args) ؛ // يمكن أن تحصل كلتا الطريقتين على نتيجة الكائن = proxy.invoke (حقيقي ، args) ؛ System.out.println ("الطريقة:"+ methodname+ "تنتهي ، النتيجة:"+ نتيجة) ؛ نتيجة العودة }}قم بإنشاء فئة وكيل واتصل بفصل الوكيل
الطبقة العامة الرئيسية {private static int a = 4 ، b = 2 ؛ كائن ثابت عام CreateCglibproxy (الحساب الحقيقي) {ensancer ensancer = جديد ensancer () ؛ ensancer.setCallback (CglibdPqueryInterceptor (حقيقي) جديد) ؛ ensancer.setInterfaces (real.getClass (). getInterfaces ()) ؛ إرجاع ensancer.create () ؛ } public static void main (string [] args) {arithmetic real = new Arithmetic () ؛ كائن proxyarithmetic = createCglibproxy (حقيقي) ؛ ((addInterface) proxyarithmetic) .add (a ، b) ؛ ((واجهة فرعية) proxyarithmetic) .sub (a ، b) ؛ }}لاحظ أن MethodProxy يوفر طريقتين عند تنفيذ وظائف.
استدعاء الكائن العام (كائن OBJ ، كائن [] args) يلقي الكائن العام القابل للاستخلاص (كائن OBJ ، كائن [] args) رمي رمي القابلة للتسمية
من بينها ، يقول Javadoc أنه يمكن استخدام طريقة الاستدعاء () لتنفيذ كائنات أخرى في نفس الفئة ، أي أن OBJ في هذه الطريقة يحتاج إلى أن ينتقل إلى كائن آخر من نفس الفئة (الطريقة المذكورة أعلاه هي الانتقال إلى كائنات مختلفة من الفئة الحسابية) ، وإلا فإنه سيدخل إلى حلقة عدوانية (stackoverflowerror تظهر حقًا بعد الاختبار). إذا كنت تفكر في الأمر بعناية ، فستجد أن الهدف في اعتراض الكائن العام (هدف الكائن ، طريقة الطريقة ، الكائن [] args ، proxy methodproxy) هو كائن وكيل تم تنفيذه. عندما يتم استدعاء طريقة ADD () من خلال الهدف ، سيتم تشغيل طريقة Intercept () ليتم استدعاؤها. إذا تم استدعاء method.invoke (الهدف ، args) في طريقة Intercept () ، فهذا يعادل استدعاء طريقة Add () مرة أخرى ، مما يؤدي إلى حلقة عودية غير محدودة. ولكن إذا قمت بتنفيذ method.invoke (حقيقي ، args) ، فلن ، لأن الهدف الحقيقي والهدف هما كائنات مختلفة في نفس الفئة ، الحقيقي هو الموضوع المنطقي الحقيقي ، والهدف هو الوكيل للموضوع الحقيقي الحقيقي.
فيما يلي مثال لمحاكاة:
واجهة solveInterface {void solve () ؛} class real armements solveInterface {public void solve () {system.out.println ("Real Solve!") ؛ }} هدف الفئة يمتد {private object obj ؛ public void setObject (object obj) {this.Obj = obj ؛ } private void invoke () {try {method method = solveInterface.class.getMethod ("solve" ، class [] {}) ؛ method.invoke (OBJ ، فئة جديدة [] {}) ؛ } catch (استثناء e) {E.PrintStackTrace () ؛ }} public void solve () {system.out.println ("target solve!") ؛ استدعاء () ؛ }} الطبقة العامة الرئيسية {public static void main (string [] args) يلقي الاستثناء {target = new target () ؛ Target.SetObject (new Real ()) ؛ // repue // target.setObject (target) ؛ // conclic call يحدث target.solve () ؛ }}في الواقع ، ستستدعي طريقة Invoke () الطريقة طريقة الحل () المقابلة وفقًا لنوع OBJ ، أي تعدد الأشكال.
4. إدراك 2
تنفيذ واجهة InternInterceptor
class cglibdpqueryInterceptor تنفذ methodInterceptor {Override اعتراض الكائن العام (هدف الكائن ، الطريقة ، الكائن ، الكائن ، args ، methodproxy proxy) يلقي رمي {String methodname = method.getName () ؛ system.out.println (method) ؛ system.out.println (method) ؛ System.out.println ("الطريقة:" + methodname + "start ، المعلمات:" + arrays.aslist (args)) ؛ // معلومات فئة الطباعة: target.getClass () ؛ حذف نتيجة الكائن = proxy.invokesuper (الهدف ، args) ؛ System.out.println ("الطريقة:"+methodname+"تنتهي ، النتيجة:"+نتيجة) ؛ نتيجة العودة }}قم بإنشاء فئة وكيل واتصل بفصل الوكيل
الفئة العامة الرئيسية {private static int a = 4 ، b = 2 ؛ الكائنات الثابتة العامة createCglibproxy () {ensancer ensancer = new ensancer () ؛ ensancer.setCallback (CglibdPqueryInterceptor () جديد) ؛ ensancer.SetSuperClass (Arithmetic.class) ؛ إرجاع ensancer.create () ؛ } public static void main (string [] args) {arithmetic real = new Arithmetic () ؛ كائن proxyarithmetic = createCglibproxy () ؛ ((addInterface) proxyarithmetic) .add (a ، b) ؛ ((واجهة فرعية) proxyarithmetic) .sub (a ، b) ؛ }}لاحظ أن المحسن لا يعين الواجهة في التنفيذ 2 ، لأنه يتم تعيين الفئة الفائقة (أي ، فئة الوالدين لفئة الوكيل هي الحساب) ، سوف يرث فئة الوكيل لدينا ، وأن الحساب قد نفذت الواجهة الخاصة بنا. لإثبات ذلك ، يمكنك طباعة معلومات الفئة الخاصة بـ Target.getClass () في طريقة Intercept of MethodInterceptor. ستجد أن فئة الوالدين لفئة وكيل CGLIB مختلفة. على النحو التالي:
التنفيذ 1:
الطبقة العامة com.test.arithmetic $$ ensancerbycglib $$ 4FA786EB يمتد java.lang.object
التنفيذ 2:
الطبقة العامة com.test.arithmetic $$ ensancerbycglib $$ 4FA786EB يمتد com.test.arithmetic
الطريقة 3: Javassist يولد الوكيل الديناميكي (إنشاء مصنع الوكيل أو إنشاء رمز ديناميكي)
Javassist هو إطار لتحرير Bytecode ، والذي يتيح لك تشغيل رمز Bytecode بكل بساطة. يمكن أن تحدد أو تعديل الفصل خلال وقت التشغيل. يتمثل مبدأ تنفيذ AOP باستخدام Javassist في تعديل الطريقة التي يجب قطعها مباشرة قبل تحميل رمز Bytecode. هذا أكثر كفاءة من استخدام CGLIB لتنفيذ AOP ، وليس هناك العديد من القيود. مبدأ التنفيذ على النحو التالي:
التنفيذ 1:
تنفيذ الواجهات
class javassistdpqueryHandler تنفذ methodHandler {Override الكائن العام (هدف الكائن ، الطريقة ، الوكيل ، الوكيل ، الكائن [] args) رمي {String methodname = method.getName () ؛ system.out.println (method) ؛ system.out.println (method) ؛ System.out.println ("الطريقة:" + methodname + "start ، المعلمات:" + arrays.aslist (args)) ؛ نتيجة الكائن = proxy.invoke (الهدف ، args) ؛ System.out.println ("الطريقة:"+methodname+"تنتهي ، النتيجة:"+نتيجة) ؛ نتيجة العودة }}قم بإنشاء فئة وكيل واتصل بفصل الوكيل
الطبقة العامة الرئيسية {private static int a = 4 ، b = 2 ؛ كائن ثابت عام createJavAssistProxy () يلقي الاستثناء {proxyfactory factory = new proxyfactory () ؛ Factory.SetSuperClass (arithmetic.class) ؛ مصنع. Return Factory.CreateClass (). newInstance () ؛ } public static void main (string [] args) يلقي الاستثناء {Arithmetic Real = new Arithmetic () ؛ كائن proxyarithmetic = createJavAssistProxy () ؛ ((addInterface) proxyarithmetic) .add (a ، b) ؛ ((واجهة فرعية) proxyarithmetic) .sub (a ، b) ؛ }}ملاحظة: إن تعريف طريقة الاستدعاء في واجهة MethodHandler هو كما يلي:
استدعاء الكائن العام (هدف الكائن ، الطريقة ، الوكيل ، الوكيل ، كائن [] args)
تمثل الطريقة كائن الطريقة الذي يستدعي الطريقة ، والوكالة هي الكائن الذي ينشئ ويحل محل الطريقة بواسطة فئة الوكيل. خلاف ذلك ، فإن استخدام method.invoke (الهدف ، args) سيقوم بإنشاء مكالمة حلقة لا حصر لها.
التنفيذ 2:
تختلف عملية الوكيل الشائعة لاستخدام جافاسيست الديناميكي قليلاً عن الطريقة السابقة. داخل Javassist ، يمكن إنشاء رمز Java الديناميكي لإنشاء رمز Bytecode. يمكن أن يكون الوكيل الديناميكي الذي تم إنشاؤه بهذه الطريقة مرنًا للغاية ويمكن أن يولد منطق العمل في وقت التشغيل.
// Custom Interceptor Interceptor InterceptorHandler { /*** سيعكس استدعاء طريقة كائن الوكيل الديناميكي هذه الطريقة. يمكنك إضافة عمليات ما قبل وبعد عمليات AOP لتنفيذ هذه الطريقة. فقط إذا تمت إضافة الرمز التالي إلى هذا الهيكل الطريقة* سيتم تنفيذ طريقة الوكيل ، وسيتم إرجاع قيمة الإرجاع إلى الوكيل وأخيراً تم إرجاعها إلى البرنامج* param OBJ كائن الوكيل* طريقة param طريقة الكائن الوظيفي* @pare args argo [] thaning thaning absoke thaning abome thaning* there thispover agoint* there thispove* there thispover* there thispover agoint* OBJ ، طريقة الطريقة ، الكائن [] args) رمي رمي ؛ }. system.out.println (method) ؛ system.out.println (method) ؛ System.out.println ("الطريقة:" + methodname + "start ، المعلمات:" + arrays.aslist (args)) ؛ نتيجة الكائن = method.invoke (obj ، args) ؛ System.out.println ("الطريقة:"+methodname+"تنتهي ، النتيجة:"+نتيجة) ؛ نتيجة العودة }} class myproxyimpl { / ** اسم الفئة من فئة الوكيل الديناميكي* / private final static string proxy_class_name_suffix = "$ myproxy_" ؛ / ** Interceptor Interface*/ Private Final Static String interceptor_handler_interface = "com.test.InterceptorHandler" ؛ / ** فهرس اسم الفئة لفئة الوكيل الديناميكي لمنع ازدواجية أسماء الفصول*/ private int int proxyclassIndex = 1 ؛ /*** واجهة الوكيل الديناميكي المعرضة للمستخدم ، تُرجع كائن الوكيل الديناميكي لواجهة معينة. لاحظ أنه يجب استخدام تنفيذ هذا الوكيل مع com.cuishen.myaop.InterceptorHandler Interceptor* ، أي إذا كان المستخدم يريد استخدام هذا الوكيل الديناميكي ، فيجب عليه أولاً تنفيذ سلسلة com.cuisheen.myaop.InterceptOrhandler Interface* param interfaceClassName. سلسلة ClasStoproxy اسم الفئة لفئة التنفيذ للواجهة ليكون وكيل ديناميكي ، على سبيل المثال test.StudentInFoserviceImpl * param interceptorHandlerMplClassName سلسلة الفئة من فئة التطبيق intergance intergance intergance * turnting intergance intergance * thratex. throws notfoundException * athrows لا يمكن compilexception * throws classnotfoundException * seee com.cuishen.myaoP.InterceptorHandler */ كائن ثابت عام newProxyInstance لا يمكن compilexception ، classnotfoundException {class interfaceClass = class.forname (interfaceClassName) ؛ Class interceptorHandlerImplClass = class.forname (interceptorHandlerImplClassName) ؛ إرجاع DynamicImplementInterface (classtoproxy ، interfaceclass ، interceptorHandlerMplclass) ؛ } /** * تطبيق ديناميكي للواجهة ليكون وكيلًا * param classtoproxy سلسلة فئة فئة التنفيذ للواجهة لتكون وكيلًا ديناميكيًا ، eg test.studentInfoserviceImpl * param interfaceClass class to be dynamially proxyed ، فئة التنفيذ التي يقدمها المستخدم من واجهة التقاطع * يعيد كائن RETURN كائن الوكيل الديناميكي لواجهة معينة * throws notfoundException * @throws لا يمكن cancompilexception * throws notfoundException ، لا يمكن compilexception ، instantiationException ، غير alustalAccessException {classpool cp = classpool.getDefault () ؛ سلسلة interfaceName = interfaceClass.getName () ؛ . // اسم حزمة الواجهة المراد تنفيذه + واجهة اسم سلسلة interfacenamepath = interfacename ؛ ctclass ctinterface = cp.getCtClass (interfacenamepath) ؛ CTClass CC = CP.MakeClass (proxyClassName) ؛ cc.addinterface (ctinterface) ؛ الطريقة [] الطرق = interfaceClass.getMethods () ؛ لـ (int i = 0 ؛ i <methods.length ؛ i ++) {method method = methods [i] ؛ DynamicImplementSmethodSfromInterface (classtoproxy ، cc ، method ، interceptorHandlerImplclass ، i) ؛ } return (object) cc.toclass (). newInstance () ؛ } /*** الطريقة في التنفيذ الديناميكي للطريقة* param classtoproxy سلسلة الفئة لفئة التنفيذ للواجهة لتكون وكيل ديناميكي ، eg test.StudentInfoserviceImpl* param application ctclass class the dynamic classy proxy class* parampl. الفئة اعتراضية فئة تطبيق التقاطع التي يقدمها المستخدم* param methodIndex int index للطريقة التي سيتم تنفيذها* throws لا يمكن cancompilexception*/ private static void dynamiciMplementsmethodSfromInterface GenerateMethodCode (classtoproxy ، methodtoimpl ، interceptorclass ، methodIndex) ؛ ctmethod cm = ctnewmethod.make (MethodCode ، Aperfecter) ؛ APPERIDER.ADDMETHOD (CM) ؛ } /*** تجميع طريقة الجسم ديناميكيًا. بالطبع ، فإن تنفيذ الطريقة في الوكيل ليس نسخة بسيطة ، ولكن يعكس طريقة الاستدعاء في التقاطع ويمرر المعلمات المستلمة* param classtoproxy اسم الفئة لفئة التنفيذ الخاصة بواجهة طريقة التبديل ديناميكيًا ، على سبيل المثال ، test.studentInFoserviceMpl param interceptorClass فئة فئة تنفيذ اعتراض من قبل المستخدم* param methodIndex int index للطريقة التي سيتم تنفيذها* @regurn سلسلة من طريقة التجميع الديناميكي*/ private static string generateMethodCode (string classtoproxy ، methodtoimpl ، class interceptorclass ، int methodIndex) { String methodReturnType = methodtoimpl.getReturnType (). getName () ؛ class [] parameters = methodtoimpl.getParameterTypes () ؛ class [] استثناء = methodtoimpl.getExceptionTypes () ؛ StringBuffer Conventbuffer = new StringBuffer () ؛ // استثناء إعلان طريقة التجميع if (is (stiventTypes.Length> 0) استثناء buffer.append ("رميات") ؛ لـ (int i = 0 ؛ i <stisplestypes.length ؛ i ++) {if (i! = inscplisttypes.length - 1) استثناء buffer.append (استثناءات [i] .getName ()). إلحاق ("،") ؛ else inscplistbuffer.append (استثناءات [i] .getName ()) ؛ } stringBuffer parameterbuffer = new StringBuffer () ؛ // قائمة المعلمة بأسلوب التجميع لـ (int i = 0 ؛ i <parameters.length ؛ i ++) {class parameter = parameters [i] ؛ String parametertype = parameter.getName () ؛ // Dynamic تحديد الاسم المتغير لسلسلة المعلمة method refname = "a" + i ؛ if (i! = parameters.length - 1) parameterbuffer.append (parametertype) .append (" + refn) .append (" ، ") ؛ parameterbuffer.append (parametertype) .Append (" + refname) ؛ } stringBuffer methodDeclare = new StringBuffer () ؛ // إعلان الطريقة ، نظرًا لأنها طريقة تنفذ الواجهة ، فهي MethodEclare.append ("عامة") .append (methodReturnType) .Append ("") .Append (MethodName) .Append ("("). oppend (parameterbuffer) .Append (")"). سلسلة interceptorImplName = interceptorClass.getName () ؛ // methodbody methodDeclare.append (interceptor_handler_interface) .Append ("interceptor = new") .Append (interceptorImplName) .Append ("() ؛/n") ؛ . if (parameters. + i + "،") ؛ آخر methodDeclare.append ("null) ؛/n") ؛ // لف قيمة الإرجاع من اعتراض المكالمات إذا (methodtoimpl.getReturnType (). isprimitive ()) {if (methodtoimpl.getReturntype (). متساوٍ (boolean.type)) آخر إذا (methodtoimpl.getReturnType (). يساوي (integer.type)) methodDeclare.Append ("return ((integer) returnoBj) .intvalue () ؛/n") ؛ آخر إذا (methodtoimpl.getReturnType (). يساوي (long.type)) methodDeclare.Append ("return ((long) returnoBj) .longvalue () ؛/n") ؛ وإلا وإلا إذا (methodToImpl.getReturntype (). يساوي (double.type)) methodDeClare.append ("return (" return ("return (" return ("return () ؛/n") ؛ else (methodToImpl.getReturntype (). methodDeclare.Append ("return (" return ("return (" return ("return (" return ("return () ؛/n") ؛ else if (methodtoImpl.getReturnType (). equals (double.type) methodDeClare.Append ("" return ("return (" return ("Return (" " methodDeClare.Append ("return (" return ("return (" return ("return (" methodtoimpl.getReturntype (). equals (double.type)) methodDeclare.Append ("return (" return ("return (" return ("methodtoimpl.getReturnType (). aread ((double) returnoBj) .doublevalue () ؛/n") ؛ else if (methodoimpl.getReturntype (). ((الحرف) returnoBj) .Charvalue () ؛/n ") ؛ آخر إذا (methodoImpl.getReturntype (). يساوي (byte.type)) MethodDeclare.Append ("Return ((byte) returnobj) .betevalue () ؛/n") ؛ MethodReTurnType + ") الفئة ، اسم الفئة لفئة الوكيل مطلوب ، فئة فئة فئة تطبيق المعرفة المعرفة من قبل المستخدم proxyarithmetic = myproxyimpl.newproxyinstance ("com.test.arithmeticInterface" ، "com.test.arithmetic" ، "com.test.InterceptOrdleMliMplplpl. ((ArithmeticInterface) Proxyarithmetic) (A ، B) ؛اطبع الرمز لتنفيذ الواجهة ديناميكيًا على النحو التالي:
int public add (int a0 ، int a1) {com.test.InterceptOrHandler interceptor = new com.test.InterceptOrHandlerImpl () ؛ object returnobj = interceptor.invoke (class.forname ("com.test.arithmetic"). newinstance () ، class.forname ( Object [] {($ w) a0 ، ($ w) a1}) ؛ return ((integer) returnoBj) .intvalue () ؛} public int sub (int a0 ، int a1) {com.test.InterceptOrhandler interceptor = new.test.interceptorhandlerimpl () interceptor.invoke (class.forname ("com.test.arithmetic"). newinstance () ، class.forname ("com.test.arithmetic"). ما ورد أعلاه هو مقدمة مفصلة لآلية تنفيذ الوكيل الديناميكي في جافا ، وآمل أن تكون مفيدة لتعلم الجميع.