2012-02-10 8 views
5

estoy escribiendo basado en esquemas muy básico primavera AOP, aquí está el .xml¿por qué no se activa este punto de corte AOP de primavera?

<bean id="aoplistener" class="tao.zhang.Listener"/> 

<aop:config> 
    <aop:aspect ref="aoplistener">     
    <aop:pointcut id="whenCalled" expression="execution(* callme(..))" /> 
    <aop:after method="scream" pointcut-ref="whenCalled" /> 
    </aop:aspect> 
</aop:config> 

El método grito() en tao.zhang.Listener se limita a imprimir un texto, y se supone que es ejecutado siempre que se llame a un método callme().

tengo un grano llamado registrador que tiene los métodos de registro() y callme()

public void log(){ 
    callme(); 
    System.out.println("Hello from logger ~~~~~~~~~~~~~~~~~~~"); 
} 

public void callme(){ 
    System.out.println("I'm called"); 
} 

Tenga en cuenta que callme() es llamado por log()

ahora tengo una planificador que llama a log() cada 5 segundos:

<task:scheduler id="myScheduler" pool-size="10"/> 

<task:scheduled-tasks scheduler="myScheduler"> 
    <task:scheduled ref="logger" method="log" fixed-rate="5000"/> 
</task:scheduled-tasks> 

Extrañamente, grito() No se invoca, pero si callme() se llama directamente:

<task:scheduler id="myScheduler" pool-size="10"/> 

<task:scheduled-tasks scheduler="myScheduler"> 
    <task:scheduled ref="logger" method="callme" fixed-rate="5000"/> 
</task:scheduled-tasks> 

grito() se invoca!

¿Alguna sugerencia? Me parece que este corte de punto no coincide con los métodos llamados dentro de otro método ...

Respuesta

9

Spring AOP atrapa una llamada al método cuando la llamada se realiza a través de un mango de bean (porque el interceptor se aplica mediante el uso de un proxy) y no cuando se llama directamente al método.

Para que su código funcione, debe cambiar al uso de AspectJ (que funciona reescribiendo el bytecode de la clase, que le permite interceptar muchas cosas y hacerlo de forma más transparente) o cambiar cómo llama al callme() que es a través de un mango de frijol:

SomeClass selfRef; 

public void log(){ 
    selfRef.callme(); 
    System.out.println("Hello from logger ~~~~~~~~~~~~~~~~~~~"); 
} 

public void callme(){ 
    System.out.println("I'm called"); 
} 

es necesario configurar el campo selfRef de forma explícita; no se autoconectará.

+0

Sí, muchas gracias! Solo estaba masticando esta oración del libro de manual de primavera: 'Primavera AOP solo admite la ejecución de métodos puntos de unión para Spring beans' – Tao

+1

Descubrí que me ayudó mucho saber cómo funcionaba Spring. Si hace algo sofisticado (incluido el AOP), le proporciona un objeto proxy que contiene los puntos de interceptación que requiere. Ese objeto proxy, el manejador de bean, si se quiere, es cómo se supone que debes hacer _all_ llamadas en el bean, y no debes ir detrás de Spring llamando a través de 'this' (que es lo que' rawme callme() 'does; the' this. está implícito). –

+0

Ahora siento que Spring AOP no es útil en muchos casos. En mi proyecto actual, quiero tomar un registro cada vez que se llama a 'callme()', y 'callme()' es usado por varios métodos en esta clase como una sub-rutina, que es una situación muy común. – Tao

Cuestiones relacionadas