Come funziona esattamente Spring BeanPostProcessor?


94

Sto studiando per la certificazione Spring Core e ho qualche dubbio su come Spring gestisce il ciclo di vita dei bean e in particolare sul bean post processor .

Quindi ho questo schema:

inserisci qui la descrizione dell'immagine

È abbastanza chiaro per me cosa significa:

I seguenti passaggi si svolgono nella fase di caricamento delle definizioni dei bean :

  • Le classi @Configuration vengono elaborate e / o vengono esaminati i componenti @ e / o vengono analizzati i file XML .

  • Definizioni di bean aggiunte a BeanFactory (ciascuna indicizzata con il proprio ID)

  • I bean speciali BeanFactoryPostProcessor richiamati, possono modificare la definizione di qualsiasi bean (ad esempio per le sostituzioni dei valori segnaposto proprietà).

Quindi i seguenti passaggi avvengono nella fase di creazione dei fagioli :

  • Ogni bean viene istanziato con entusiasmo per impostazione predefinita (creato nel giusto ordine con le sue dipendenze iniettate).

  • Dopo l'inserimento delle dipendenze, ogni bean passa attraverso una fase di post-elaborazione in cui possono verificarsi ulteriori configurazioni e inizializzazioni.

  • Dopo la post-elaborazione il bean è completamente inizializzato e pronto per l'uso (tracciato dal suo id fino a quando il contesto non viene distrutto)

Ok, questo è abbastanza chiaro per me e so anche che ci sono due tipi di processori di bean post che sono:

  • Inizializzatori: inizializza il bean se richiesto (ad esempio @PostConstruct).

  • e tutto il resto: che consentono una configurazione aggiuntiva e che può essere eseguito prima o dopo la fase di inizializzazione

E posto questa diapositiva:

inserisci qui la descrizione dell'immagine

Quindi è molto chiaro per me cosa fanno gli inizializzatori bean post processors (sono i metodi annotati con l' annotazione @PostContruct e che vengono chiamati automaticamente immediatamente dopo i metodi setter (quindi dopo l'iniezione delle dipendenze), e so che posso usarli per eseguire un batch di inizializzazione (come popolare una cache come nell'esempio precedente).

Ma cosa rappresenta esattamente l'altro bean post processor? Cosa intendiamo quando diciamo che questi passaggi vengono eseguiti prima o dopo la fase di inizializzazione ?

Quindi i miei bean vengono istanziati e le sue dipendenze vengono iniettate, quindi la fase di inizializzazione è completata (mediante l'esecuzione di un metodo annotato @PostContruct ). Cosa si intende per dire che prima della fase di inizializzazione viene utilizzato un Bean Post Processor? Significa che accade prima dell'esecuzione del metodo annotato @PostContruct ? Significa che potrebbe accadere prima dell'iniezione delle dipendenze (prima che vengano chiamati i metodi setter)?

E cosa intendiamo esattamente quando diciamo che viene eseguito dopo la fase di inizializzazione . Significa che succede dopo l'esecuzione di un metodo annotato @PostContruct , o cosa?

Posso facilmente capire nella mia testa perché ho bisogno di un metodo annotato @PostContruct ma non riesco a immaginare un esempio tipico dell'altro tipo di processore di bean post, puoi mostrarmi qualche esempio tipico di quando vengono utilizzati?


Sono abbastanza sicuro che non dovresti condividere le immagini delle diapositive :)
Reg

@Reg Di che corso / presentazione sono esatte queste immagini?
Malvon

@Malvon Questo era dell'edizione precedente del corso base ufficiale di primavera di Pivotal. AND BTW - Se ti stai preparando per l'esame, ignora qualsiasi cosa con XML :)
Reg

@Reg Esiste un modo per acquistare il corso senza partecipare effettivamente ai corsi di formazione?
Malvon

Mi chiedo cosa succede in quella parte viola del diagramma "Definizioni bean post-elaborazione"?
Akshay Hiremath

Risposte:


48

Il documento Spring spiega i BPP in Personalizzazione dei bean utilizzando BeanPostProcessor . I bean BPP sono un tipo speciale di bean che vengono creati prima di qualsiasi altro bean e interagiscono con i bean appena creati. Con questo costrutto, Spring ti offre i mezzi per collegarti e personalizzare il comportamento del ciclo di vita semplicemente implementando un BeanPostProcessorte stesso.

Avere un BPP personalizzato come

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

verrebbe chiamato e stamperà la classe e il nome del bean per ogni bean creato.

Per capire come il metodo si adatta al ciclo di vita del bean e quando esattamente il metodo viene chiamato, controllare la documentazione

postProcessBeforeInitialization (Object bean, String beanName) Applica questo BeanPostProcessor alla nuova istanza di bean specificata prima di qualsiasi callback di inizializzazione del bean (come afterPropertiesSet di InitializingBean o un metodo di inizializzazione personalizzato).

postProcessAfterInitialization (Object bean, String beanName) Applica questo BeanPostProcessor alla nuova istanza di bean data dopo qualsiasi callback di inizializzazione del bean (come afterPropertiesSet di InitializingBean o un metodo di inizializzazione personalizzato).

La parte importante è anche quella

Il bean verrà già popolato con i valori delle proprietà.

Per quanto riguarda la relazione con la @PostConstructnota che questa annotazione è un modo conveniente per dichiarare un postProcessAfterInitializationmetodo, e Spring se ne accorge quando si registra CommonAnnotationBeanPostProcessoro si specifica il <context:annotation-config />file di configurazione in bean. Se il @PostConstructmetodo verrà eseguito prima o dopo qualsiasi altro postProcessAfterInitializationdipende dalla orderproprietà

È possibile configurare più istanze di BeanPostProcessor e controllare l'ordine in cui vengono eseguiti questi BeanPostProcessor impostando la proprietà order.


30

Il tipico esempio per un bean post processor è quando si desidera avvolgere il bean originale in un'istanza proxy, ad esempio quando si utilizza l' @Transactionalannotazione.

Il post processore bean riceverà l'istanza originale del bean, può chiamare qualsiasi metodo sulla destinazione, ma può anche restituire l'istanza effettiva del bean che dovrebbe essere vincolata nel contesto dell'applicazione, il che significa che può effettivamente restituire qualsiasi oggetto che vuole. Lo scenario tipico in cui ciò è utile è quando il processore di post bean avvolge la destinazione in un'istanza proxy. Tutte le invocazioni sul bean associato nel contesto dell'applicazione passeranno attraverso il proxy, e il proxy quindi potrà eseguire qualche magia prima e / o dopo le invocazioni sul bean di destinazione, ad esempio AOP o gestione delle transazioni.


6
Complimenti per un esempio di vita reale!
raiks

grazie per aver fornito il caso d'uso effettivo e non solo la teoria
Amol Aggarwal

4

La differenza è che BeanPostProcessorsi collegherà all'inizializzazione del contesto, quindi chiamerà postProcessBeforeInitializatione postProcessAfterInitializationper tutti i bean definiti.

Ma @PostConstructviene utilizzato solo per la classe specifica che si desidera personalizzare la creazione del bean dopo il costruttore o il metodo set.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.