ภาพรวม
ในบทความก่อนหน้านี้มีการแนะนำว่าถ้าคุณฉีดตัวเองเป็นถั่วถ้าคุณมี @async และ @Transaction ถ้าคุณฉีดตัวเองด้วย @autowire คุณจะรายงานการพึ่งพาเป็นวงกลม หากคุณฉีดตัวเองด้วย beanfactoryaware @transaction จะไม่ถูกต้อง ตัวอย่างเช่น:
@ServicePublic Class MyService ใช้ beanfactoryaware {ส่วนตัว myservice self; // คำอธิบายประกอบการทำธุรกรรมนั้นไม่ถูกต้อง @Transactional Public Notwork () {... } @async อนาคตสาธารณะ async () {... } @Override โมฆะสาธารณะ setBeanfactory (beanfactory beanfactory) โยน beansexception {self = beanfactory.getBean -ฉันเพิ่งพูดถึงมันสั้น ๆ ในเวลานั้นและบทความนี้คือการแนะนำว่าทำไมมันถึงล้มเหลว
ทั่วไป
เงื่อนไขต่อไปนี้จะต้องปฏิบัติตามในสถานการณ์ข้างต้น:
ผลที่ได้คือ: ยกเว้น @async คำอธิบายประกอบจะมีผลและไม่มีผลใด ๆ ดังที่แสดงในรูปด้านล่าง
พร็อกซีปกติควรเป็นตัวเลขดังต่อไปนี้:
เหตุผล
สิ่งแรกที่นึกถึงคือวิธีการประมวลผลของคำอธิบายประกอบ @async อาจแตกต่างจากคนอื่น ในการดำเนินการของ asyncannotationbeanpostprocessor (รหัสเฉพาะอยู่ในคลาสหลักของมัน AbstractivisingBeanPostProcessor) พบปัญหา
ภายใต้สถานการณ์ปกติถั่วที่เข้ามานั้นเป็นคลาสพร็อกซีแบบไดนามิกที่ถูกพร็อกซีและเมื่อมันล้มเหลวคลาสจริงที่เข้ามานั้นเป็นจริงดังแสดงในรูปด้านล่าง:
จากนั้นหลังจากวิเคราะห์รหัสถ้าเป็นคลาสจริงเมื่อถึงบรรทัดที่ 69 มันจะส่งคืนจริงและเพิ่มที่ปรึกษาของ @AYSNC ไปยังหลักการแบบไดนามิก หากเป็นคลาสจริงเมื่อถึงบรรทัดที่ 83 มันจะสร้างคลาสพร็อกซีและเพิ่มที่ปรึกษาของ AYSNC ไปยังพร็อกซีแบบไดนามิกเท่านั้นดังนั้น @TransAction จะไม่ถูกต้องแล้ว
ทำไมตัวแทนไม่เข้ามา?
ในความเป็นจริงความแตกต่างเพียงอย่างเดียวคือคุณได้รับตัวเองผ่าน beanfactoryaware หรือไม่ แล้วทำไมคุณถึงใช้ beanfactory เพื่อรับตัวเองแล้วคุณไม่ใช่พร็อกซีใน beanpostprocessor ที่ตามมา? หากคุณคุ้นเคยกับกลไกการโหลด Spring @Transaction คุณจะรู้ว่าการสร้างพร็อกซีแบบไดนามิกเช่น @Transaction และคำอธิบายประกอบ @retryable ถูกสร้างขึ้นใน AnnotationawareAspectJautoproxycreator จากการดีบักเราพบว่าหลังจากผ่านคำอธิบายประกอบ AnnotationawareaspectJautoproxycreator แล้วพร็อกซีแบบไดนามิกของเราก็ไม่ได้ถูกเพิ่มเข้ามา
ลองมาดูการใช้งานใน AnnotationawareaspectJautoproxycreator แต่หลังจากนั้นไม่มีการสร้างคลาสพร็อกซี เหตุผลก็คือมี "MyService" ในแผนที่ที่เปิดเผยล่วงหน้า
เขาเปิดเผยเมื่อไหร่? จริงๆแล้วมันคือ
@OverridePublic เป็นโมฆะ setBeanFactory (BeanFactory BeanFactory) พ่น beansexception {self = beanfactory.getBean (myservice.class);}จากนั้นทุกอย่างก็สว่างขึ้น ในตัวอย่าง myservice, beanfactoryaware ถูกกระตุ้นและคลาสพร็อกซีถูกสร้างขึ้นผ่าน beanfactory.getBean (myservice.class); (เคล็ดลับ: คลาสพร็อกซีปัจจุบันไม่มี adivisor ของ @async) เพราะฤดูใบไม้ผลิกำลังสร้างถั่ว myservice และยังไม่ได้ใส่เข้าไปใน beanfactory จากนั้นเราเรียกใช้ beanfactory.getBean (myservice.class); ในกระบวนการนี้เราสร้างพร็อกซีและส่งคืนและเข้าร่วมกับแผนที่ที่เปิดเผยล่วงหน้า สิ่งนี้นำไปสู่ชุดของปัญหาที่ตามมา มันรู้สึกพันกันเล็กน้อย คุยกับภาพ:
โดยปกติกระบวนการต่อไปนี้ควรเป็น:
นี่เป็นกรณีที่มีสถานการณ์ผิดปกติ
สรุป
ภายใต้สถานการณ์ปกติให้ใช้ @autowire เพื่อฉีด (หากใช้ AutoWire สถานการณ์ข้างต้นจะส่งการพึ่งพาเป็นวงกลมโดยตรง) แน่นอนถ้ามีปัญหาคุณไม่สามารถปล่อยมันไปได้ คุณต้องรู้เหตุผลและเหตุผล!
ข้างต้นเป็นเนื้อหาทั้งหมดของบทความนี้ ฉันหวังว่ามันจะเป็นประโยชน์ต่อการเรียนรู้ของทุกคนและฉันหวังว่าทุกคนจะสนับสนุน wulin.com มากขึ้น