2010-07-22 12 views
19

Sto cercando di utilizzare AOP per eseguire alcune elaborazioni dopo un controller annotato. Tutto funziona senza errori, ma il consiglio non viene eseguito.Spring AOP Advice on Controllori annotati

Ecco il codice del controller:

@Controller 
public class HomeController {  
    @RequestMapping("/home.fo") 
    public String home(ModelMap model) { 
     model = new ModelMap(); 
     return "home"; 
    } 
} 

e la messa a punto in applicazione-config

<aop:aspectj-autoproxy/> 

<bean id="testAdvice" class="com.test.TestAdvice"> 
</bean> 

<bean id="testAdvisor" 
    class="org.springframework.aop.aspectj.AspectJExpressionPointcutAdvisor"> 
    <property name="advice" ref="testAdvice" /> 
    <property name="expression" value="execution(* *.home(..))" /> 
</bean> 

e il consiglio attuale

public class TestAdvice implements AfterReturningAdvice { 

    protected final Log logger = LogFactory.getLog(getClass()); 

    public void afterReturning(Object returnValue, Method method, Object[] args, 
      Object target) throws Throwable { 
     logger.info("Called after returning advice!"); 
    } 
} 

E 'anche possibile avere consigli su controller annotati? Sto usando Spring 2.5.

+0

Non sono mai riuscito a farlo funzionare e, sfortunatamente, ho perso tempo per riuscire a lavorarci. Per ora mi devo solo copiare il codice. – jdana

+0

È necessario includere il proprio bean 'testAdvisor' in' 'come questo:' ' – xli

risposta

1

Per i controller MVC il metodo preferito per eseguire ciò che si sta tentando di fare è utilizzare gli intercettori. Vedi http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/mvc.html#mvc-handlermapping-interceptor

+6

Non sono d'accordo. Gli aspetti sono probabilmente un modo più elegante per ottenere la stessa cosa. – skaffman

+1

La mia regola generale è utilizzare gli intercettori quando si desidera intercettare determinate richieste web. Usa Aspetti quando vuoi intercettare metodi su normali fagioli primaverili. Poiché la domanda è relativa ai Controllori di intercettazione (che sono mappati alle richieste web), l'uso di intercettori è più adatto. Gli intercettori – Sasi

+0

sono terribili, in generale. a chi importa degli URI? Voglio annotare esattamente quali controller dovrebbero eseguire quali parti di logica. annotazioni con aspetti è l'unico modo per farlo. – Alex

22

È possibile avere consigli sui controller annotati.

Presumo che vogliate consigliare dopo l'esecuzione di tutti i metodi nelle classi annotate con @Controller.

Ecco un esempio:

import org.aspectj.lang.annotation.AfterReturning; 
import org.aspectj.lang.annotation.Aspect; 
import org.aspectj.lang.annotation.Pointcut; 

@Aspect 
public class ControllerAspect { 

    @Pointcut("within(@org.springframework.stereotype.Controller *)") 
    public void controllerBean() {} 

    @Pointcut("execution(* *(..))") 
    public void methodPointcut() {} 

    @AfterReturning("controllerBean() && methodPointcut() ") 
    public void afterMethodInControllerClass() { 
     System.out.println("after advice.."); 
    } 
} 

Se si desidera utilizzare Spring AOP con la sintassi AspectJ, è necessario anche un file di configurazione come questa:

<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://www.springframework.org/schema/beans" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:aop="http://www.springframework.org/schema/aop" 
    xsi:schemaLocation=" 
      http://www.springframework.org/schema/aop 
      http://www.springframework.org/schema/aop/spring-aop-2.5.xsd 
      http://www.springframework.org/schema/beans 
      http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"> 

    <bean id="controllerAspect" class="controller.ControllerAspect" /> 

    <aop:aspectj-autoproxy> 
     <aop:include name="controllerAspect" /> 
    </aop:aspectj-autoproxy> 
</beans> 

Nota: Con Spring AOP, la primavera il contenitore tesserà soltanto i fagioli della primavera. Se l'oggetto @Controller non è un bean Spring, è necessario utilizzare la tessitura AspectJ.

+0

Come faccio a sapere se @Controller è un bean?So che sta ricevendo correttamente le dipendenze tramite @Autowired, quindi ho pensato che fosse un bean, ma ho ancora problemi nell'ottenere l'aspetto da eseguire. – jdana

+1

Se l'autowiring funziona e non si dispone di un altro contenitore IOC rispetto a Spring, allora è un bean Spring. – Espen

+1

I miei altri componenti funzionano bene con l'aspetto ma senza fortuna per i controller. Nella stessa classe di aspetto, definisco i puntatori del controller e anche i collegamenti ai servizi. i punti di servizio funzionano ma non i controllori. C'è qualche indizio sul perché questo accade? –

2

Ho avuto lo stesso problema in cui i consigli per il repository funzionavano, ma i consigli per Controller non lo erano. Finalmente ho trovato una soluzione. In breve, è necessario assicurarsi che la definizione AOP sia caricata nel contesto di Servlet, non in un contesto diverso.

Nel mio caso, la mia definizione Spring AOP è definita in tools-config.xml. Dopo essersi trasferito da qui

<context-param> 
    <param-name>contextConfigLocation</param-name> 
    <param-value>classpath:spring/tools-config.xml</param-value> 
</context-param> 

<listener> 
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 
</listener> 

a qui,

<servlet> 
    <servlet-name>petclinic</servlet-name> 
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> 
    <init-param> 
     <param-name>contextConfigLocation</param-name> 
     <param-value>classpath:spring/mvc-core-config.xml, classpath:spring/tools-config.xml</param-value> 
    </init-param> 
    <load-on-startup>1</load-on-startup> 
</servlet> 

il consiglio per il regolatore sta funzionando.

+0

Cosa succede se tutto è tramite annotazioni e non esiste un file xml per la configurazione AOP? – Dish

Problemi correlati