سؤال

عندما تبدأ في العبث بعناصر الوكيل التلقائي في Spring، فغالبًا ما تواجه هذا السلوك كما هو موثق:

الفصول التي تنفذ واجهة BeanPostProcessor خاصة ، وبالتالي يتم التعامل معها بشكل مختلف بواسطة الحاوية.سيتم إنشاء إنشاء جميع معالجات BeanPostProcessors والفاصوليا المرجعية مباشرة عند بدء التشغيل ، كجزء من مرحلة بدء التشغيل الخاصة من ApplicationContext ، ثم سيتم تسجيل جميع معالجات الفاصولياء بطريقة مُصنفة - وتطبيقها على جميع الفاصوليا الإضافية.نظرًا لأن AOP Auto-Proxying يتم تنفيذها باعتبارها معالجًا بين الفاصولياء نفسه ، فلا توجد معالجات من الفاصولياء أو الفاصوليا المشار إليها مباشرة مؤهلة للحصول على قيود تلقائية (وبالتالي لن يكون لها جوانب "منسوجة" فيها.

لأي فول من هذا القبيل ، يجب أن ترى رسالة سجل المعلومات:"Bean 'Foo" غير مؤهل للمعالجة من قبل جميع معالجات BeanPostProcessors (على سبيل المثال:غير مؤهل للحصول على تلقائي) ".

بمعنى آخر، إذا قمت بكتابة BeanPostProcessor الخاص بي، وكانت هذه الفئة تشير مباشرة إلى وحدات أخرى في السياق، فلن تكون تلك الوحدات المشار إليها مؤهلة للوكيل التلقائي، وسيتم تسجيل رسالة بهذا المعنى.

مشكلتي هي أن تعقب مكان وجود هذا المرجع المباشر يمكن أن يكون صعبًا للغاية، نظرًا لأن "المرجع المباشر" يمكن أن يكون في الواقع سلسلة من التبعيات المتعدية التي تنتهي في النهاية بأخذ نصف الفول في سياق التطبيق.كل ما يقدمه لك Spring هو رسالة معلومات واحدة، وهي لا تساعد كثيرًا حقًا، بخلاف إخبارك متى تم اكتشاف حبة الفول في شبكة المراجع هذه.

يحتوي BeanPostProcessor الذي أقوم بتطويره على إشارات مباشرة إلى حبوب أخرى، ولكنها مجموعة محدودة جدًا من المراجع.على الرغم من ذلك، يتم بعد ذلك استبعاد كل حبة في السياق الخاص بي تقريبًا من أن تكون وكيلًا تلقائيًا، وفقًا لرسائل السجل، لكن لا يمكنني رؤية أين تحدث هذه التبعية.

هل وجد أي شخص طريقة أفضل لتتبع هذا؟

هل كانت مفيدة؟

المحلول 2

وفقط لجلب بعض الإغلاق على هذا السؤال، وتسببت في انهيار الرسم البياني كائن غير مهيأ من قبل BeanPostProcessor باستخدام @Autowired للحصول على تابعيها، وآلية autowire تسبب بشكل فعال كل تعريف الفول أخرى ليتم تهيئتها قبل حصلت على BeanPostProcessor فرصة أن يكون لهم رأي في هذه المسألة. الحل هو عدم استخدام autowiring لBPPS الخاص بك.

نصائح أخرى

اتبع هذه الوصفة:

  1. يفتح BeanPostProcessorChecker في IDE الخاص بك (إنها فئة داخلية من AbstractApplicationContext)
  2. قم بتعيين نقطة توقف على if (logger.isInfoEnabled()) { في الطريقة postProcessAfterInitialization
  3. قم بتشغيل التعليمات البرمجية الخاصة بك
  4. عندما تصل إلى نقطة التوقف، ابحث عن المكالمات إلى getBean(String,Class<T>) في تتبع المكدس الخاص بك.

    ستحاول إحدى هذه المكالمات إنشاء ملف BeanPostProcessor.ينبغي أن يكون هذا الفول الجاني.

خلفية

تخيل هذا الموقف:

public class FooPP implements BeanPostProcessor {
    @Autowire
    private Config config;
}

عندما يجب على الربيع أن يخلق config (لأنها تبعية لـ FooPP)، فيه مشكلة:العقد يقول أن كل شيء BeanPostProcessor يجب أن يتم تطبيقه على كل حبة يتم إنشاؤها.ولكن عندما يحتاج الربيع config, ، يوجد PP واحد على الأقل (أي FooPP) وهو غير جاهز للخدمة!

ويزداد الأمر سوءًا عند استخدام @Configuration فئة لتعريف هذه الحبة:

@Configuration
public class BadSpringConfig {
     @Lazy @Bean public Config config() { return new Config(); }
     @Lazy @Bean public FooPP fooPP() { return new FooPP(); }
}

كل فئة تكوين هي حبة فاصوليا.وهذا يعني بناء مصنع للفاصوليا من BadSpringConfig, ، يحتاج الربيع إلى تطبيق المعالج اللاحق fooPP ولكن من أجل القيام بذلك، فإنه يحتاج أولا إلى مصنع الفول ...

في هذا المثال، من الممكن كسر إحدى التبعيات الدورية.تستطيع فعل FooPP ينفذ BeanFactoryAware للحصول على حقن الربيع BeanFactory في معالج آخر.بهذه الطريقة، لا تحتاج إلى التوصيل التلقائي.

لاحقًا في الكود، يمكنك أن تطلب الحبة بتكاسل:

private LazyInit<Config> helper = new LazyInit<Config>() {

    @Override
    protected InjectionHelper computeValue() {
        return beanFactory.getBean( Config.class );
    }
};

@Override
public Object postProcessBeforeInitialization( Object bean, String beanName ) throws BeansException {
     String value = helper.get().getConfig(...);
}

(مصدر LazyInit)

لكسر الدورة بين مصنع الفول ومعالج النشر، تحتاج إلى تكوين معالج النشر في ملف تكوين XML.يستطيع الربيع قراءة ذلك وبناء جميع الهياكل دون الخلط.

ولست متأكدا ما اذا كان أي مساعدة، ولكن الكسوف الربيع IDE الصورة عرض الرسم البياني يبدو أنها يمكن أن تكون مفيدة في فرز المراجع الفول ..

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top