إذا تم استخدام حقن المنشئ ، فقد يتم إنشاء سيناريو التبعية الدائرية التي لا يمكن تحليلها.
ما هو التبعية الدائرية
الاعتماد الدائري هو في الواقع مرجع دائري ، أي أن اثنين أو أكثر من الفاصوليا التي تحمل بعضها البعض وتشكل في النهاية حلقة مغلقة. على سبيل المثال ، يعتمد A على B ، B يعتمد على C ، ويعتمد C على A. كما هو موضح في الشكل أدناه:
لاحظ أن هذه ليست دعوة حلقة إلى الوظيفة ، ولكنها مترابط للكائن. مكالمات الحلقة هي في الواقع حلقة ميتة ما لم يكن هناك حالة نهاية.
هناك سيناريوهات تبعية حلقة في الربيع:
(1) الاعتماد الدائري للمؤسسة (2) الاعتماد الدائري لسمة الحقل.
كيفية اكتشاف ما إذا كان هناك تبعية دائرية
من السهل نسبيًا اكتشاف التبعيات الدائرية. عند إنشاء الفول ، يمكن أن تضع علامة على الفول. إذا عادت المكالمة العودية ووجدت أنه يتم إنشاؤها ، فهذا يعني أن التبعية الدائرية هي.
هنا هو الموقف الذي واجهته ، هيكل الكود كما يلي:
فئة تكوين أمن الينابيع:
ConfigurationPublic Class BrowsersEcurityConfig يمتد WebSecurityConfigureRadapter {userDetailsService userDetailsService ؛ / ** * حقن userDetailsService من خلال مُنشئ فئة التكوين */ AUTOWIRES PULLORSERSERSECURITYCONFIG (userDetailsService userDetailsService) {this.userDetailsService = userDetailsService ؛ } / ** * إعلان تشفير التشفير في فئة التكوين * / bean provorpordencoder passworder () {إرجاع bcryptpasswordencoder () جديد ؛ } ... ...}فئة userDetailsService:
ComponentPublic Class MyUserDetailservice تنفذ userDetailsService {prossive passwordercoder passworder ؛ logger logger الخاص = loggerFactory.getLogger (getClass ()) ؛ / ** * حقن passwordencoder من خلال المُنشئ */ autowired public myUserDetailservice (passwordencoder passwordencoder) {this.passwordencoder = passwordencoder ؛ } ... ...}بعد الجري ، يرمي الربيع رسالة الخطأ التالية:
وصف:
تبعيات بعض الفاصوليا في سياق التطبيق تشكل دورة:
┌
| BrowsersEcurityConfig المعرّفة في الملف [d: /code/java/ideaprojects/mango-security/mango-security-browser/target/classes/stu/mango/security/browser/browsersecurityconfig.class]
↑ ↓
| MyUserDetailservice محدد في الملف [d: /code/java/ideaprojects/mango-security/mango-security-browser/target/classes/stu/mango/security/browser/myuserdetailservice.class]
└
في هذا المثال ، يضخ BrowsersErityConfig مثيل userDetailsService من خلال المنشئ ، ويتم حقن خرف المستخدم في Passwordencoder المعلن في متصفح SurunyConfig من خلال المُنشئ.
باختصار ، يعني الاعتماد الدائري لفاصوليا الربيع أن الفئة A تحتاج إلى حقن مثيل من الفئة B (أو الفول المعلن في ب) في المُنشئ ، في حين أن الفئة B تحتاج إلى حقن مثيل من الفئة A (أو الفاصوليا المعلنة في أ) في المنشئ. إذا تم تكوين حبوب الفئة A والفئة B لضخ بعضها البعض ، فإن حاوية IOC الربيعية تكتشف مرجع الحلقة هذه في وقت التشغيل وترفع beancurterlyincreationException. على عكس الحالة النموذجية (بدون تبعيات دائرية) ، فإن التبعية الدائرية بين الفول A و Bean B تجبر أحد الفاصوليا التي يتم حقنها في الآخر قبل تهيئتها بالكامل (هذا سيناريو "دجاج أولي أولاً" نموذجي).
حل
بكل بساطة ، لا يتم استخدام حقن التبعية القائمة على المنشئ. يمكن حلها بالطريقة التالية.
استخدم التعليق التوضيحي Autowired في الحقل واترك Spring يقرر الحقن في الوقت المناسب. 【يوصي】
استبدل حقن التبعية القائمة على المنشئ مع حقن التبعية المستندة إلى Setter لحل التبعية الدائرية.
ما سبق هو كل محتوى هذه المقالة. آمل أن يكون ذلك مفيدًا لتعلم الجميع وآمل أن يدعم الجميع wulin.com أكثر.