2010-07-22 9 views
19

Estoy tratando de usar AOP para hacer algo de procesamiento después de un controlador anotado. Todo se ejecuta sin errores, pero el consejo no se está ejecutando.Consejos de AOP de primavera sobre controladores anotados

Aquí es el código del controlador:

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

y la configuración de la aplicación-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> 

y el consejo real

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!"); 
    } 
} 

¿Es incluso posible tener asesoramiento sobre controladores anotados? Estoy usando Spring 2.5.

+0

Nunca pude hacer que esto funcione, y desafortunadamente, me he quedado sin tiempo para poder trabajar en él. Por ahora, tengo que limitarme a copiar el código. – jdana

+0

Necesita incluir su bean 'testAdvisor' en' 'como este:' ' – xli

Respuesta

1

Para los controladores MVC, el método preferido para lograr lo que intenta hacer es utilizar interceptores. Ver http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/mvc.html#mvc-handlermapping-interceptor

+6

No estoy de acuerdo. Se puede decir que los aspectos son una forma más elegante de lograr lo mismo. – skaffman

+1

Mi regla general es usar interceptores cuando quiere interceptar ciertas solicitudes web. Use Aspectos cuando desee interceptar métodos en granos de primavera normales. Dado que la pregunta está relacionada con la interceptación de los controladores (que se asignan a las solicitudes web), el uso de interceptores es más adecuado. – Sasi

+0

interceptores son terribles, en general. ¿A quién le importan los URI? quiero anotar exactamente qué controladores deberían ejecutar qué partes de la lógica. las anotaciones con aspectos es la única forma de hacerlo. – Alex

22

Es posible tener consejos sobre los controladores anotados.

Supongo que desea asesorar después de la ejecución de todos los métodos en las clases anotadas con @Controller.

He aquí un ejemplo:

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.."); 
    } 
} 

Si desea utilizar la primavera AOP con la sintaxis AspectJ, también necesita un archivo de configuración de la siguiente manera:

<?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 la primavera AOP, la primavera el contenedor solo tejerá Spring beans. Si el objeto @Controller no es un bean de resorte, debe usar el tejido AspectJ.

+0

¿Cómo puedo saber si el @Controller es un frijol?Sé que está recibiendo dependencias correctamente a través de @Autowired, así que pensé que era un frijol, pero aún tengo problemas para ejecutar el aspecto. – jdana

+1

Si el autoenvío funciona y no tiene otro contenedor IOC que Spring, entonces es un Spring Bean. – Espen

+1

Mis otros componentes funcionan bien con aspecto pero no tienen suerte para los controladores. En la misma clase de aspecto, defino los puntos de control y también los puntos de servicio. los puntos de servicio funcionan pero los controladores no. ¿Hay alguna pista sobre por qué sucede esto? –

2

Tuve el mismo problema cuando el consejo para el repositorio funcionaba, pero el consejo para el controlador no. Finalmente encontré una solución. En resumen, debe asegurarse de que su definición de AOP esté cargada en el contexto del servlet, no en un contexto diferente.

En mi caso, mi definición de AOP de primavera se define en tools-config.xml. Después de trasladarse desde aquí

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

de aquí,

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

el asesoramiento para el regulador está trabajando.

+0

¿Qué pasa si todo se hace a través de anotaciones y no hay ningún archivo xml para la configuración de AOP? – Dish

Cuestiones relacionadas