2011-11-01 14 views
5

Sto giocando con Spring AOP.Spring AOP crea extra bean

Ecco una semplice classe

public class CModel extends Car { 
    private double torqueMeasure = 1; 

    public CModel() { 
     System.out.println(" C-Model constructor");   
    } 
} 

E primavera configurazione è simile a questo

<aop:config> 
    <aop:aspect ref="audit"> 
     <aop:before pointcut="execution(* com.test.main..*(..))" method="firstControl"/> 
      ... 
    </aop:aspect> 
</aop:config> 

Ok ora; quando aggiungo aop: config e intercetta CModel, Spring chiama il costruttore CModel due volte. Significa che Spring crea 2 oggetti CModel, giusto?

Se elimino AOP config, Spring crea solo un oggetto CModel.

Qualche idea sul perché sia ​​così?

Grazie.

+1

Penso che la primavera crei questo bean e proxy per esso. La classe proxy dinamico estende la classe base, quindi dovrebbe chiamare super() nel suo costruttore. È possibile stampare la traccia dello stack nel costruttore CModel per essere certi che (qualcosa come la nuova Exception(). PrintStackTrace()). – svaor

risposta

5

Anche se non ne sono sicuro, la mia ipotesi è che la prima molla istanzia la classe regolare e quindi crea un proxy CGLIB, che è una sottoclasse. Nota che per l'inizializzazione devi usare @PostConstruct, che è garantito per essere usato una volta.

per verificare la mia ipotesi, aggiungere un punto di interruzione nel costruttore e vedere quando viene richiamata - uno dei tempi dovrebbe essere subito dopo la CModel$EnhancedByCGLIB qualcosa

+1

Penso che tu abbia ragione. In realtà ne parlai [di recente] (http://nurkiewicz.blogspot.com/2011/10/spring-pitfalls-proxying.html), forse l'OP troverà ulteriori dettagli lì. A proposito, c'è un metodo ancora più semplice per verificarlo: 'System.out.println (this)' - la seconda riga stampata produrrà qualcosa come 'CModel $ EnhancedByCGLIB'. –

+3

È documentato in [7.6 meccanismi di Proxying] (http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/aop.html#aop-proxying) – axtavt

3

Quando Primavera crea un proxy per la classe, userà CGLIB per generare una classe che sottoclassi CModel. L'effetto netto è che il tuo costruttore verrà chiamato due volte.

Controllare la documentazione primavera per maggiori dettagli (in particolare il terzo punto): http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/aop.html#aop-proxying

Come nota a margine, Primavera utilizzerà il meccanismo di proxy JDK se la classe implementa un'interfaccia - e il meccanismo proxy JDK non chiamerà il tuo costruttore.

+1

Darn - sembra Sono stato picchiato al pugno :) Ci scusiamo per la risposta duplicata. – wmkoch