Spring BeanPostProcessor tam olarak nasıl çalışır?


99

Spring Core sertifikası için çalışıyorum ve Spring'in fasulye yaşam döngüsünü nasıl yönettiği ve özellikle fasulye post işlemcisi hakkında bazı şüphelerim var .

Yani şu şemaya sahibim:

görüntü açıklamasını buraya girin

Bunun ne anlama geldiği benim için oldukça açık:

Fasulye Tanımlarını Yükle aşamasında aşağıdaki adımlar gerçekleşir :

  • @Configuration sınıflar işlenir ve / veya @Components ve / veya taranır XML dosyaları çözümlenir.

  • BeanFactory'ye eklenen Bean tanımları (her biri kendi kimliği altında dizine eklenir)

  • Özel BeanFactoryPostProcessor çekirdeklerinin çağrılması, herhangi bir çekirdeğin tanımını değiştirebilir (örneğin, özellik-yer tutucu değerleri değiştirmeleri için).

Daha sonra çekirdek oluşturma aşamasında aşağıdaki adımlar gerçekleşir :

  • Her bir çekirdek varsayılan olarak hevesle örneklenir (bağımlılıkları enjekte edilerek doğru sırada oluşturulur).

  • Bağımlılık enjeksiyonundan sonra her çekirdek, daha fazla konfigürasyon ve başlatmanın gerçekleşebileceği bir işlem sonrası aşamasından geçer.

  • İşlem sonrası işlemden sonra çekirdek tamamen başlatılır ve kullanıma hazır hale gelir (içerik yok olana kadar kimliği ile izlenir)

Tamam, bu benim için oldukça açık ve ayrıca iki tür fasulye sonrası işlemcisi olduğunu da biliyorum :

  • Başlatıcılar: Talimat verildiyse çekirdeği başlatın (ör. @PostConstruct).

  • ve Geri kalan her şey: ek yapılandırmaya izin veren ve başlatma adımından önce veya sonra çalışabilir

Ve bu slaydı yayınlıyorum:

görüntü açıklamasını buraya girin

Bu yüzden benim için başlatıcıların post işlemcileri ne işe yaradığı çok açık (bunlar @PostContruct ek açıklaması ile açıklanmış yöntemlerdir ve ayarlayıcı yöntemlerden hemen sonra otomatik olarak çağrılırlar (yani bağımlılık enjeksiyonundan sonra) ve bunu kullanabileceğimi biliyorum bazı başlatma toplu işlemleri gerçekleştirin (önceki örnekte olduğu gibi bir önbellek doldurduğunuz gibi).

Peki diğer fasulye post işlemcisini tam olarak ne temsil ediyor? Bu adımların başlangıç ​​aşamasından önce veya sonra yapıldığını söylediğimizde ne demek istiyoruz? ?

Böylece benim çekirdeklerim somutlaştırıldı ve bağımlılıkları enjekte edildi, böylece başlatma aşaması tamamlandı ( @PostContruct açıklamalı yönteminin yürütülmesiyle ). Başlatma aşamasından önce Bean Post İşlemcisinin kullanıldığını söylemekle ne demek istiyoruz? Bu, @PostContruct açıklamalı yöntem yürütmeden önce gerçekleştiği anlamına mı geliyor? Bağımlılık enjeksiyonundan önce olabileceği anlamına mı geliyor (bundan önce ayarlayıcı yöntemler çağrılır)?

Ve başlatma adımından sonra yapıldığını söylediğimizde tam olarak ne demek istiyoruz ? Bu, @PostContruct açıklamalı bir yöntemin yürütülmesinden sonra gerçekleştiği anlamına gelir veya ne?

Neden bir @PostContruct açıklamalı yönteme ihtiyacım olduğunu kolayca anlayabiliyorum, ancak diğer tür fasulye post işlemcisinin tipik bir örneğini bulamıyorum, bana ne zaman kullanıldığına dair tipik bir örnek gösterebilir misiniz?


Slaytların resimlerini paylaşmamanız gerektiğinden oldukça eminim :)
Reg

@Reg Bu görüntüler tam olarak hangi kurstan / sunumdan?
Malvon

@Malvon Bu, Pivotal'ın resmi Bahar temel kursunun bir önceki baskısıydı. VE BTW - Sınava hazırlanıyorsanız, XML ile ilgili her şeyi göz ardı edin :)
Reg

@Reg Eğitim kurslarına gerçekten katılmadan kursu satın almanın bir yolu var mı?
Malvon

Merak ediyorum, "İşlem sonrası Fasulye Tanımları" diyagramının mor bölümünde ne oluyor?
Akshay Hiremath

Yanıtlar:


51

Bahar belgesi, BeanPostProcessor kullanarak çekirdekleri özelleştirme altındaki BPP'leri açıklamaktadır . BPP çekirdekleri, diğer çekirdeklerden önce oluşturulan ve yeni oluşturulan çekirdeklerle etkileşime giren özel bir çekirdek türüdür. Bu yapıyla, Spring size yaşam döngüsü davranışını basitçe birBeanPostProcessor kendiniz .

Özel bir BPP'ye sahip olmak

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

çağrılır ve oluşturulan her fasulye için sınıf ve fasulye adı yazdırılır.

Yöntemin fasulyenin yaşam döngüsüne nasıl uyduğunu ve yöntemin tam olarak ne zaman çağrıldığını anlamak için belgeleri kontrol edin

postProcessBeforeInitialization (Nesne bean, String beanName) Bu BeanPostProcessor'ı, herhangi bir bean başlatma geri çağrısından önce (InitializingBean's afterPropertiesSet veya özel bir başlatma yöntemi gibi) verilen yeni bean örneğine uygulayın.

postProcessAfterInitialization (Object bean, String beanName) Bu BeanPostProcessor'ı, herhangi bir bean başlatma geri çağırmasından sonra (InitializingBean's afterPropertiesSet veya özel bir başlatma yöntemi gibi) verilen yeni bean örneğine uygulayın.

Önemli olan aynı zamanda

Fasulye, mülk değerleriyle zaten doldurulmuş olacaktır.

@PostConstructBu açıklamanın bir postProcessAfterInitializationyöntemi bildirmenin uygun bir yolu olduğu notuyla olan ilişkiyi ilgilendiren hususlar için ve Spring, siz kaydederek CommonAnnotationBeanPostProcessorveya <context:annotation-config />fasulye yapılandırma dosyasını belirttiğinizde bunun farkına varır . İster @PostConstructmetot önce veya herhangi bir başka sonra yürütülür postProcessAfterInitializationbağlıdır ordermülkiyet

Birden çok BeanPostProcessor örneğini yapılandırabilir ve order özelliğini ayarlayarak bu BeanPostProcessors'ın yürütüleceği sırayı kontrol edebilirsiniz.


32

Bean post işlemcisi için tipik örnek, orijinal fasulyeyi bir proxy örneğine sarmak istediğiniz zamandır, örneğin, @Transactional notu .

Bean post işlemcisi, çekirdeğin orijinal örneğini verir, hedefte herhangi bir yöntemi çağırabilir, ancak aynı zamanda uygulama bağlamında bağlanması gereken gerçek fasulye örneğini de döndürebilir, bu da aslında herhangi bir istediği nesne. Bunun yararlı olduğu tipik senaryo, bean post işlemcisinin hedefi bir proxy örneğinde sarmalamasıdır. Uygulama bağlamında bean bağı üzerindeki tüm çağrılar proxy üzerinden geçer ve ardından proxy, hedef fasulye üzerindeki çağrılardan önce ve / veya sonra bazı sihir gerçekleştirir, örneğin AOP veya işlem yönetimi.


6
Gerçek hayattan bir örnek için tebrikler!
raiks

sadece teoriyi değil, gerçek kullanım
senaryosunu

5

Aradaki fark, BeanPostProcessorbağlam başlatmaya bağlanacak postProcessBeforeInitializationve ardından postProcessAfterInitializationtanımlanmış tüm fasulye çağrıları için çağrılacaktır.

Ancak @PostConstruct, yalnızca yapıcı veya set yönteminden sonra fasulye oluşturmayı özelleştirmek istediğiniz belirli sınıf için kullanılır.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.