transactional async وغيرها من التعليقات التوضيحية لا تعمل
من قبل ، واجه الكثير من الناس بعض المواقف التي لا يعمل فيها التعليقات التوضيحية عند استخدام transactional و async وغيرها من التعليقات التوضيحية في الربيع.
لماذا تحدث هذه المواقف؟ نظرًا لأن وظائف هذه التعليقات التوضيحية يتم تنفيذها فعليًا بواسطة Spring AOP ، ويتم تنفيذ مبادئ تنفيذها من خلال الوكيل.
الوكيل الديناميكي JDK
دعونا نفهم المبادئ الأساسية لـ JDK Dynamic Proxy مع مثال بسيط:
// واجهة الفئة الهدف واجهة عامة jdkproxytestservice {void run () ؛} // الفئة الهدف الفئة العامة jdkproxytestserviceimpl تنفذ jdkproxytestservice {public void run () {system.out.println ("do some ...") ؛ }} // proxy class public class testjdkproxy تنفذ invocationHandler {private Object TargetObject ؛ // proxy target object // إنشاء الكائن العام للكائن العام newProxy (Object TargetObject) {this.targetObject = targetObject ؛ return proxy.newproxyinstance (targetObject.getClass (). getClassloader () ، targetObject.getClass (). } // استخدم الانعكاس لإجراء تحسين منطقي على الكائن العام الأصلي للمنطق (وكيل الكائن ، طريقة الطريقة ، الكائن [] args) يلقي رمي {// Simulate START START VISUMEBEGINTRANSACTACTACTACTACTACTACTION () ؛ // كائن منطق التنفيذ الأصلي ret = method.invoke (TargetObject ، args) ؛ // تقديم المعاملات الوهمية austumecommittransaction () ؛ العودة } private void vileBegIntransAction () {system.out.println ("START TRAMPHTACTION START ...") ؛ } private void austumecommittransaction () {system.out.println ("تقديم المعاملة الوهمية ...") ؛ }} // اختبار الفئة العامة اختبار {public static void main (string [] args) {testjdkproxy jdkproxy = new testjdkproxy () ؛ jdkproxytestservice proxy = (jdkproxytestService) jdkproxy.newproxy (jdkproxytestServiceImpl () new jdkproxytestserviceimpl ()) ؛ proxy.run () ؛ }}يجب أن يكون المثال أعلاه قادرًا على شرح مبدأ الوكيل الديناميكي JDK بوضوح. يستخدم آلية الانعكاس لإنشاء فئة مجهولة المصدر تقوم بتنفيذ واجهة الوكيل ، والمكالمات InvokeHandler للتعامل معها قبل استدعاء الطريقة المحددة. عندما نسمي طريقة من خلال كائن فئة وكيل ، سنقوم فعليًا بالاتصال بأسلوب الاستدعاء أولاً ، ثم نتصل بالطريقة الأصلية. وبهذه الطريقة ، يمكننا إضافة منطق المعالجة بشكل موحد قبل وبعد منطق الطريقة الأصلية.
يحتوي Spring أيضًا على طريقة وكيل ديناميكي هي الوكيل الديناميكي CGLIB. يقوم بتحميل ملف الفئة لفئة كائن الوكيل ويقوم بمعالجته عن طريق تعديل رمزها بتوليد الفئات الفرعية. على الرغم من أن أساليب المناولة مختلفة ، إلا أن أفكار الوكالة متسقة.
إذا كان الكائن الهدف الذي يجري أن يكون الوكيل يطبق واجهة ، فسيستخدم Spring الوكيل الديناميكي JDK افتراضيًا. سيتم الوكيل على جميع الواجهات التي ينفذها هذا النوع الهدف. إذا كان الكائن الهدف لا ينفذ أي واجهة ، يتم إنشاء وكيل CGLIB.
فشل شرح الربيع AOP وحلها
استنادًا إلى التحليل أعلاه لمبدأ الوكيل الديناميكي ، دعونا نلقي نظرة على المشكلتين الشائعتين التاليتين:
في نفس الفئة ، الطريقة A Method A Method B (مشروح على الطريقة ب) ، والتعليقات التعليق غير صالحة.
بالنسبة لجميع شرائح التعليقات التوضيحية لـ Spring AOP ، إذا وجد Spring مثل هذه التعليقات التوضيحية عند مسح الفاصوليا ، فسيقوم ببناء كائن وكيل ديناميكيًا.
يكون هذا التعليق التوضيحي صالحًا إذا كنت ترغب في الاتصال مباشرة بالطريقة A مع التعليق التوضيحي من خلال كائن من الفئة X. لأنه في هذا الوقت ، سيحدد Spring أن هناك شرحًا توضيحيًا على الطريقة التي توشك على الاتصال بها ، وبعد ذلك سيستخدم كائن الوكيل من الفئة X للاتصال بالطريقة A.
ولكن لنفترض أن الطريقة A في الفئة X ستستدعي الطريقة B مع التعليق التوضيحي ، وما زلت ترغب في استدعاء الطريقة من خلال كائن من الفئة X ، فإن التعليق التوضيحي على الطريقة B غير صالح. نظرًا لأن Spring تحدد أن A الذي تتصل به ليس له أي شرح ، فلا يزال الكائن الأصلي يستخدم بدلاً من كائن الوكيل. عندما يتم استدعاء B بعد ذلك ، يكون توضيح الطريقة B في الكائن الأصلي غير صالح بالطبع.
حل:
أسهل طريقة هي بالطبع لجعل الأساليب A و B لا يوجد بها تبعيات ويمكنها الاتصال مباشرة الطريقة B من خلال كائن من الفئة X.
ولكن في كثير من الأحيان ، قد لا يكون منطقنا مكتوبًا جيدًا بهذه الطريقة ، لذلك هناك طريقة أخرى: ابحث عن طريقة للحصول على كائن الوكيل يدويًا.
تحتوي فئة AopContext على طريقة CurrentProxy () يمكنها الحصول مباشرة على كائن الوكيل للفئة الحالية. ثم يمكن حل المثال أعلاه مثل هذا:
// طريقة الاتصال B داخل الطريقة A // 1. اتصل ب B مباشرة ، التعليق التوضيحي غير صالح. B () // 2.
الكائن Autowired فارغ في طريقة التعليق التوضيحي AOP
في الاستخدام السابق ، في طريقة التعليقات التوضيحية ، عند استخدام كائنات حقن أخرى ، وجد أنه لم يتم حقن الكائن ، وكان فارغًا.
أخيرًا ، تبين أن سبب ذلك هو أن الطريقة كانت خاصة. نظرًا لأن Spring يستخدم الوكيل الديناميكي JDK Dynamic أو CGLIB ، فإن أحدهما فئة تنفذ الواجهة والآخر يتم تنفيذها من خلال الفئات الفرعية. لا الواجهة ولا الفئة الأم ، يمكن أن تكون الطريقة الخاصة موجودة ، وإلا لا يمكن تجاوز الفئة الفرعية ولا فئة التنفيذ.
إذا كانت الطريقة خاصة ، فلا يمكن العثور على هذه الطريقة في عملية الوكيل ، مما يسبب مشاكل في إنشاء كائنات وكيل وتسبب في عدم حقن بعض الكائنات.
لذلك إذا احتاجت الطريقة إلى استخدام تعليقات AOP ، فقم بتعيينها على طريقة غير خاصة.
ما سبق هو كل محتوى هذه المقالة. آمل أن يكون ذلك مفيدًا لتعلم الجميع وآمل أن يدعم الجميع wulin.com أكثر.