Аспект не ловит все события в рамках весны? - PullRequest
7 голосов
/ 02 сентября 2008

Мой проект основан на Spring Framework 2.5.4. И я пытаюсь добавить аспекты для некоторых контроллеров (я использую aspectj 1.5.3).

Я включил авто-прокси в application-servlet.xml, просто вставил эти строки в конец XML-файла:

<aop:aspectj-autoproxy />
<bean id="auditLogProcessor" class="com.example.bg.web.utils.AuditLogProcessor" />

Созданный аспект:

package com.example.bg.web.utils;

import org.apache.log4j.Logger;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;

@Aspect
public class AuditLogProcessor
{
    private final static Logger log = Logger.getLogger(AuditLogProcessor.class);

    @After("execution(* com.example.bg.web.controllers.assets.AssetThumbnailRebuildController.rebuildThumbnail(..))")
    public void afterHandleRequest() {
        log.info("test111");
    }

    @After("execution(* com.example.bg.web.controllers.assets.AssetThumbnailRebuildController.rebuildThumbnail(..))")
    public void afterRebuildThumbnail() {
        log.info("test222");
    }
}

Мои контроллеры:

class AssetAddController implements Controller
class AssetThumbnailRebuildController extends MultiActionController

Когда я устанавливаю точки торможения в советниках аспектов и вызываю контроллеры, я ловлю только afterHandleRequest (), но не afterRebildThumbnail () Что я сделал не так?

Примечание

Я задаю этот вопрос от имени моего друга, у которого нет доступа к SO бета, и я понятия не имею, о чем он.

EDIT

Действительно, были некоторые ошибки, спасибо Cheekysoft. Но проблема все еще сохраняется.

Ответы [ 4 ]

2 голосов
/ 16 сентября 2008

Ваши точки останова не находятся под ударом, потому что вы используете прокси Spring AOP. См. понимание-aop-прокси для описания особенностей прокси AOP.

По сути, инфраструктура MVC будет вызывать метод handleRequest на прокси-сервере вашего контроллера (который, например, MultiActionController, который вы используете в качестве базового класса, реализует), этот метод затем сделает "внутренний" вызов к его методу rebuildThumbnail, но он не будет проходить через прокси-сервер и, таким образом, не затронет никаких аспектов. (Это не имеет ничего общего с финальными методами.)

Чтобы добиться того, чего вы хотите, исследуйте использование «реального» AOP с помощью ткачества времени загрузки (которое Spring очень хорошо поддерживает).

1 голос
/ 03 сентября 2008

Базовая настройка выглядит нормально.

Синтаксис можно немного упростить, если не указывать точечный вырез на месте, а просто указать метод, к которому следует применять последующее уведомление. (Названные точки для методов создаются автоматически.)

, например

@After( "com.example.bg.web.controllers.assets.AssetAddController.handleRequest()" )
public void afterHandleRequest() {
    log.info( "test111" );
}

@After( "com.example.bg.web.controllers.assets.AssetThumbnailRebuildController.rebuildThumbnail()" )   
public void afterRebuildThumbnail() {
    log.info( "test222" );
}

Пока метод rebuildThumbnail не является окончательным, а имя метода и класс верны. Я не понимаю, почему это не сработает.

см. http://static.springframework.org/spring/docs/2.0.x/reference/aop.html

1 голос
/ 02 сентября 2008

AspectJ плохо работает с классами в среде Spring Web MVC. Прочитайте нижнюю часть поля «Открыть для расширения ...» в правой части страницы

Вместо этого взгляните на интерфейс HandlerInterceptor .

Новые Spring MVC Annotations могут также работать с тех пор, как все классы Controller являются POJO, но я сам не пробовал.

0 голосов
/ 03 сентября 2008

Это так же просто, как написание? или в вопросе есть только опечатки? Иногда ты пишешь rebuildThumbnail, а иногда пишешь rebildThumbnail

Методы, которые вы пытаетесь переопределить с помощью совета, не являются окончательными методами в среде MVC, поэтому, хотя ответ bpapas полезен, я понимаю, что в данном случае это не проблема. Тем не менее, убедитесь, что действие контроллера rebuildThumbnail не является окончательным

@ bpapas: поправьте меня, если я ошибаюсь. Собственное действие контроллера программиста - это то, что он пытается переопределить. Глядя на источник MultiActionController (и его родителей), единственный завершенный метод, потенциально в стеке, это MultiActionController.invokeNamedMethod, хотя я не уверен на 100%, будет ли это в стеке в то время или нет. Приведет ли наличие завершенного метода выше в стеке к проблеме, добавляющей рекомендацию AOP к методу ниже?

...