Bagaimana tepatnya cara kerja Spring BeanPostProcessor?

99

Saya belajar untuk sertifikasi Spring Core dan saya memiliki beberapa keraguan tentang bagaimana Spring menangani siklus hidup kacang dan khususnya tentang prosesor pasca kacang .

Jadi saya punya skema ini:

masukkan deskripsi gambar di sini

Cukup jelas bagi saya apa artinya:

Langkah-langkah berikut ini berlangsung di fase Load Bean Definitions :

  • The @Configuration kelas diproses dan / atau @Components -scan untuk dan / atau file XML yang diurai.

  • Definisi kacang ditambahkan ke BeanFactory (masing-masing diindeks di bawah id-nya)

  • Kacang BeanFactoryPostProcessor khusus dipanggil, dapat memodifikasi definisi kacang apa pun (misalnya untuk penggantian nilai tempat penampung properti).

Kemudian langkah-langkah berikut berlangsung dalam fase pembuatan kacang :

  • Setiap kacang dibuat dengan bersemangat secara default (dibuat dalam urutan yang benar dengan dependensi yang dimasukkan).

  • Setelah injeksi ketergantungan, setiap biji melewati fase pasca-pemrosesan di mana konfigurasi dan inisialisasi lebih lanjut dapat terjadi.

  • Setelah pasca pemrosesan, kacang sepenuhnya diinisialisasi dan siap digunakan (dilacak oleh idnya hingga konteksnya dihancurkan)

Ok, ini cukup jelas bagi saya dan saya juga tahu bahwa ada dua jenis prosesor posting kacang yaitu:

  • Penginisialisasi: Inisialisasi kacang jika diinstruksikan (mis. @PostConstruct).

  • dan Semua sisanya: yang memungkinkan konfigurasi tambahan dan yang dapat berjalan sebelum atau setelah langkah inisialisasi

Dan saya memposting slide ini:

masukkan deskripsi gambar di sini

Jadi sangat jelas bagi saya apa penginisialisasi pengolah posting kacang (mereka adalah metode yang dijelaskan dengan anotasi @PostContruct dan yang secara otomatis dipanggil segera setelah metode penyetel (jadi setelah injeksi ketergantungan), dan saya tahu bahwa saya dapat menggunakannya untuk melakukan beberapa batch inisialisasi (seperti mengisi cache seperti pada contoh sebelumnya).

Tapi apa sebenarnya yang mewakili prosesor posting kacang lainnya? Apa yang kami maksud ketika kami mengatakan bahwa langkah-langkah ini dilakukan sebelum atau setelah fase inisialisasi ?

Jadi kacang saya dibuat instance-nya dan dependensinya dimasukkan, lalu fase inisialisasi selesai (dengan eksekusi metode beranotasi @PostContruct ). Apa yang kami maksud dengan mengatakan bahwa Prosesor Bean Post digunakan sebelum fase inisialisasi? Artinya itu terjadi sebelum eksekusi metode beranotasi @PostContruct ? Apakah ini berarti bahwa ini bisa terjadi sebelum injeksi ketergantungan (sebelum metode penyetel dipanggil)?

Dan apa sebenarnya yang kami maksud ketika kami mengatakan bahwa itu dilakukan setelah langkah inisialisasi . Artinya itu terjadi setelah itu eksekusi metode beranotasi @PostContruct , atau apa?

Saya dapat dengan mudah membayangkan di kepala saya mengapa saya memerlukan metode beranotasi @PostContruct tetapi saya tidak dapat menemukan beberapa contoh tipikal dari jenis prosesor posting kacang lainnya, dapatkah Anda menunjukkan kepada saya beberapa contoh khas kapan digunakan?

AndreaNobili
sumber
Saya yakin Anda tidak boleh berbagi gambar slide :)
Reg
@Reg Dari kursus / presentasi apa gambar-gambar ini berasal?
Malvon
@Malvon Ini adalah dari kursus inti resmi Musim Semi Pivotal edisi sebelumnya. DAN BTW - Jika Anda sedang mempersiapkan ujian, abaikan apa pun dengan XML :)
Reg
@Reg Apakah ada cara untuk membeli kursus tanpa benar-benar menghadiri kelas pelatihan?
Malvon
Saya bertanya-tanya Apa yang terjadi di bagian ungu dari diagram "Proses pasca Definisi Bean"?
Akshay Hiremath

Jawaban:

51

Spring doc menjelaskan BPP di bawah Mengkustomisasi kacang menggunakan BeanPostProcessor . Kacang BPP adalah jenis biji khusus yang dibuat sebelum biji lainnya dan berinteraksi dengan biji yang baru dibuat. Dengan konstruksi ini, Spring memberi Anda sarana untuk terhubung dan menyesuaikan perilaku siklus proses hanya dengan menerapkan BeanPostProcessordiri Anda sendiri.

Memiliki BPP khusus seperti

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;
    }
}

akan dipanggil dan mencetak kelas dan nama kacang untuk setiap kacang yang dibuat.

Untuk memahami bagaimana metode ini cocok dengan siklus hidup kacang, dan kapan tepatnya metode dipanggil, periksa dokumennya

postProcessBeforeInitialization (Object bean, String beanName) Terapkan BeanPostProcessor ini ke instance bean baru yang diberikan sebelum callback inisialisasi bean apa pun (seperti inisialisasi afterPropertiesSet atau metode init kustom).

postProcessAfterInitialization (Object bean, String beanName) Menerapkan BeanPostProcessor ini ke instance bean baru yang diberikan setelah callback inisialisasi bean (seperti inisialisasi afterPropertiesSet atau metode init kustom).

Bagian penting juga itu

Kacang sudah diisi dengan nilai properti.

Untuk urusan apa hubungannya dengan @PostConstructcatatan bahwa anotasi ini adalah cara mudah untuk mendeklarasikan sebuah postProcessAfterInitializationmetode, dan Spring mengetahuinya ketika Anda mendaftar CommonAnnotationBeanPostProcessoratau menentukan <context:annotation-config />file konfigurasi kacang. Apakah @PostConstructmetode akan dijalankan sebelum atau sesudah yang lain postProcessAfterInitializationbergantung pada orderpropertinya

Anda dapat mengkonfigurasi beberapa instance BeanPostProcessor, dan Anda dapat mengontrol urutan yang dijalankan BeanPostProcessor ini dengan mengatur properti order.

Tuan Budak
sumber
32

Contoh tipikal untuk prosesor bean post adalah ketika Anda ingin membungkus bean asli dalam sebuah instance proxy, misalnya saat menggunakan @Transactionalanotasi.

Prosesor bean post akan diberikan instance original bean, ia dapat memanggil method apapun pada target, tetapi juga dapat mengembalikan instance bean sebenarnya yang harus terikat dalam konteks aplikasi, yang artinya ia dapat mengembalikan apapun. objek yang diinginkannya. Skenario tipikal saat ini berguna adalah ketika prosesor posting kacang membungkus target dalam contoh proxy. Semua pemanggilan pada bean terikat dalam konteks aplikasi akan melewati proxy, dan proxy kemudian dapat melakukan beberapa keajaiban sebelum dan / atau setelah pemanggilan pada bean target, misalnya AOP atau manajemen transaksi.

marthursson.dll
sumber
6
Pujian untuk contoh kehidupan nyata!
raik
terima kasih telah menyediakan kasus penggunaan aktual dan bukan hanya teori
Amol Aggarwal
5

Perbedaannya adalah BeanPostProcessorakan menghubungkan ke inisialisasi konteks kemudian memanggil postProcessBeforeInitializationdan postProcessAfterInitializationuntuk semua kacang yang ditentukan.

Tetapi @PostConstructhanya digunakan untuk kelas tertentu yang ingin Anda sesuaikan pembuatan kacang setelah konstruktor atau metode set.

Tam Le
sumber