2011-11-01 21 views
5

Estoy jugando con Spring AOP.Primavera AOP crea bean extra

Aquí es una clase simple

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

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

Y Resorte configuración es como esto

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

Ok ahora; cuando agrego aop: config e intercepto CModel, Spring llama al constructor CModel dos veces. Significa que Spring crea 2 objetos CModel, ¿verdad?

Si elimino la configuración AOP, Spring crea solo un objeto CModel.

¿Alguna idea de por qué es así?

Gracias.

+1

Creo que Spring crea este bean y proxy para él. La clase de proxy dinámico extiende la clase base, por lo que debe llamar a super() en su constructor. Puede imprimir el seguimiento de la pila en el constructor de CModel para asegurarse de que (algo así como la nueva Exception(). PrintStackTrace()). – svaor

Respuesta

5

Aunque no estoy seguro, mi suposición es que Spring crea primero la clase normal y luego crea un proxy CGLIB, que es una subclase. Tenga en cuenta que para la inicialización debe usar @PostConstruct, que se garantiza que se usará una vez.

una verificación de hipótesis, añadir un punto de interrupción en el constructor y ver cuando se invoca - uno de los momentos que debería ser justo después de la CModel$EnhancedByCGLIB algo

+1

Creo que estás en lo correcto. De hecho, publiqué un blog sobre [recientemente] (http://nurkiewicz.blogspot.com/2011/10/spring-pitfalls-proxying.html), tal vez el OP encontrará más detalles allí. Por cierto, hay un método aún más simple para verificar esto: 'System.out.println (this)' - la segunda línea impresa arrojará algo como 'CModel $ EnhancedByCGLIB'. –

+3

Está documentado en [7.6 mecanismos de proxy] (http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/aop.html#aop-proxying) – axtavt

3

Cuando la primavera crea un proxy a su clase, se utilizará CGLIB para generar una clase que subclasifica CModel. El efecto neto es que su constructor será llamado dos veces.

Mira la documentación de la primavera para obtener más información (en concreto el tercer punto): http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/aop.html#aop-proxying

Como nota al margen, la primavera va a utilizar el mecanismo de proxy JDK si su clase implementa una interfaz - y el mecanismo de proxy JDK no llamará a tu constructor

+1

Darn - parece Me golpearon al golpe :) Perdón por la respuesta duplicada. – wmkoch

Cuestiones relacionadas