Аннотация Aop в контроллерах Spring не работает

Я сделал аннотацию для aop. Когда я использую его в любом методе, а не в методах контроллера, он работает хорошо. Однако, когда я использую его в методах моего контроллера, мой контроллер перестает работать. Он начинает выдавать ошибку 404 не найдено для сопоставлений. Я нашел аналогичный вопрос здесь: Spring 3 MVC @Controller с перехватчиками AOP? но я не знаю, как это сделать. Мой метод на моем контроллере таков:

@WebAuditable // This is my annotation that works at other methods
@Override
@RequestMapping(value = "/ad", method = RequestMethod.POST, headers = "Accept=application/json")
public
@ResponseBody
Cd create(HttpServletResponse response, @RequestBody Cd cd) {
    ...
}

Мой интерфейс, который реализует мой контроллер, таков:

public interface BaseController<T> {

    public List<T> getAll(HttpServletResponse response);

    public T getByName(HttpServletResponse response, String id);

    public T create(HttpServletResponse response, T t);

    public T update(HttpServletResponse response, T t);

}

Любые советы?

PS: @SeanPatrickFloyd говорит, что:

Примечание. При использовании интерфейсов контроллера (например, для проксирования АОП) убедитесь, что все ваши аннотации сопоставления, такие как @RequestMapping и @SessionAttributes, последовательно размещены в интерфейсе контроллера, а не в классе реализации.


person kamaci    schedule 22.11.2011    source источник


Ответы (1)


Дело в том, что сопоставление контроллеров выполняется во время выполнения, и если вы используете прокси-серверы AOP, прокси-объекты не имеют аннотаций во время выполнения, а только их интерфейсы. Я могу придумать две возможные стратегии обхода этого ограничения.

Либо аннотируйте общие методы интерфейса, либо (если вы не хотите советовать всем контроллерам) создайте подинтерфейс для каждого типа реализации, явно аннотируя их методы. Я знаю, что это много переписанного кода, что противоречит тому, что представляет собой АОП, но я не знаю лучшего способа придерживаться прокси-серверов на основе интерфейса.

Другой способ — переключиться на прокси CGLib с помощью proxy-target-class="true". Таким образом, прокси-классы должны (я не уверен в этом) сохранять аннотации.

Обновление: аннотирование вашего интерфейса должно работать так (если оно работает)

public interface BaseController<T> {

    @WebAuditable
    public List<T> getAll(HttpServletResponse response);

    @WebAuditable
    public T getByName(HttpServletResponse response, String id);

    @WebAuditable
    public T create(HttpServletResponse response, T t);

    @WebAuditable
    public T update(HttpServletResponse response, T t);

}

Аннотирование базового класса не сработает, потому что прокси-серверы JDK не предоставляют никакой информации, которая не поддерживается интерфейсами.

person Sean Patrick Floyd    schedule 23.11.2011
comment
Спасибо за вашу помощь. Как я буду аннотировать общие методы, можете ли вы показать мне пример? Существует базовый интерфейс контроллера, который реализуется всеми моими контроллерами. (На самом деле существует абстрактный класс, который реализует BaseController, но не реализует свои методы создания, обновления и удаления, контроллеры реализуют их) Итак, могу ли я решить эту проблему с аннотированием моего BaseController и как я могу аннотировать его, чтобы показать мне из моего вопроса? - person kamaci; 23.11.2011
comment
Я пытался, но не работал аннотировать этот интерфейс. Я не мог найти способ сделать это. Как насчет второго совета? - person kamaci; 23.11.2011