Spring BeanPostProcessor ทำงานอย่างไร


98

ฉันกำลังศึกษาสำหรับการรับรองฤดูใบไม้ผลิแกนผมมีข้อสงสัยบางอย่างเกี่ยวกับฤดูใบไม้ผลิจัดการถั่ววงจรชีวิตและโดยเฉพาะอย่างยิ่งเกี่ยวกับในการประมวลผลถั่วโพสต์

ดังนั้นฉันจึงมีสคีมานี้:

ป้อนคำอธิบายภาพที่นี่

ค่อนข้างชัดเจนสำหรับฉันว่ามันหมายถึงอะไร:

ขั้นตอนต่อไปนี้เกิดขึ้นในเฟสLoad Bean Definitions :

  • @Configurationเรียนมีการประมวลผลและ / หรือ@Componentsจะสแกนหาและ / หรือไฟล์ XML ที่มีการแยกวิเคราะห์

  • เพิ่มคำจำกัดความของ Bean ใน BeanFactory (แต่ละรายการจัดทำดัชนีภายใต้ id)

  • ถั่วBeanFactoryPostProcessorพิเศษที่เรียกใช้มันสามารถแก้ไขนิยามของ bean ใด ๆ (ตัวอย่างเช่นการแทนที่ค่าคุณสมบัติตัวยึด)

จากนั้นขั้นตอนต่อไปนี้จะเกิดขึ้นในขั้นตอนการสร้างถั่ว :

  • ถั่วแต่ละอันจะถูกสร้างอินสแตนซ์อย่างกระตือรือร้นตามค่าเริ่มต้น (สร้างขึ้นตามลำดับที่ถูกต้องพร้อมกับการเติมการอ้างอิง)

  • หลังจากการฉีดพึ่งพาถั่วแต่ละชนิดจะต้องผ่านขั้นตอนหลังการประมวลผลซึ่งอาจเกิดการกำหนดค่าและการเริ่มต้นเพิ่มเติม

  • หลังจากการประมวลผลภายหลัง bean จะเริ่มต้นอย่างสมบูรณ์และพร้อมสำหรับการใช้งาน (ติดตามโดย id จนกว่าบริบทจะถูกทำลาย)

โอเคนี่ค่อนข้างชัดเจนสำหรับฉันและฉันก็รู้ด้วยว่ามีโปรเซสเซอร์ bean post สองประเภทได้แก่ :

  • Initializers:เริ่มต้น bean หากได้รับคำแนะนำ (เช่น @PostConstruct)

  • และส่วนที่เหลือทั้งหมด:ที่อนุญาตให้มีการกำหนดค่าเพิ่มเติมและอาจทำงานก่อนหรือหลังขั้นตอนเริ่มต้น

และฉันโพสต์สไลด์นี้:

ป้อนคำอธิบายภาพที่นี่

ดังนั้นมันจึงชัดเจนมากสำหรับฉันว่าinitializers bean post processors คืออะไร (เป็นวิธีการที่มีคำอธิบายประกอบ@PostContructและจะถูกเรียกโดยอัตโนมัติทันทีหลังจากวิธีการ setter (ดังนั้นหลังจากการฉีดการพึ่งพา) และฉันรู้ว่าฉันสามารถใช้เพื่อ ดำเนินการแบตช์การเริ่มต้นบางอย่าง (โดยเติมข้อมูลในแคชดังตัวอย่างก่อนหน้านี้)

แต่สิ่งที่แสดงถึงโปรเซสเซอร์ bean post อื่น ๆ ? เราหมายถึงอะไรเมื่อเราบอกว่าขั้นตอนเหล่านี้ดำเนินการก่อนหรือหลังขั้นตอนการเริ่มต้น ?

ดังนั้นถั่วของฉันจึงถูกสร้างอินสแตนซ์และการอ้างอิงของมันจะถูกฉีดเข้าไปดังนั้นขั้นตอนการเริ่มต้นจะเสร็จสมบูรณ์ (โดยการดำเนินการของวิธีการใส่คำอธิบายประกอบ@PostContruct ) เราหมายถึงอะไรที่บอกว่า Bean Post Processor ถูกใช้ก่อนขั้นตอนการเริ่มต้น? หมายความว่ามันเกิดขึ้นก่อนการเรียกใช้เมธอดที่ใส่คำอธิบายประกอบ@PostContruct ? หมายความว่ามันอาจเกิดขึ้นก่อนการฉีดแบบพึ่งพา (ก่อนที่จะเรียกวิธีการ setter)?

และว่าสิ่งที่เราหมายถึงเมื่อเราบอกว่ามันจะดำเนินการหลังจากขั้นตอนการเริ่มต้น หมายความว่ามันเกิดขึ้นหลังจากนั้นการเรียกใช้เมธอดที่ใส่คำอธิบายประกอบ@PostContructหรืออะไร?

ฉันสามารถคิดในหัวของฉันได้อย่างง่ายดายว่าทำไมฉันต้องใช้วิธีการที่มีคำอธิบายประกอบ@PostContructแต่ฉันไม่สามารถหาตัวอย่างทั่วไปของตัวประมวลผลโพสต์ bean ชนิดอื่นได้คุณช่วยแสดงตัวอย่างทั่วไปของเวลาที่ใช้งานได้ไหม


ฉันค่อนข้างแน่ใจว่าคุณไม่ควรแชร์ภาพของสไลด์ :)
Reg

@Reg ภาพเหล่านี้มาจากหลักสูตร / การนำเสนอที่แน่นอนอะไร?
Malvon

@ มัลวอนนี่มาจากหลักสูตร Spring core อย่างเป็นทางการของ Pivotal รุ่นก่อนหน้า และ BTW - หากคุณกำลังเตรียมสอบไม่ต้องสนใจอะไรกับ XML :)
Reg

@Reg มีวิธีซื้อคอร์สโดยไม่เข้าคลาสอบรมจริงหรือ?
Malvon

ฉันสงสัยว่าเกิดอะไรขึ้นในส่วนสีม่วงของแผนภาพ“ Post process Bean Definitions”
Akshay Hiremath

คำตอบ:


50

ฤดูใบไม้ผลิ doc อธิบายสูภายใต้ถั่วการปรับแต่งโดยใช้ BeanPostProcessor ถั่ว BPP เป็นถั่วชนิดพิเศษที่สร้างขึ้นก่อนถั่วอื่น ๆ และโต้ตอบกับถั่วที่สร้างขึ้นใหม่ ด้วยโครงสร้างนี้ Spring ช่วยให้คุณสามารถเชื่อมต่อและปรับแต่งพฤติกรรมวงจรชีวิตได้ง่ายๆเพียงแค่ใช้BeanPostProcessorตัวคุณเอง

มี BPP ที่กำหนดเองเช่น

public class CustomBeanPostProcessor implements BeanPostProcessor {

    public CustomBeanPostProcessor() {
        System.out.println("0. Spring calls constructor");
    }

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName)
            throws BeansException {
        System.out.println(bean.getClass() + "  " + beanName);
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName)
            throws BeansException {
        System.out.println(bean.getClass() + "  " + beanName);
        return bean;
    }
}

จะถูกเรียกและพิมพ์ชื่อคลาสและ bean สำหรับ bean ที่สร้างขึ้นทุกตัว

เพื่อเน้นย้ำว่าวิธีการนี้เหมาะสมกับวงจรชีวิตของ bean อย่างไรและเมื่อใดที่เมธอดถูกเรียกตรวจสอบเอกสาร

postProcessBeforeInitialization (Object bean, String beanName)ใช้ BeanPostProcessor นี้กับอินสแตนซ์ bean ใหม่ที่กำหนดก่อนการเรียกกลับการเริ่มต้น bean ใด ๆ (เช่น InitializingBean's afterPropertiesSet หรือวิธีการเริ่มต้นที่กำหนดเอง)

postProcessAfterInitialization (Object bean, String beanName)ใช้ BeanPostProcessor นี้กับอินสแตนซ์ bean ใหม่ที่กำหนดหลังจากการเรียกกลับการเตรียมใช้งาน bean (เช่น InitializingBean's afterPropertiesSet หรือวิธีการเริ่มต้นที่กำหนดเอง)

บิตที่สำคัญก็คือ

bean จะถูกเติมด้วยค่าคุณสมบัติอยู่แล้ว

สำหรับสิ่งที่เกี่ยวข้องกับความสัมพันธ์กับ@PostConstructหมายเหตุว่าหมายเหตุประกอบนี้เป็นวิธีที่สะดวกในการประกาศpostProcessAfterInitializationวิธีการและ Spring จะรับทราบเมื่อคุณลงทะเบียนCommonAnnotationBeanPostProcessorหรือระบุ<context:annotation-config />ไฟล์คอนฟิกูเรชันใน bean ไม่ว่าจะเป็น@PostConstructวิธีการที่จะดำเนินการก่อนหรือหลังอื่น ๆpostProcessAfterInitializationขึ้นอยู่กับorderสถานที่ให้บริการ

คุณสามารถกำหนดค่าอินสแตนซ์ BeanPostProcessor ได้หลายรายการและคุณสามารถควบคุมลำดับที่ BeanPostProcessors เหล่านี้ดำเนินการได้โดยตั้งค่าคุณสมบัติคำสั่ง


31

ตัวอย่างทั่วไปสำหรับตัวประมวลผล bean post คือเมื่อคุณต้องการห่อ bean ดั้งเดิมในอินสแตนซ์พร็อกซีเช่นเมื่อใช้@Transactionalคำอธิบายประกอบ

ตัวประมวลผล bean post จะถูกส่งมอบอินสแตนซ์ดั้งเดิมของ bean ซึ่งอาจเรียกใช้เมธอดใด ๆ บนเป้าหมาย แต่ยังส่งคืนอินสแตนซ์ bean จริงที่ควรถูกผูกไว้ในบริบทของแอ็พพลิเคชันซึ่งหมายความว่ามันสามารถส่งคืน วัตถุที่ต้องการ สถานการณ์โดยทั่วไปเมื่อสิ่งนี้มีประโยชน์คือเมื่อตัวประมวลผล bean post ห่อเป้าหมายในอินสแตนซ์พร็อกซี การเรียกใช้ทั้งหมดบน bean ที่ถูกผูกไว้ในบริบทของแอปพลิเคชันจะผ่านพร็อกซีจากนั้นพร็อกซีจะทำการใช้เวทมนตร์ก่อนและ / หรือหลังการเรียกใช้บน bean เป้าหมายเช่น AOP หรือการจัดการธุรกรรม


6
ความรุ่งโรจน์สำหรับตัวอย่างในชีวิตจริง!
raiks

ขอบคุณที่ให้กรณีการใช้งานจริงไม่ใช่แค่ทฤษฎี
Amol Aggarwal

5

ความแตกต่างคือBeanPostProcessorจะเชื่อมโยงในการเริ่มต้นบริบทจากนั้นเรียกpostProcessBeforeInitializationและpostProcessAfterInitializationสำหรับถั่วที่กำหนดทั้งหมด

แต่@PostConstructใช้สำหรับคลาสเฉพาะที่คุณต้องการปรับแต่งการสร้าง bean หลังจาก constructor หรือ set method

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.