2012-02-10 15 views
5

sto scrivendo molto di base dello schema a base di Primavera AOP, ecco la .xmlperché non si attiva questo collegamento Spring AOP?

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

Il metodo urlo() in tao.zhang.Listener stamperà appena fuori del testo, e si suppone che sia eseguito ogni volta che viene chiamato un metodo callme().

Ho un fagiolo chiamato logger che ha i metodi log() e callme()

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

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

noti che callme() viene chiamato dal log()

ora ho un scheduler che chiama log() ogni 5 secondi:

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

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

Stranamente, urlo() non viene richiamato, ma se callme() viene chiamato direttamente:

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

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

urlo() viene richiamato!

Qualche suggerimento? Mi sembra che questo collegamento non corrisponda ai metodi chiamati all'interno di un altro metodo ...

risposta

9

Spring AOP intercetta solo una chiamata di metodo quando la chiamata viene eseguita tramite un handle di bean (poiché l'intercettore viene applicato tramite l'uso di un oggetto proxy) e non quando il metodo viene chiamato direttamente.

Per rendere il vostro lavoro di codice, è necessario o passare ad usare AspectJ (che funziona riscrivendo bytecode della classe, che gli permette di intercettare gran lunga più cose e di farlo in modo più trasparente) o per cambiare come si chiama callme() così che è tramite una maniglia di fagioli:

SomeClass selfRef; 

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

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

è necessario configurare il campo selfRef esplicitamente; it non sarà autowired.

+0

Sì, grazie mille! Stavo solo masticando questa frase dal manuale di primavera: 'Spring AOP supporta solo i punti di unione dell'esecuzione del metodo per i fagioli Spring ' – Tao

+1

Ho scoperto che mi ha aiutato molto sapere come funzionava Spring. Se fa qualcosa di carino (incluso AOP), ti dà un oggetto proxy che contiene i punti di intercettazione che richiede. Quell'oggetto proxy - l'handle del bean, se vuoi - è come dovresti fare _all_ chiamate sul bean, e non dovresti andare dietro a Spring's back chiamando tramite 'this' (che è ciò che è un raw' callme() 'fa; il' this' è implicito). –

+0

Ora sento che Spring AOP non è molto utile in molti casi. Nel mio progetto attuale, voglio prendere qualche registro ogni volta che viene chiamato 'callme()', e 'callme()' è usato da vari metodi in questa classe come una sub-routine, che è una situazione molto comune. – Tao

Problemi correlati