2010-07-22 2 views
19

Я пытаюсь использовать AOP для выполнения некоторых обработок после аннотированного контроллера. Все работает без ошибок, но совет не выполняется.Spring AOP Советы по аннотированным контроллерам

Вот код контроллера:

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

и установка в прикладной конфигурации

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

и фактические советы

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

Возможно ли это иметь совет по аннотированные контроллеры? Я использую Spring 2.5.

+0

Я никогда не мог заставить это работать, и, к сожалению, у меня не хватило времени, чтобы иметь возможность работать над этим. На данный момент мне приходится просто копировать код. – jdana

+0

Вам нужно включить свой компонент 'testAdvisor' в' 'следующим образом:' ' – xli

ответ

1

Для контроллеров MVC предпочтительным методом достижения того, что вы пытаетесь сделать, является использование перехватчиков. См. http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/mvc.html#mvc-handlermapping-interceptor

+6

Я не согласен. Аспекты, возможно, более элегантный способ достичь того же. – skaffman

+1

Мое общее правило - использовать перехватчики, если вы хотите перехватить определенные веб-запросы. Используйте аспекты, когда вы хотите перехватывать методы на обычных весенних бобах. Поскольку вопрос связан с перехватом контроллеров (которые сопоставляются с веб-запросами), использование перехватчиков более подходит. – Sasi

+0

Перехватчики ужасны, в общем. кто заботится о URI? Я хочу точно указать, какие контроллеры должны выполнять какие части логики. аннотации с аспектами - единственный способ сделать это. – Alex

22

Возможно, имеется совет по аннотированным контроллерам.

Я предполагаю, что вы хотите посоветоваться после выполнения всех методов в классах, аннотированных с помощью @Controller.

Вот пример:

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

Если вы хотите использовать Spring AOP с синтаксисом AspectJ, необходимо также файл конфигурации, как это:

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

Примечание: С Spring AOP, весна контейнер будет только плетуть весенние бобы. Если объект @Controller не является компонентом Spring, вы должны использовать плетение AspectJ.

+0

Как определить, является ли @Controller bean-компонентом?Я знаю, что он правильно получает зависимости через @Autowired, поэтому я думал, что это был компонент, но у меня все еще возникают проблемы с получением аспекта. – jdana

+1

Если автоустановка работает, и у вас нет другого контейнера МОК, чем весна, то это весна. – Espen

+1

Мои другие компоненты прекрасно работают с аспектом, но не для диспетчеров. В том же классе аспектов я определяю точки контроллера, а также точки обслуживания. службы pointcuts работают, но контроллеры «нет». Есть ли какие-либо сведения о том, почему это происходит? –

2

У меня была такая же проблема, когда совет для Репозитория работал, но рекомендаций для Контролера не было. Наконец я нашел решение. Короче говоря, вам нужно убедиться, что ваше определение AOP загружено в контексте Servlet, а не в другом контексте.

В моем случае определение Spring AOP определено в tools-config.xml. После переезда его здесь

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

к здесь,

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

совет для контроллера работает.

+0

Что делать, если все через аннотации и нет файла xml для конфигурации AOP? – Dish

Смежные вопросы