Spring 3 MVC @ Контроллер с перехватчиками AOP? - PullRequest
11 голосов
/ 03 мая 2011

Кто-нибудь знает, почему, по-видимому, невозможно использовать AOP с аннотированными контроллерами MVC? (см. Пост ). У меня есть @Controller, который перестает работать, как только я добавляю pointcut к нему. Проблема не в том, что перехватчик не вызывается, а в том, что @Controller просто перестает работать (в журнале вы можете увидеть, что вместо «Mapped URL path [/ xx] на обработчик« Yyy ») вы получаете« no URL » пути определены ").

Я знаю, что есть механизм для добавления перехватчиков к контроллерам через handlerMapping, но мой вопрос относится к перехватчикам AOP. Разве аннотированные контроллеры не являются просто pojos в контейнере Spring, как любое другое pojo? В чем разница? Почему?

@Controller
@RequestMapping("/user")
public class RestTestImpl implements RestTest {
    @RequestMapping(value="/", method={RequestMethod.GET})
    public @ResponseBody String deleteUsers(String arg) {
        return "Xxxxx";
    }
}

В моем сервлет-контексте у меня есть:

<context:component-scan base-package="org.xxx.yyy"></context:component-scan>
<mvc:annotation-driven />
<bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
    . . .
</bean>

И все работает просто замечательно.

Но когда я добавлю:

    <aop:config>
        <aop:pointcut expression="execution(* org.xxx.*(..))" id="pc1"/>
        <aop:advisor advice-ref="hibernateInterceptor"  pointcut-ref="pc1" order="2" />
    </aop:config>

Контроллер перестает быть контроллером (без ошибок, просто перестает привязываться к указанному URL)!

Ответы [ 3 ]

17 голосов
/ 03 мая 2011

Из Spring MVC Reference :

Примечание
При использовании интерфейсов контроллера (например, для проксирования AOP), убедитесь, что последовательно поставил все свои отображение аннотаций - таких как @RequestMapping и @SessionAttributes - на интерфейсе контроллера , а не на классе реализации.

Конечно, эта заметка хорошо спрятана: -)

16 голосов
/ 24 февраля 2012

Я столкнулся с той же проблемой и нашел решение.

Действительно, ваш контроллер (аннотированный @Controller) и ваши аспекты (аннотированные @Aspect) должны быть в одном и том же Spring Spring .

Обычно люди определяют свои контроллеры в dispatch-servlet.xml или xxx-servlet.xml и их служебные компоненты (включая аспекты) в основном applicationContext. XML . Это не сработает.

Когда Spring инициализирует контекст MVC, он создает прокси для вашего контроллера, но если ваши аспекты не находятся в одном контексте, Spring не будет создавать для них перехватчики.

Вышеуказанное утверждение не зависит

  • о том, как вы объявляете свои контроллеры / аспекты (с помощью ручного объявления XML или стиля аннотации)
  • в выбранном вами стиле прокси (JDK proxy или CGLIB)

Я проверил все комбинации, и все они работают, пока контроллер и аспекты находятся в одном и том же Весенний контекст

1 голос
/ 03 мая 2011

Мое лучшее предположение, без каких-либо серьезных копаний, заключается в том, что используемый вами AOP-механизм Spring оборачивает целевые классы в прокси-классы, которые в конечном итоге теряют свою аннотацию или исходная аннотация удаляется после плетения.

Я уверен, что есть лучший ответ, и я остановлюсь на моем, поскольку я думаю о лучшем, более ясном способе представить его.

...